c++ - C++ 中 fstream 的行为
问题描述
我制作了以下脚本,应该从文件中读取:
char match[] = "match";
int a;
int b;
inp >> lin;
while(!inp.eof()) {
if(!strcmp(lin, match)) {
inp >> a >> b;
cout << a << " " << b <<endl;
}
inp >> lin;
}
inp.close();
return num_atm;
}
它应该读取所有单词,如果一行以 match 开头,它还应该打印该行的其余部分。
我的输入文件是这样的:
match 1 2 //1
match 5 2 //2
nope 3 6 //3
match 5 //4
match 1 4 //5
match 5 9 //6
它将正确打印 1 2、5 2 并跳过 3 6。但是,它会卡住并继续打印 5 0 并永远继续打印 5 0。我得到匹配被放入 b,这是一个整数,但我不明白为什么这是循环的。输入读取不应该匹配 4 一次,尝试读取/写入 5 并匹配,然后使用第 4 行和第 5 行的匹配完成?然后它应该接下来读取数字 1 和 4,然后从数字 6 开始匹配。
我也明白,由于这个词不适合整数,它会在第五行再次读取 match,但这不是它的作用。
它回到它已经读取的第四行中的匹配,并再次读取它。为什么是这样?
解决方案
当您阅读时,>>
行尾的处理方式与空格相同:它们只是更多被跳过的空格。这意味着你看到
match 1 2
match 5 2
nope 3 6
match 5
match 1 4
match 5 9
但程序看到
match 1 2 match 5 2 nope 3 6 match 5 match 1 4 match 5 9
让我们快进到事情向南的地方
流的内容:
nope 3 6 match 5 match 1 4 match 5 9
加工
inp >> lin; // reads nope stream: 3 6 match 5 match 1 4 match 5 9
if(!strcmp(lin, match)) { // nope != match skip body
}
inp >> lin; // reads 3 stream: 6 match 5 match 1 4 match 5 9
if(!strcmp(lin, match)) { // 3 != match skip body
}
inp >> lin; // reads 6 stream: match 5 match 1 4 match 5 9
if(!strcmp(lin, match)) { // 6 != match skip body
}
inp >> lin; // reads match stream: 5 match 1 4 match 5 9
if(!strcmp(lin, match)) { // match != match Enter body
inp >> a >> b; // reads 5 and fails to parse match into an integer.
// stream: match 1 4 match 5 9
// stream now in failure state
cout << a << " " << b <<endl; // prints 5 and garbage because b was not read
}
inp >> lin; // reads nothing. Stream failed
if(!strcmp(lin, match)) { // match != match Enter body
inp >> a >> b; // reads nothing. Stream failed
// stream: match 1 4 match 5 9
// stream now in failure state
cout << a << " " << b <<endl; // prints g and garbage because b was not read
}
因为没有任何东西被读过,while(!inp.eof())
是完全没有价值的。永远无法到达文件的末尾。该程序将永远循环,可能会打印它上次读取的任何内容。成功读取。
如果您有一条没有 2 个数字的匹配线,则解决此问题完全取决于您想要做什么,但典型的框架看起来像
std::string line;
while(std::getline(inp, line) // get a whole line. Exit if line can't be read for any reason.
{
std::istringstream strm(line);
std::string lin;
if(strm >> lin && lin == match) // enters if lin was read and lin == match
// if lin can't be read, it doesn't matter.
// strm is disposable
{
int a;
int b;
if (strm >> a >> b) // enters if both a and b were read
{
cout << a << " " << b <<"\n"; // endl flushes. Very expensive. just use a newline.
}
}
}
输出应该是这样的
1 2
5 2
1 4
5 9
如果您想使用匹配 5b
...如果文件中没有,则取决于您要b
输入的内容。
推荐阅读
- javascript - 我不知道如何修复我的成绩计算器功能
- php - 将 SQL 查询从单列单值 LIKE 更新为多列单值搜索
- javascript - Javascript移动重定向,页面不断刷新
- python - 如何使用 tkinter after() 一次创建一个矩形?
- python - 如何打开一系列 csv 文件,在文件名中使用修改后的字符串变量进行编辑和重新保存
- java - 致命异常:AsyncTask #1 java.lang.RuntimeException:执行 doInBackground() 时出错
- java - 在抽象类上实现 ID 的优雅方式
- reactjs - dataLayer.push() 第一次不起作用
- sql - 使用存储过程从子表更改父表中的数据?
- mysql - MYSQL - 按另一个表排序一个表