大家。我是一位经验丰富的C程序员,试图适应C ++。我想做相当于这个C语句...
sscanf(str, "%s %s", sub1, sub2);
...但是使用C ++的字符串对象。假设str是“hello world”,执行上面的sscanf语句会在sub1中放入“hello”,在sub2中放入“world”。我知道我可以在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";
但它输出“是!不!”,这意味着它选择了“你好”而不是“世界”。有什么想法吗?
答案 0 :(得分:3)
这是因为与operator>>
一起使用的cin
将仅捕获“hello”短语,并将停在第一个分隔符(在本例中为空格)。如果要捕获整个输入行直到用户键入的第一个行分隔符,则必须使用getline(cin, q)
。 getline()
的双参数版本使用换行符作为分隔符,但是有一个三参数版本,允许您指定自定义行分隔符字符。
答案 1 :(得分:3)
永远不要使用iostream而不进行错误检查。正如Jason所说,读取整行,而不仅仅是一个令牌,但即便如此,也要检查错误:
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
转换成循环。
基本上,您可以检查每个格式化的提取(getline
,>>
)作为条件,因为结果可转换为可测试的内容,如果操作,条件将为false
失败。因此,除非操作成功,否则您不得解释所声称的收件人变量!
如果您将此检查添加到代码x >> h >> w;
中,您将永远不会超过该行而不会失败。