我有以下数据,例如:
34 poo
34 bar
34 qux
62 foo1
62 qux
78 qux
这些是根据第一列进行排序的。
我想要做的是处理以34开头的行,但我也想要 文件迭代在找不到34s后退出,无需扫描 通过整个文件。我该怎么做?
原因是因为要处理的行数非常大(~10 ^ 7)。 那些以34开头的人只占其中的1-10%左右。
我知道我可以grep这些行并将其输出到另一个文件中,但这太繁琐了,会产生更多的磁盘空间消耗。
此代码说明了我使用“继续”失败的尝试:
#include <iostream>
#include <vector>
#include <fstream>
#include <sstream>
using namespace std;
int main () {
string line;
ifstream myfile ("mydata.txt");
vector<vector<string> > dataTable;
if (myfile.is_open())
{
while (! myfile.eof() )
{
stringstream ss(line);
int FirstCol;
string SecondCol;
if (FirstCol != 34) {
continue;
}
// This will skip those other than 34
// but will still iterate through all the file
// until the end.
// Some processing to FirstCol and SecondCol
ss >> FirstCol >> SecondCol;
cout << FirstCol << "\t << SecondCol << endl;
}
myfile.close();
}
else cout << "Unable to open file";
return 0;
}
答案 0 :(得分:7)
使用break
代替continue
! continue
返回到循环的头部,只跳过当前迭代,而break
离开循环是好的。
在一个不相关的说明中,如果由于任何原因无法读取文件,您的代码会出现导致挂起的错误(例如,当您的程序尝试访问该文件时,用户将其删除,用户会删除USB文件夹等等)。这是因为循环条件如:
while (!file.eof())
危险!如果文件流进入错误状态,eof
永远不会是true
,循环将继续打开......您需要测试该文件是否处于任何可读状态。这可以通过使用隐式转换为布尔值来完成:
while (file)
只有在文件未完成读取并且没有错误时,这将导致循环运行。
答案 1 :(得分:2)
假设文件中的数据按第一列排序(正如我在您的示例中所注意到的那样),您应该替换来自
的if语句if (FirstCol != 34)
{
continue;
}
有类似的东西:
if (FirstCol > 34)
{
break;
}
答案 2 :(得分:1)
基于FirstCol对文件进行排序的假设,使用状态变量来指示您是否找到了第一个。一旦找到第一个,一旦找到一个!= 34的列,就可以摆脱循环。
例如,假设您的数据现在是:
15 boo
32 not
34 foo
34 bar
34 qux
62 foo1
62 qux
78 qux
...此代码可以满足您的需求:
#include "stdafx.h"
#include <iostream>
#include <vector>
#include <fstream>
#include <sstream>
using namespace std;
int main () {
string line;
ifstream myfile ("mydata.txt");
vector<vector<string> > dataTable;
if (myfile.is_open())
{
bool found34 = false;
while ( myfile )
{
stringstream ss(line);
int FirstCol;
string SecondCol;
// This will skip those other than 34
// but will still iterate through all the file
// until the end.
// Some processing to FirstCol and SecondCol
myfile >> FirstCol >> SecondCol;
cout << FirstCol << "\t" << SecondCol << endl;
switch( FirstCol )
{
case 34 :
found34 = true;
cout << "Processing a 34";
continue; // keep looping
default :
if( found34 )
{
// we found all the 34's and now we're on to the next value, so we're done
cout << "We're done.";
break;
}
else
{
// we haven't found the first 34 yet, so keep scanning until we do
cout << "Keep on looking for a 34...";
continue;
}
}
}
myfile.close();
}
else cout << "Unable to open file";
return 0;
}
答案 3 :(得分:1)
假设行应该包含输入,那么读取内容是个好主意!变化:
while (! myfile.eof() )
为:
while ( getline( myfile, line ) )