0

I am a beginner at C++ and I have read various problems and solutions, but I still cannot get my code to work! The problem is that if i do not include the commented-out cin.clear() or cin.synch() my code does not stop at the beginning getline. When i do add them, it loops infinitely. Is there something that I am not including? Here is my source code:

  #include <iostream>  
  #include <fstream>
  #include <string>
  #include <cctype>
  using namespace std;
  int main() {
string inputFileName, outputFileName, inData, outData, inWord, outWord;
ifstream inFile, testStream;
ofstream outFile;
bool outPutOpened = false;
char outChar; 
int shiftNum = 0, idx = 0;
do  {

    inWord.clear();
    outWord.clear();
    //cin.clear();
    //cin.sync();


    cout << "Available options: " << endl;
    cout << "1. ENCRYPT - Encrypt a file using Caesar Cypher" << endl // menu
    << "2. Quit - Exit the program" << endl << endl;
    cout << "   Enter keyword or option index: ";
    getline(cin, inWord); // get option
    outWord.resize(inWord.length());
    transform(inWord.begin(), inWord.end(), outWord.begin(), ::toupper); //capitalize
    if (outWord.compare("ENCRYPT") == 0 || outWord.compare("1") == 0) {
        cout << "CAESAR CYPHER PROGRAM" << endl
        << "======================" << endl << endl;
        do {                
            cout << "Provide the input file name: ";

            getline(cin, inputFileName);

            inFile.open(inputFileName.c_str());
            if (inFile.fail()) {
            cout << "Cannot open file, please try again!" << endl;
                inFile.clear();
            }
     }

            while (!inFile.is_open());

        getline(inFile, inData);

        do {
            cout << "Provide the output file name: ";
            cin >> outputFileName;

            testStream.clear();
            testStream.open(outputFileName.c_str());
            if(testStream.good()) {
            cout << "That file already exists, choose another" << endl;
                testStream.clear();
                testStream.close();
            }
            else {
                testStream.clear();
                testStream.close();
                outFile.open(outputFileName.c_str());
                if (outFile.good()) {
                    outPutOpened = true;
                }   
            }
        }
        while (!outPutOpened); 
        cout << "Enter the shift number: ";
        cin >> shiftNum;

        for (idx = 0; idx <= inData.length() - 1; idx++) {

            if  (inData[idx] >= 'a' && inData[idx] <= 'z') {
        outChar = (((inData[idx] - 'a') + shiftNum) % 26) + 'a';
                outFile.put(outChar);

            }
            else if (inData[idx] >= 'A' && inData[idx] <= 'Z'){
                outChar = (((inData[idx] - 'A') + shiftNum) % 26) + 'A'; 
                outFile.put(outChar);
            }
            else {
                outFile.put(inData[idx]);
            }
        }
    }

  else if (outWord.compare("2") == 0 || outWord.compare("QUIT") == 0) {
    break;
}
else {
    cout << inWord << " is an unrecognized option, please try again" 
    << endl;
}
}  
while (outWord.compare("2") || outWord.compare("QUIT")); 
return 0;
}
ziesemer
  • 27,712
  • 8
  • 86
  • 94
Bryan Smith
  • 45
  • 1
  • 2
  • 7
  • By the way, this program is a Caesar Cypher program and I am using Xcode – Bryan Smith Dec 12 '11 at 03:37
  • Very closely related, not sure if duplicate though: http://stackoverflow.com/questions/3994394/using-c-code-in-visual-c-no-errors-but-some-part-of-the-code-is-just-ignore -- Although I'm quite confident that there are hundreds of duplicates. – Benjamin Lindley Dec 12 '11 at 03:43
  • @BenjaminLindley: its the same root problem and answer, but not the same problem or question. – Daniel Dec 12 '11 at 03:47

1 Answers1

0

The problem that in all your places where you use something like:

cin >> something;

the new line character remains in cin, so that what you will be reading next. Just every time you are finished reading from a line with this, write

string trash;
getline(cin, trash);

like:

cin >> something;
string trash;
getline(cin, trash);

and then the new line character won't remain in cin and you will start with a fresh line.

Yun
  • 3,056
  • 6
  • 9
  • 28
Daniel
  • 30,896
  • 18
  • 85
  • 139
  • 3
    Instead of using the above method a call to `std::istream::ignore` is much more suitable, [click here for documentation](http://www.cplusplus.com/reference/iostream/istream/ignore/) – Filip Roséen - refp Dec 12 '11 at 03:42
  • I think std::cin.ignore(std::numeric_limits::max(), '\n'); is a much neater solution to dump input till end of line – Adrian Cornish Dec 12 '11 at 03:46
  • Thanks a lot! The junk string method worked. It is a little messy, but at least it works. The problem with ignore is that I have tried to use somehting like cin.ignore(1000, '\n'); but then the program hangs and doesn't accept input. – Bryan Smith Dec 12 '11 at 03:49
  • Does anyone know why it hangs if I add an ignore statement at the beginning instead of the cin.clear() and the cin.synch() where the commented section where cin.clear() is? – Bryan Smith Dec 12 '11 at 03:54
  • And as for the new line characater, Isn't cin.clear() or cin.synch() supposed to flush the buffer anyways? Why is the junk string necessary? – Bryan Smith Dec 12 '11 at 04:01
  • @BryanSmith: `cin.clear()` just clears error bits, it has nothing to do with input. `cin.sync()` removes everything in the buffer, so if the user pasted content with line break, everything after the line break will go away and not just the line break. – Daniel Dec 12 '11 at 04:35