3

每个人。我是一位经验丰富的 C 程序员,正在努力适应 C++。我想做这个C语句的等价物......

sscanf(str, "%s %s", sub1, sub2);

...但是使用 C++ 的字符串对象。假设 str 是“hello world”,执行上述 sscanf 语句会将“hello”放入 sub1,将“world”放入 sub2。我知道我可以在 C++ 中使用类似的 C 函数,但我想使用 C++ 字符串对象而不是字符数组。我试过这个:

string q, h, w;
cout << "Type \"hello world\": ";
cin >> q;
istringstream x(q);
x >> h >> w;
if (h == "hello")
    cout << "Yes!\n";
else
    cout << "No!\n";
if (w == "world")
    cout << "Yes!\n";
else
    cout << "No!\n";

但它输出“Yes!No!”,这意味着它选择了“hello”而不是“world”。有任何想法吗?

4

2 回答 2

3

这是因为operator>>使用 withcin只会捕获“hello”短语,并且会在第一个分隔符处停止(在本例中为空格)。如果要捕获直到用户键入的第一行分隔符的整个输入行,则必须使用getline(cin, q). 的两个参数版本getline()使用换行符作为分隔符,但也有一个三参数版本允许您指定自定义行分隔符。

于 2012-01-14T04:40:46.153 回答
3

切勿在没有错误检查的情况下使用 iostream。正如杰森所说,阅读整行,不仅仅是一个标记,但即使这样也要检查错误:

std::string line;

if (std::getline(std::cin, line))
{
    std::string h, w;
    std::istringstream iss(line);

    if (iss >> h >> w)
    {
        // success
    }
    else
    {
        std::cerr << "Error reading your input.\n";
    }
}
else
{
    std::cerr << "Error reading from stdin!\n";
}

if如果您想继续阅读,可以将s 设为循环。

基本上,您可以检查每个格式化提取 ( getline, >>) 作为条件,因为结果可以转换为可测试的内容,并且条件将是false操作失败。因此,除非操作成功,否则您绝不能解释声称的收件人变量!

如果您将此检查添加到您的代码x >> h >> w;中,您将永远不会通过该行而不会失败。

于 2012-01-14T04:43:30.083 回答