C ++ getline или cin не принимает строку с пробелами, я искал в Google и все еще в тупике! - PullRequest
4 голосов
/ 30 июня 2010

Прежде всего, спасибо всем, кто мне помогает, это очень ценится!

Я пытаюсь сохранить строку с пробелами и специальными символами в MessageToAdd.

IЯ использую getline (cin,MessageToAdd);, и я также пытался cin >> MessageToAdd;.

Я так озадачен!При вводе примера ввода

Тест

Все работает как задумано.Однако, если бы я использовал

Test Test Test

Вся консоль просто моргнула бы быстро, пока я не нажал Ctrl C .

Мой стиль размещения переменных вверху, как мне сказали, устарел.Пожалуйста, прости меня, поскольку я все еще учу себя, и это просто сила привычки.Я буду менять свой стиль вскоре после того, как решу это:)

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);
}

1 Ответ

8 голосов
/ 30 июня 2010

Я скажу вам одну вещь, которая сразу же не так с вашим кодом, не ваша конкретная проблема, но, тем не менее, волосатая.

Я предполагаю, что ваша mainMenu() функция вызывает эту.В этом случае вы, похоже, заблуждаетесь, что:

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

вернется в ваше меню.Это будет не сделать это.То, что он будет делать, это снова вызвать код вашего главного меню, и в конечном итоге вы исчерпаете место в стеке.

Я подозреваю, что вам следует делать цикл в mainMenu(), а приведенный выше код должен простоиспользуйте return; вместо рекурсивного вызова mainMenu().

Это и тот факт, что я думаю, что вы должны сравнивать MessageToAdd с "911" вместо str.


Еще одна вещь, которую я хотел бы сделать, - поместить временный код отладки в:

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";

и посмотреть, что будет напечатано.Конечно, вы можете отслеживать выполнение в отладчике, но это потребует от вас выполнения работы самостоятельно.Если вы просто опубликуете вывод (первые 100 строк, если он огромен), то мы, вероятно, легко расскажем вам, что случилось.


На самом деле, я думаю, что ваша проблема - cin.ignore.Когда я запускаю ваш код, ничего не работает, ни Test, ни Test Test Test.Это потому, что он игнорирует первые 1080 символов, которые я пытаюсь ввести.Доказательство можно увидеть, когда вы измените эти операторы на:

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

и вы получите est вывод при вводе test.

Извлеките строку ignore и попробуйте снова,Я не уверен в этом, поскольку вы, похоже, указываете, что Test работает, но я не вижу в этом правильности.


Итак, вот что вам нужно сделать (как минимум):

  • избавиться от cin.ignore в целом.
  • использовать return вместо mainMenu().
  • использовать if (MessageToAdd == "911") вместо if (str == "911").
  • Дайте нам знать, как это будет происходить.
...