C++ 如何正确解析文件?(使用中断/继续)

C++ 如何正确解析文件?(使用中断/继续),c++,iteration,file-processing,C++,Iteration,File Processing,例如,我有如下数据: 34 foo 34巴 34 qux 62 foo1 62倍 78倍 这些将根据第一列进行排序 我想做的是处理以34开头的行,但我也希望 文件迭代在没有找到更多的34后退出,无需扫描 通过整个文件。我该怎么做 原因是要处理的行数非常大(~10^7)。 而那些以34开头的只占1-10%左右 我知道我可以grep这些行并将其输出到另一个文件中,但这太单调了,会消耗更多的磁盘空间 此代码说明了我使用“继续”失败的尝试: #包括 #包括 #包括 #包括 使用名称空间std; int

例如,我有如下数据:

34 foo
34巴
34 qux
62 foo1
62倍
78倍

这些将根据第一列进行排序

我想做的是处理以34开头的行,但我也希望 文件迭代在没有找到更多的34后退出,无需扫描 通过整个文件。我该怎么做

原因是要处理的行数非常大(~10^7)。 而那些以34开头的只占1-10%左右

我知道我可以grep这些行并将其输出到另一个文件中,但这太单调了,会消耗更多的磁盘空间

此代码说明了我使用“继续”失败的尝试:

#包括
#包括
#包括
#包括
使用名称空间std;
int main(){
弦线;
ifstream myfile(“mydata.txt”);
矢量数据表;
如果(myfile.is_open())
{
而(!myfile.eof())
{
弦流ss(线);
int FirstCol;
字符串第二列;
if(FirstCol!=34){
继续;
}
//这将跳过除34以外的选项
//但仍将遍历所有文件
//直到最后。
//对FirstCol和SecondCol的一些处理
ss>>第一列>>第二列;

不能使用
break
而不是
continue
continue
返回到循环的头部,只跳过当前迭代,而
break
将永远离开循环

另一方面,如果由于任何原因无法读取文件(例如,当您的程序试图访问文件时,用户删除了文件,用户删除了文件所在的U盘等),则您的代码存在一个错误,导致文件挂起。这是因为循环条件,例如:

while (!file.eof())
危险的!如果文件流进入错误状态,
eof
将永远不会是
true
,循环将持续不断……您需要测试文件是否处于任何可读状态。这只需使用隐式转换为布尔值即可:

while (file)

这将导致循环仅在文件未完成读取且无错误的情况下运行。

使用
中断
而不是
继续
继续
返回循环的头部,只跳过当前迭代,而
中断
将永远离开循环

另一方面,如果由于任何原因无法读取文件(例如,当您的程序试图访问文件时,用户删除了文件,用户删除了文件所在的U盘等),则您的代码存在一个错误,导致文件挂起。这是因为循环条件,例如:

while (!file.eof())
危险的!如果文件流进入错误状态,
eof
将永远不会是
true
,循环将持续不断……您需要测试文件是否处于任何可读状态。这只需使用隐式转换为布尔值即可:

while (file)

这将导致循环仅在文件未完成读取且无错误时运行。

假设文件中的数据按第一列排序(如我在示例中注意到的),则应替换

if (FirstCol != 34) 
{
    continue;
}
比如:

if (FirstCol > 34) 
{
    break;
}

假设文件中的数据按第一列排序(正如我在您的示例中注意到的),您应该替换

if (FirstCol != 34) 
{
    continue;
}
比如:

if (FirstCol > 34) 
{
    break;
}

基于文件按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;
}
#包括“stdafx.h”
#包括
#包括
#包括
#包括
使用名称空间std;
int main(){
弦线;
ifstream myfile(“mydata.txt”);
矢量数据表;
如果(myfile.is_open())
{
bool found34=假;
while(myfile)
{
弦流ss(线);
int FirstCol;
字符串第二列;
//这将跳过除34以外的选项
//但仍将遍历所有文件
//直到最后。
//对FirstCol和SecondCol的一些处理
我的文件>>第一列>>第二列;

cout基于文件按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;
}
#包括“stdafx.h”
#包括
#包括
#包括
#包括
使用名称空间std;
int main(){
弦线;
ifstream myfile(“mydata.txt”);
矢量数据表;
如果(myfile.is_open())
{
bool found34=假;
while(myfile)
{
弦流ss(线);
int FirstCol;
字符串第二列;
//这将跳过除34以外的选项
//但仍将遍历所有文件
//直到最后。
//对FirstCol和SecondCol的一些处理
我的文件>>第一列>>第二列;

cout假设该行应该包含输入,最好读入一些内容!更改:

  while (! myfile.eof() ) 
致:


假设该行应该包含输入,那么最好阅读以下内容