-1

I'm working on a C++ project for school and I am trying to write a matrix from a text file into an array. There are negative numbers and two 5x5 matrices in the source data. I keep getting different characters (╧ or =) instead of the negative number:

void main()
{
    char c;
    char nbRow , nbCol;
    int location = 0;
    int MatrixArray[10][10];
    int negNbr;
    int k = 0;
    int l = 0;

    cin.get(c);
    nbRow = c;
    cout << "Number of rows: " << nbRow << endl;
    cin.get(c);
    cin.get(c);
    nbCol = c;
    cout << "Number of columns: " << nbCol << endl;

    while (!cin.eof())
    {

            cin.get(c);
            //cout << (int)c << endl;
            if (!isblank(c) && (isdigit(c) || c == 45))
            {
                cout << c << " | test1 " << " | ";
                if (c == 45)
                {
                    cin.get(c);
                    negNbr = (char)c;
                    negNbr = negNbr * -1;
                    cout << (char)negNbr;
                    MatrixArray[k][l] = (char)negNbr;// *-1;

                }
                else //if (isdigit(c))
                {
                    MatrixArray[k][l] = (char)c;
                }
                cout << " |test2 " << k << l << "| " << (char)MatrixArray[k][l] << endl;

                    if (l == 4)
                    {
                        k++;
                        l = 0;
                    }
                    else l++;
                }

    }
  • HINT: the "char" data type is UNSIGNED, so you cannot get negative numbers out of it..... – mrunion Sep 21 '18 at 23:59
  • If I use int then my cin.get doesn't work, I get this error: no instance of overloaded function "std::basic_istream<_elem _traits="">::get [with _Elem=char, _Traits=std::char_traits]" matches the argument list – CurryMustard Sep 22 '18 at 00:01
  • Yes, you will have to convert your string input to numeric data at some point in this process. cin takes strings/characters. Your matrix needs numbers. You will have to do the conversion. – mrunion Sep 22 '18 at 00:03
  • 3
    @mrunion: char in c++ is implementation defined. On x86 and x64 systems it is usually signed. – PlinyTheElder Sep 22 '18 at 00:07
  • Thank you for the correction, PlinyTheElder. You are indeed correct. I assumed poorly! – mrunion Sep 22 '18 at 00:08
  • See [why `while (!cin.eof())` is wrong](https://stackoverflow.com/q/5605125/9254539). – BessieTheCookie Sep 22 '18 at 05:04
  • Why can't you just change `c == 45` to `c == '-'`? It makes the code more readable and it doesn't rely on ASCII being used. – BessieTheCookie Sep 22 '18 at 05:06
  • I tried it before and it didn't work but now it worked, maybe I used double quotes last time I tried. Thanks for the tip. – CurryMustard Sep 22 '18 at 05:12
  • The `while (!cin.eof())` was part of a code snippet that the professor provided us to use for this project, is `instream` part of a different header library? I've been googling but I can't seem to find it, i get the error `identified 'instream' is undefined` ... if it's part of a different header library I'm not allowed to use it for this project – CurryMustard Sep 22 '18 at 05:41
  • "The `while (!cin.eof())` was part of a code snippet that the professor provided us to use for this project" This way of reading input (check for error, read input, process data without checking for error) is the wrong way to do it. The correct order is 1) read, 2) check for error, 3) process input if there was no error. – Swordfish Sep 22 '18 at 10:31
  • Did you mean `std::istream` (no "n") defined in ``, or `std::ifstream` defined in ``? Also, `void main()` is plain wrong. The C++ standard states that `main()` must return an int, which indicates the program's exit status. You probably need a [good book](https://stackoverflow.com/q/388242/9254539), as your professor doesn't seem to be very competent and makes basic mistakes like `while (!cin.eof())` and `void main()`. – BessieTheCookie Sep 28 '18 at 04:17

2 Answers2

1

cin.get reads a single character of input. If you call cin.get(c) and type 123 into your console, c will end up containing the char '1', not the number 1 or the number 123 or anything like that. If you then convert that to int, you'll end up with the int 49, since '1' is the ASCII code point 49.

The correct way to read integers from the console is to use the >> operator:

int i;
std::cin >> i;

Using the >> operator, if you type 123 into your console, i will end up with the value 123.

Miles Budnek
  • 19,769
  • 2
  • 26
  • 41
  • I can't seem to get this to work with my script, I'm very new to C++, is cin used for input in the console? I'm trying to read it from a file, I've been trying to adapt it but I can't get it to work unfortunately. Thanks for your help – CurryMustard Sep 22 '18 at 01:31
  • `std::cin` reads from the process's standard input stream. By default, that's the console. It's possible to redirect it to read from a file, but usually [`std::ifstream`](https://en.cppreference.com/w/cpp/io/basic_ifstream) is used for reading from files. It's interface is similar to `std::cin`. – Miles Budnek Sep 22 '18 at 01:42
  • One of my project requirements: "You are forbidden to use any other header libraries other than iostream." To use ifstream it looks like I need to include the fstream header but that's not going to work for me. – CurryMustard Sep 22 '18 at 04:34
  • @CurryMustard if you cannot use `` you'll have to redirect the input so what you read from `std::cin` is actually the contents of a file. How that can be done depends on your operating system/shell. In Windows cmd.exe it would look like `program.exe < input.txt`. – Swordfish Sep 22 '18 at 10:37
-1

achar is often by default an signed char (depending on your compiler), so of course it can hold negative numbers - from -128 to +127.

There are no 'negative characters' though, so when you try to print it, it will be interpreted as unsigned char, in the range from 0 to 255. Depending on your character set, the characters associated with >128 look like the 'funny pictures' you described.

To see the negative values, you need to use int, and it will print as a number - for example -127.

Aganju
  • 5,994
  • 1
  • 9
  • 22
  • 5
    This is incorrect. It is [implementation-defined](http://eel.is/c++draft/basic.fundamental#1) whether char can hold negative values. If you want to have a signed char, use `signed char`. – Michael Kenzel Sep 22 '18 at 00:04
  • When I print as int I get the ASCII values instead of the numerical value (e.g. 48 instead of 0). If I declare the variable to be an int instead of a char from the beginning then my cin.get doesn't work, I get an error – CurryMustard Sep 22 '18 at 00:07
  • It's -128 to +127, and as others have said, whether it's signed or unsigned is implementation defined. – PlinyTheElder Sep 22 '18 at 00:09
  • 1
    @PlinyTheElder -- no. The type `char` can represent the same range of values as **either** `signed char` or `unsigned char`, depending on whether `char` is signed or unsigned. And the ranges of `signed char` and `unsigned char` must be **at least** [-127,127] and [0,255], respectively, although they can be larger. – Pete Becker Sep 22 '18 at 11:06
  • @PeteBecker: incorrect. It's [-128, +127] for signed char. It can be easily checked by simply incrementing a signed char 255 times. Note that your range [-127, 127] has an odd number of values. – PlinyTheElder Sep 22 '18 at 15:53
  • @PlinyTheElder -- I'm sure that's right for **the compiler that you're using**. That's not what the language definition requires. But note that you cannot legally test the range of a signed integral type by incrementing it. Incrementing off the top produces undefined behavior. It's okay for unsigned types: the value is required to wrap to zero. – Pete Becker Sep 22 '18 at 16:10
  • @PeteBecker: ahh, that makes sense. I misread your comment. Are there any common compilers that set the lower limit at [-127] ? – PlinyTheElder Sep 22 '18 at 16:18
  • @PlinyTheElder — it’s not so much the compiler as the hardware. When it uses sign-magnitude representation the range is symmetrical and there are two zeros, one negative and one positive. – Pete Becker Sep 22 '18 at 18:07
  • @CurryMustard To your program, `'0'` is just a character and nothing else. To get the numerical value, subtract `'0'` from the character as the digits are guaranteed to have consecutive encoding values. Why are you trying to read input character by character anyway? Just use `>>`. – BessieTheCookie Sep 28 '18 at 04:21