Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++ getline or cin not accepting a string with spaces, I've searched Google and I'm still stumped!

First of all, thanks to everyone who helps me, it is much appreciated!

I am trying to store a string with spaces and special characters intact into MessageToAdd.

I am using getline (cin,MessageToAdd); and I have also tried cin >> MessageToAdd;.

I am so stumped! When I enter the sample input

Test

Everything works as intended. However if I were to use

Test Test Test

The whole console would just blink fast until I pressed CtrlC.

My style of putting variables at the top I've been told is obsolete. Please forgive me as I am still teaching myself and it's simply force of habit. I will be changing my style shortly after I get this solved :)

void AddMessage() {
    ifstream myReadFile;
    string str;
    string MessageToAdd;
    string myMessages[10];
    int i; // of course my famous i
    static string rowHtmlCloseTags;
    static string rowHtmlOpenTags;
    string replacement;

    myReadFile.open("C:\\Users\\Andrews\\Documents\\Visual Studio 2010\\Projects\\computerclass\\Debug\\outages.htm",ios::in);
    i = 0; //the start of my array
    rowHtmlCloseTags = "</b></td>"; // value that I want to replace with nothing
    rowHtmlOpenTags = "<td><b>";

    if(!myReadFile) // is there any error?
    {
        cout << "Error opening the file! Aborting…\n";
        exit(1);
    }

    if (myReadFile.is_open())
    {
        cout << endl;

        while (!myReadFile.eof())
        {
            getline(myReadFile, str);

            if (str == "<tr>")
            {            
                getline(myReadFile, str); //get the next line cause thats where the <td><b>Outage Message</b></td> is.
                size_t foundIndex = str.find(rowHtmlCloseTags); //does the sought string exist in this this line?
                if (foundIndex != str.npos) //if not no position
                    str.replace(foundIndex, rowHtmlCloseTags.size(), replacement); //replace the string
                else
                    std::cout << "Oops.. didn't find " << rowHtmlCloseTags << std::endl; //else throw a bitch

                foundIndex = str.find(rowHtmlOpenTags); //does the sought string exist in this this line?
                if (foundIndex != str.npos) //if not no position
                    str.replace(foundIndex, rowHtmlOpenTags.size(), replacement); //replace the string
                else
                    std::cout << "Oops.. didn't find " << rowHtmlOpenTags << std::endl; //else throw a bitch

                myMessages[i]=str;
                i++;
            }
        }
    }
    system("cls");
    i=0;
    while (i < 10)
    {
        cout << i << ") " << myMessages[i] << endl;
        i++;
        if (myMessages[i]=="")
        {
            break;
        }
    }
    myReadFile.close();
    cout << endl;
    cout << endl;
    cout << "Enter the message you would like to see on the reader board.\n";
    cout << "Or enter 911 to go back to the main menu: ";
    cin.ignore(1080);
    getline (cin,MessageToAdd);

    if (str == "911") //go back to the main menu
    {
        system("cls");
        mainMenu();
    }
    else //insert the message into a blank spot in the array
    {
        i=0;
        while (i < 10)
        {
            if (myMessages[i].empty())
            {
                myMessages[i]=MessageToAdd;
                break;
            }
            else
            {
                i++;
            }
        }
    }

    //now rebuild the htm file with the new array
    CreateHtmlFile(myMessages);
}
like image 890
CodingIsAwesome Avatar asked Feb 26 '23 18:02

CodingIsAwesome


1 Answers

I'll tell you one thing that's immediately wrong with your code, not your specific problem but a hairy one nonetheless.

I'm presuming that your mainMenu() function is calling this one. In that case, you appear to be under the misapprehension that:

if (str == "911") //go back to the main menu
{
       system("cls");
       mainMenu();
}

will return to your menu. It will not do that. What it will do is to call your main menu code afresh and eventually you will run out of stack space.

I suspect that what you should be doing is having a loop in mainMenu() and that code above should just use return; rather than calling mainMenu() recursively.

That and the fact that I think you should be comparing MessageToAdd against "911" rather than str.


Another thing I would do would be to put some temporary debug code in:

cout << "DEBUG A\n";
i=0;
while (i < 10)
{
    cout << "DEBUG B " << i << "\n";
    if (myMessages[i].empty())
    {
        cout << "DEBUG C\n";
        myMessages[i]=MessageToAdd;
        break;
    }
    else
    {
        i++;
        cout << "DEBUG D " << i << "\n";
    }
    cout << "DEBUG E\n";
}
cout << "DEBUG F\n";

and see what gets printed. Of course, you could trace the execution in a debugger but that would require you to do the work yourself. If you just post the output (first 100 lines if it's huge), then we can probably tell you what's wrong easily.


Actually, I think your problem is the cin.ignore. When I run your code, nothing works, neither Test nor Test Test Test. That's because it's ignoring the first 1080 characters I'm trying to input. Proof can be seen when you change those statements to:

cin.ignore(1);
getline (cin,MessageToAdd);
cout << MessageToAdd << "\n";

and you get est output when you enter test.

Take out the ignore line and try again. I'm not certain of this since you seem to indicate that Test works but I can't see this as being correct.


So here's what you need to do (at a bare minimum):

  • get rid of the cin.ignore altogether.
  • use return rather than mainMenu().
  • use if (MessageToAdd == "911") instead of if (str == "911").
  • let us know how it goes then.
like image 138
paxdiablo Avatar answered Mar 01 '23 09:03

paxdiablo