3

I am trying to write a console program, which gets a number from the input and puts it into an array. The read in lasts as long as the user does not hit the "space" button. I have tried several things, but my program won't compare the input with the ASCII code of "space". Thanks in advance!

#include <iostream>
using namespace std;

int main()
{
    int fabcd[25],number_of_items = 0;
    cout << "The read in loop lasts while you don't hit space:\n";
    while((char)cin.get() != 32)
    {
            cin >> fabcd[number_of_items];
            number_of_items++;      
    }   
    return 0;
}
Grobi
  • 149
  • 1
  • 2
  • 10
  • it will then get an integer input, and will compare to the number 32 – Grobi Mar 18 '13 at 09:37
  • maybe cin.get() won't work this way or something – Grobi Mar 18 '13 at 09:38
  • nah it treats it like a char, but still won't work xD – Grobi Mar 18 '13 at 09:39
  • The stream defaults to whitespace-skipping behaviour. See e.g. http://stackoverflow.com/questions/6774825/reading-from-ifstream-wont-read-whitespace – Tony Delroy Mar 18 '13 at 09:40
  • wait! what's this? `cin >> fabcd[number_of_items]` – kwjsksai Mar 18 '13 at 09:43
  • you should `char a=cin.get();` then `fabcd[number_of_items]=a` – kwjsksai Mar 18 '13 at 09:45
  • @Immueggpain Maybe. It depends on what he wants to do. If he wants to read an integer (one or more characters forming a number), he needs `>>` somewhere. If he wants to read digits, then `int a = std::cin.get();` is the correct solution. It is _never_ correct to assign the results of `std::cin::get()` to a `char` before having tested for end of file. – James Kanze Mar 18 '13 at 09:47
  • @TonyD White space is only skipped on formatted input (`>>`). Never for `std::cin::get()`. – James Kanze Mar 18 '13 at 09:50
  • @JamesKanze, True. See my answer below. It's something else wrong. – kwjsksai Mar 18 '13 at 09:51
  • @Immueggpain There's more than one thing wrong, and it's not even clear what the OP is trying to do. See my answer, below. – James Kanze Mar 18 '13 at 09:52

5 Answers5

4

There are several problems with your code. The most fundamental is that you do two inputs each time through the loop, the first in the while, and the second using >> in the loop. Note too that the second will skip any spaces, then convert the input to an integer. If the input cannot be legally converted to an integer (e.g. the next character is an 'a'), the input goes into an error state, and cin.get() will always return EOF. And of course, if you are entering numbers, you can easily enter more than 25, and overrun the buffer.

If you just want to enter a sequence of numbers, then:

std::vector<int> fabcd;
int tmp;
while ( std::cin >> tmp ) {
    fabcd.push_back( tmp );
}

is all you need. (The numbers must be separated by white space.) If you want to enter the digits, up until you encounter a white space, something like the following should work:

std::vector<int> digits;
int tmp = std::cin.get();
while ( tmp != EOF && ! std::isspace( tmp ) ) {
    digits.push_back( tmp /* or tmp - '0' */ );
    tmp = std::cin.get();
}

Notice that the results of std::cin.get() are assigned to an int, not a char. This function returns an int intentionally, because it must be able to return the out of band value EOF. There are a couple of variants on this: if you use std::cin::peek(), instead of std::cin::get(), you'll not actually extract the character (which you'll have to do in the loop); and there is also std::get( char& ), which extract the character into the given char, provided it isn't at EOF. Using this function, the loop would be:

std::vector<int> digits;
char tmp;
while ( std::get( tmp ) && ! std::isspace( tmp ) ) {
    digits.push_back( tmp );
}

(You might also want to use std::isdigit, instead of ! std::ispace to control the loop.)

EDIT:

One last point: the actual numeric code for a space or whatever depends on the implementation, and is not necessarily 32. Also, you'll want to handle tabs and newlines similarly. You should always use the isspace, etc. functions. Or if you really do want to check for a space, and only a space, compare with ' ', and not 32.

James Kanze
  • 150,581
  • 18
  • 184
  • 329
0

(char)13 ist the carriage return not the space.

isn't the point that you would do:

((char)cin.Get()) !=' '
Michiel Cornille
  • 2,067
  • 1
  • 19
  • 42
0

The acii code for space is 32. So you should substitute 64 or 13, which is carraiage return to 32:

while((char)cin.get() != 32)

However the problem might be that cin may stop on some characters for example whitespace: You can disable this behaviour by setting: cin.unsetf(ios::skipws); according to C++, user input check for '\0' stops at spaces?

Community
  • 1
  • 1
David Karlsson
  • 9,396
  • 9
  • 58
  • 103
  • The thing is I have tried with 32, then wanted to try with the enter button 13, but my loop still won't stop for some reason. – Grobi Mar 18 '13 at 09:30
  • cin >> plainText reads from the input up to, but excluding, the first whitespace character. Maybe std::getline(cin, plainText) could work. – David Karlsson Mar 18 '13 at 09:34
  • `std::ios::skipws` has no effect on `std::istream::get`. Only formatted input ('>>') skips white space. – James Kanze Mar 18 '13 at 09:56
0

Here is the answer:

int fabcd[25],number_of_items = 0;
cout << "The read in loop lasts while you don't hit space:\n";
char a;
while((a=cin.get()) != ' ')
{

        fabcd[number_of_items]=a;
        number_of_items++;      
}   
return 0;
kwjsksai
  • 337
  • 1
  • 4
  • 15
  • This is incorrect, and will go into an endless loop on end of file. `std::cin::get()` returns an `int` for a reason, and it is _always_ incorrect to assign it to a `char` before having tested for end of file. – James Kanze Mar 18 '13 at 09:51
  • @JamesKanze, yes it's int, but it can be assigned to a char – kwjsksai Mar 18 '13 at 09:52
  • With loss of important information. In correct code, you cannot assign it t6o a `char` _before_ having ensured that it isn't `EOF` (typically -1, but guaranteed to be negative). – James Kanze Mar 18 '13 at 09:55
  • @JamesKanze, how can you expect any `EOF` here? well but you are right that you do need to check `EOF` before convert it to `char` if needed. – kwjsksai Mar 18 '13 at 09:57
  • The same way you get end of file anywhere. How can you be sure that there will be no end of file? – James Kanze Mar 18 '13 at 09:59
  • The key point, of course, is that on an 8 bit machine, `std::istream::get` may return 257 different values. That's _why_ it returns `int`, and not `char`. (You could use `while ( std::cin.get( a ) && a != ' ' )`, however.) Checking for success is important, because any time there is failure on input, the stream will continue to return failure (`EOF` from `std::istream::get()`) until the error has been cleared. An endless loop in your example. – James Kanze Mar 18 '13 at 10:02
0

try this :

 #include <iostream>
#include <conio.h >
using namespace std;

int main()
{
    int fabcd[25],number_of_items = 0;
    cout << "The read in loop lasts while you don't hit space:\n";
    while( _kbhit() != 32  )
    {
            char ch =getche();
            if (ch != 32 )
            {
           cin >> fabcd[number_of_items];
            number_of_items++;
            }
            else
                break;

    }   
    cout << "\nnumber of items:"<<number_of_items;
    cin.get();
    cin.get();
    return 0;
}
ReZa
  • 1,273
  • 2
  • 18
  • 33
  • In what language? That's not C++, and on the few platforms which support ``, it's deprecated. It's a holdover from MS-DOS (where it was a holdover from CP/M), and you should never use `` in new code. – James Kanze Mar 18 '13 at 09:54