0

When I enter "111 111" and then press enter, the output shows nothing. Then when I press enter twice, the expected output appears. Why is that?

#include<iostream>
using namespace std;
int main()
{
    char seq[10];
    //initialize the sequence
    for (int i = 0; i<10; i++)
    {
        seq[i] = ' ';
    }
    //read characters from the keyboard
    for (int i = 0; i<10; i++)
    {
        cin.get(seq[i]);
        if (seq[i] == '\0')
        {
            break;
        }
    }
    //the output should be the sequence of characters
    //users typed before
    cout << seq;
    system("pause");
    return 0;
}
Enamul Hassan
  • 5,266
  • 23
  • 39
  • 56
beryllium
  • 63
  • 1
  • 1
  • 7
  • 1
    There is a `'\0'` character in C++, which terminates the string. – Ayush Gupta Nov 22 '15 at 06:37
  • why not using `cin >>` instead – Hernantas Nov 22 '15 at 06:39
  • @AyushGupta that is true for C-strings, not necessarily for `std::string`. Anyway, beryllium uses C-strings and therefore you are correct. – cdonat Nov 22 '15 at 06:40
  • 3
    `if (seq[i] = '\0')`. Enable warnings, and read them. – n. m. could be an AI Nov 22 '15 at 06:41
  • I'm sure this is a duplicate because we get a million questions with the same problem, but they never have a reasonable title so I can't find one to mark it as a duplicate. – Weak to Enuma Elish Nov 22 '15 at 06:43
  • @cdonat Actually, it is true for `std::string`. Because of new requirements placed on `std::string` in c++11, it has to be null terminated. – Weak to Enuma Elish Nov 22 '15 at 06:44
  • 1
    @JamesRoot are you sure about that? [This](http://en.cppreference.com/w/cpp/string/basic_string/operator%22%22s) description of string literals (C++14) suggests, that `std::string` can very well hold `\0` characters in the middle of the string. Please have a look at the examples at the bottom of the page. – cdonat Nov 22 '15 at 06:49
  • @cdonat `std::string` will terminate in a null character regardless of if you put null characters in the middle. – Weak to Enuma Elish Nov 22 '15 at 07:01
  • @JamesRoot have you tried that? Can you quote the standard or point to a credible source for that, please? The example from the link I have provided suggests the opposite. – cdonat Nov 22 '15 at 07:05
  • @cdonat [This](http://stackoverflow.com/a/6077274/4756309) answer and the comments below explain why. – Weak to Enuma Elish Nov 22 '15 at 07:12
  • @Hernantas because you can't read the blank space using cin>>,which is what I want it to do – beryllium Nov 22 '15 at 07:17
  • @JamesRoot Ah, I think, I misread you. Yes, `std::string` will store an additional `'\0'`at the end of the string. But it does not end on the first `'\0'` in the character sequence. Therefore it is not literally null-terminated, because a `'\0'` does not _terminate_ the string. – cdonat Nov 22 '15 at 07:20

4 Answers4

3

You can use header file string instead, which provides more flexibility like below:

#include<iostream>
#include<string>
using namespace std;
int main()
{
    string seq;
    //initialize the sequence

    //read characters from the keyboard
    getline(cin,seq);

    //the output should be the sequence of characters
    //users typed before
    cout << seq;
    system("pause");
    return 0;
}

In response to OP's question update:

In the described case, You never inputting \0 from standard input, right? Rather you are pressing enter key.

if (seq[i] == '\0'){

Instead, you can replace this checking line with:

if (seq[i] == '\n'){
Enamul Hassan
  • 5,266
  • 23
  • 39
  • 56
  • @beryllium `=` is the assignment operator, while `==` is comparison. Instead of checking if the value was null, you were assigning null to the value, and checking the value. The null character has the value 0 (false), and so the if statement could never be executed. – Weak to Enuma Elish Nov 22 '15 at 07:10
  • @beryllium Thank you too. Your code did not work for the reason what exactly James Root described. However, don't forget to accept the answer if it solve your problem. – Enamul Hassan Nov 22 '15 at 07:21
  • When I corrected this, an interesting problem occurs...I'll update it in the question. – beryllium Nov 22 '15 at 07:26
2

You can provide std::getline() with an additional char parameter, that defines the line-delimiter. In your case, simply let it read to the next '\0'.

auto seq = std::string{};
std::getline(cin, seq, '\0');

BTW.: are you really sure, you want to read to the next '\0'? It is not too easy to enter a zero character with the keyboard. If you actually are interested in a complete line from the input, just drop the delimiter parameter: std::getline(cin, seq).

cdonat
  • 2,748
  • 16
  • 24
0

This code:

for (int i = 0; i<10; i++){
    seq[i] = ' ';
}

initializes all elements in seq to spaces, not '\0'. I don't think your break statement will trigger therefore.

Lucien
  • 134
  • 5
  • 1
    Changing the assignment to `seq[i] = '\0'` wouldn't fix the problem. The problem is the asker is accidentally assigning instead of comparing in an equality statement. The previous value in the array is already overwritten before the comparison, so the initial values don't matter. – Weak to Enuma Elish Nov 22 '15 at 06:47
0

Your program reads 10 characters before it does anything else. So you need to provide 10 characters.

The break check never triggers. why would it.

Finally, cout << seq is not safe, as it may read memory past the end of seq.

Ludwig Schulze
  • 2,155
  • 1
  • 17
  • 36