cin.getline没有执行c ++

时间:2011-07-25 06:27:59

标签: c++ inputstream getline

出于一些奇怪的原因,当我把它放在其他if块中时,我的输入行cin.getline(oneLine, 80);被完全忽略了。我无法理解为什么,因为当我将它移动到程序中的其他位置时,它可以工作。

     else if (choice == "user-id")
     {   
        cout << endl << "Enter a full name e.g. John Smith ";
        char oneLine[80];
        cin.getline(oneLine, 80);
        cout << oneLine;                        
     }

这是我的其余代码。我是C ++的新手,所以我确信我的许多惯例充其量也是值得怀疑的。

int main( )
{
    while (true)
        {

        int pause;
        string choice = "proceed";
        string nameGiven;
        string userIdGiven;
        string result;
        using namespace std ;

        while ((choice != "name") && (choice != "user-id"))
        {   
            cout << "Would you like to search for a name or user-id? ";
            cin >> choice;
            if ((choice != "name") && (choice != "user-id"))
               cout <<"Please enter a valid choice (name or user-id)" << endl;
        }

        if (choice == "name") 
        {
            string dataType = "int";
            while (true)
            {    
                cout << endl << "Enter a valid user id (4 digit maximum) ";
                cin >> userIdGiven;

                if (valid(userIdGiven))
                   break;
                else
                    cout << endl << "Not a valid number. " << endl;
                   continue;
             }
             result = findData(userIdGiven, dataType);
             cout << "name: " << result;

         }

         else if (choice == "user-id")
         {   
            cout << endl << "Enter a full name e.g. John Smith ";
            char oneLine[80];
            std::getline(oneLine, 80);
            cout << oneLine;                       
         }

        string ans;
        cout << endl << "Would you like to play again? (yes/no) " << endl;
        cin >> ans;
        if ( (ans == "yes") || (ans == "Yes") || (ans == "Y") || (ans == "y") )
             continue;
          else
              break;

        cin >> pause;
     } 
return 0;
}

3 个答案:

答案 0 :(得分:2)

您的std::cin对象在之前的输入操作中处于错误状态(std::cin.good() == false)。例如,您可能尝试读取数字,但输入缓冲区中只有非数字字符。

在继续使用std::istream之前,请务必检查输入是否成功。

注意: 不要使用与char*一起使用的旧输入函数,因为它们比新的操作更复杂且安全性更低在std::string。在您的情况下,请使用std::getline(std::istream&, std::string&, char = '\n')

答案 1 :(得分:1)

twsaef的评论实质上是正确的...你正在将一个字符串串入选择,它会消耗字符直到但不包括下一个空白字符 - 你可能正在键入换行符来终止输入,所以它留在缓冲区中。然后你使用getline看到那个换行符并读取一个空字符串。

最简单的解决方案是调用getline()来读取初始字符串,然后检查选项是“name \ n”还是“user-id \ n”。更好 - 编写一个“修剪”函数,以便在比较之前从行中删除空格(提升字符串库已经具有此功能)。否则,您可以使用std::cin中的读取和忽略字符,直到获得'\ n'。或者甚至读一行然后放入一个字符串流并从那里读取一个字符串....很多选择。

并且,请检查您的流状态!尝试使用:

if (std::cin >> x)
    // x was parsed from stream... use it
else
    // print an error so you know where things failed!

答案 2 :(得分:0)

FWIW,我在看到更新之前猜到了问题是什么(这是愚蠢的常见),并在其他猜测中对自己轻笑(尽管即使他们错过了OP的问题他们也能提出非常好的观点)。

代码行正常工作并且正如所宣传的那样。它不会像你想要的那样工作。

当您从std :: cin读取时,暂停程序并等待输入。导致暂停的原因是读操作缺少足够的输入数据。

输入一次一行地输入您的程序。请记住,控制台窗口也是一个程序。它负责将用户的按键转换为文本字符(真正的字节),处理退格键等内容,并将其全部收集到行中。

所以说你用int读了一个operator>>,然后用getline读了一行。在用户点击Return键之前,程序将看不到int,因为这会触发控制台向您的程序提供一行输入。

operator>>将跳过前导空格,读取整数,单独留下尾随空格。换行符是空格。输入中有换行符(显然在行的末尾)。

getline() 不会跳过任何前导空格,直到下一个换行符为止。下一个字符恰好是换行符,因此getline()愉快地读取一个空行,程序继续执行该操作。

那你怎么解决这个问题?如果您正在阅读cin的所有输入,那么您希望程序在每次进行阅读操作时都会暂停。这样做的方法是确保在那时从来没有任何可用的数据,并且这样做的方法是在每次阅读时阅读所有可用的内容 - 即整行 -

所以,请务必阅读cin的完整一行。 正如wilx所述,请使用免费功能std::getline。不要使用流的.getline成员函数。使用std::string表示文本字符串。这就是它的用途。它会让你的生活更加轻松。这也意味着如果你期望一个整数并且用户键入“76长号”,你就可以摆脱“长号”数据(并且可以决定你是想把它扔掉,还是对用户大喊大叫,让他重新输入一个没有任何有趣评论的数字。)

但那又怎么样?你只需要一个字符串,你可能想要一个int。幸运的是,有一个简单的解决方案。我们可以使用标准库类std::stringstream将字符串视为流数据源。我们只是从字符串构造一个字符串流,然后像std::cin一样使用它 - 即我们可以用operator>>读取它,检查流状态以查看读取是否成功等等。

如sbi所述,请务必检查阅读是否成功!如果您尝试阅读int并且流中包含“hi mom”等文字,则(a){{ 1}}变量将被更改(因此,如果它未被初始化,它仍未被初始化,这是一个非常危险的状态),并且(b)流将进入“失败”状态,将读取,直到你清除它,并且(c)即使你清除它,数据仍将存在,如果你不小心可能会触发无限循环。

幸运的是,通过单独的int,我们可以避免各种并发症。如果阅读失败,那么所有这些事情都发生在stringstream对象上 - 而不是stringstreamstd::cin操作将始终在getline上成功,除非用户明确指出文件结尾(Linux上的control-D字符或Windows上的control-Z)。我们可以轻松检查std::cin是否处于失败状态,循环并创建另一个 - 旧的将自动清理。

我们甚至可以制作一个帮助函数,如:

stringstream

template <typename T> // Attempt to read into to_read, and return whether successful. bool read_primitive_from_input(std::istream& input, T& to_read) { std::string line; std::getline(std::cin, line); std::istringstream iss(line); return iss >> to_read; } 由标准库标头std::stringstream提供。 <sstream>来自std::string,当然。

相关问题