1
#include <iostream>
#include <vector>
#include <string>

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

int main()
{
    cout << "Input strings(end-of-file to exit):"<<endl;
    vector<string> strings;
    string x;


    while (cin >> x)
    {
        strings.push_back(x);
    }

    typedef vector<string>::size_type vc_sz;
    vc_sz size = strings.size();
    int same_string=0;

    for (int i = 0; i < size; i++)
    {
        for (int j = i+1; j < size; j++)
        {
            if (strings[i] == strings[j])
                ++same_string;
        }
    }

    cout << "Same string number:" << same_string << endl;

    system("pause");
    return 0;
}

This is a code for a simple program that counts how many string inputs are redundant. Everything seems to work fine except I need to type in end-of-file(ctr+z) two times to end the loop and get the result. I can't figure out why this is happening.

Slava
  • 43,454
  • 1
  • 47
  • 90
  • `while (cin >> x)` might not do what you think it does!! see [here](http://stackoverflow.com/search?q=[c%2B%2B]+%22while+%28cin+%3E%3E+x%29%22) ... – πάντα ῥεῖ Nov 26 '13 at 19:43
  • possible duplicate of [while (cin >> x) and end-of-file issues](http://stackoverflow.com/questions/1078218/while-cin-x-and-end-of-file-issues) – πάντα ῥεῖ Nov 26 '13 at 19:46
  • @g-makulik this is not the case, cin is not used anymore after that loop – Slava Nov 26 '13 at 19:49
  • @g-makulik It is not a duplicate of that question. That question is asking why he cannot input after a Ctrl-Z ... this one is asking why he has to provide 2 Ctrl-Z's to break the input. – Zac Howland Nov 26 '13 at 19:49
  • 1
    To establish EOF you have two choices. Either enter a *single* Ctrl-Z on a *blank* line, or *two* Ctrl-Z at the end of a content line. The choice is yours. – WhozCraig Nov 26 '13 at 19:50
  • @user3035311 your problem seems to be OS and environment specific, you should provide information what OS and what compiler you are using. – Slava Nov 26 '13 at 19:50
  • @Slava: Ctrl-Z is the Windows-specific EOF sequence. It won't matter what compiler is being used. – Zac Howland Nov 26 '13 at 19:52
  • @ZacHowland stream state and state of input result should be tested separately, shouldn't they? – πάντα ῥεῖ Nov 26 '13 at 19:53
  • @ZacHowland, I know, but never seen double Ctrl-Z issue, looks like WhozCraig made a good catch, Ctrl-Z is typed not on emtpy line. – Slava Nov 26 '13 at 19:53
  • @g-makulik He isn't testing the input at all - he is testing the state of the istream (`cin`). As long as it is in a valid state `std::cin.good() != false`, then the input is assumed to be valid. – Zac Howland Nov 26 '13 at 20:01
  • I ran the code in the question and I found another strange thing : if the input is : like \n like \n hateEOF \n hateEOF \n love \n EOF(in a new line) result is : Same string number:1 , BUT it is 2 !!! can you explain this please ?? – T-D Nov 26 '13 at 20:02

2 Answers2

4

It would appear that you are attempting to out the EOF character at the end of a line sequence:

> This is my inputEOF

This will force you to enter another EOF to actually end the stream. If you want to end the stream with a single EOF, you need to hit enter first:

> This is my inputENTER
> EOF
Zac Howland
  • 15,777
  • 1
  • 26
  • 42
  • 1
    Note, Ctrl-D on a supported OS (Linux, OS X, etc) behaves the same way. – WhozCraig Nov 26 '13 at 19:58
  • I ran the code in the question and I found another strange thing : if the input is : like like hateEOF hateEOF love EOF(in a new line) result is : Same string number:1 , BUT it is 2 !!! can you explain this please ?? – T-D Nov 26 '13 at 19:59
  • 1
    @T-D you must clear the error state after the EOF marker (`std::cin.clear()`). You will also need to ignore the EOF character before trying to re-read it. Keep in mind that using EOF in this way (meaning "end of stream") should actually mean the end of the input stream. Treating it as a break between entries is not good practice. – Zac Howland Nov 26 '13 at 20:02
0

You can significantly simplify your code if you use std::set

int main()
{
    cout << "Input strings(end-of-file to exit):"<<endl;
    set<string> strings;
    string x;
    int same_string=0;

    while (cin >> x)
    {
        if( !strings.insert(x).second ) ++same_string;
    }

    cout << "Same string number:" << same_string << endl;

    system("pause");
    return 0;
}
Slava
  • 43,454
  • 1
  • 47
  • 90