1


I'm reading c++ primer 5th and I have a little problem with an exercise:

Read a sequence of words from cin and store the values a vector. After you’ve read all the words, process the vector and change each word to uppercase. Print the transformed elements, eight words to a line.

My code is this:

#include <iostream>
#include <vector>
#include <string>
#include <cctype>

using std::vector;
using std::string;
using std::cin;
using std::cout;
using std::endl;

int main(){

    vector<string> words;
    string wordBuffer;
    vector<string> output(1);

    while (cin >> wordBuffer){
        words.push_back(wordBuffer);
    }

    for (string &word : words){
        for (char &letter : word){
            letter = toupper(letter);
        }
    }

    unsigned currentLine = 0;
    for (decltype(words.size())index = 0; index < words.size(); ++index){

        output[currentLine] += words[index] + " ";

        if ((index+1) % 8 == 0){
            ++currentLine;
            output.push_back("");
        }

    }

    for (string s : output){
        s[s.size() - 1] = 0; //removing the whitespace
        cout << s << endl;
    }

    system("pause");
    return 0;
}

Now, everything works well, but i have an issue with the input of the words by console.
If I write

I am writing a random words ^Z

and press Enter nothing happens. I have to rewrite the ^Z after I have pressed the Enter, like here:

I am writing a random words
^Z

Can you expain me why? Thanks!

PS: I'm saying that because in my previous programs writing ^Z in the same line worked fine. Like in this code:

#include <iostream>;


int main(){
    int currval = 0,val = 0;

        int count = 1;
        while (std::cin >> val){
            if (currval == val){
                ++count;
            }
            else {
                std::cout << "The number " << currval << " appears " << count << " times" << std::endl;
                currval = val;
                count = 1;
            }
        }
        std::cout << "The number " << currval << " appears " << count << " times" << std::endl;

    system("pause");

    return 0;
}

I can't figure out why :(

Andrii Omelchenko
  • 13,183
  • 12
  • 43
  • 79
P. Danielski
  • 550
  • 7
  • 17
  • Did you write ^Z or press Ctrl+Z? (in the other program) – tomer.z Sep 10 '14 at 13:33
  • This is not a C++ issue but is standard behaviour in Windows. To confirm you can run this simple program and get the same behaviour (CTRL+Z must be pressed on its own line in order to terminate): `char c; while((c = getchar()) != EOF) putchar(c);` – Brandin Sep 10 '14 at 13:35

2 Answers2

4

The ^Z has to be first in order for Windows to treat it as Ctrl+Z, otherwise it is just treated as meaningless characters.

If you would like it to work like you wrote i'd suggest:

String wordBuffer("")
while (strcmp(wordBuffer[strlen(wordBuffer)-3], "^Z") != 0){
    words.push_back(wordBuffer);
    cin >> wordBuffer
}

EDIT: in your second example it works because when you read integers c++ knows to divide the given string of numbers in the space (or ENTER if the numbers are entered separately in every line) to read every number separately so if you'll enter:

123 2323 4545 43 ^Z

It will read 123, then 2323, ... and then ^Z and so it will be as though it got it in a separate line but when you read string, it cant do that because a string contain every symbol and so it separate the input in the ENTER pressed and that why the second one works

Andrii Omelchenko
  • 13,183
  • 12
  • 43
  • 79
tomer.z
  • 1,033
  • 1
  • 10
  • 25
  • so why in my second example it works? This is the thing I can't understand – P. Danielski Sep 10 '14 at 13:56
  • For a disk file in text mode, the CRT's [`_read`](http://msdn.microsoft.com/en-us/library/wyssk1bs.aspx) treats CTRL+Z (0x1A) as `EOF` -- regardless of position. That's the case if standard input or `cin` is a file. For a console, as noted, it's actually Windows `ReadFile` that reports 0 read characters if the first byte is CTRL+Z. – Eryk Sun Sep 10 '14 at 16:50
0

As far as I know Ctrl+Z is placed in the keyboard buffer before any other entered symbols. Thus any entered characters before Ctrl+Z will be discarded. You need to do the following

I am writing a random words  ENTER
^Z ENTER
Andrii Omelchenko
  • 13,183
  • 12
  • 43
  • 79
Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335