【问题标题】:C++: reading from txt file with multiple delimeterC ++:从具有多个分隔符的txt文件中读取
【发布时间】:2016-11-01 21:33:17
【问题描述】:

有没有办法从包含学生记录但由不同字符分隔的文件中读取?我的文字如下:

125 {John_BROWN_Biology} {100_81}
245 {Amanda_SMITH_Chemistry} {83_74}
436 {Michael_CLARK_Calculus} {35_48}

我必须将它们存储在单独的数组中,以便计算它们的平均值并按升序排列。 我是这样用C++写的代码:

int rank;
char st_info[SIZE];
int grades[SIZE];
bool success1 = false;
bool success2 = false;
bool success3 = false;

ifstream inFile;
inFile.open("records.txt");
string line;
int i=0, j=0;
while (!inFile.getline(rank, 30, '{').eof){
    inFile.getline(st_info, SIZE, '_');
    inFile.getline(words_array, SIZE, '_');
}
while (!success1)
{
    getline(inFile,Line,'{'); // get values for info array
    stringstream iss1; 
    iss1 << Line; //Put the string into a stream
    iss1 >> rank; //To send data as an int.
    cout << "STUDENT NUMBER:" << rank << "  ";
    while (!success2){
    // for the info in {} part
        getline(inFile,Line,'_'); 
        stringstream iss; 
        iss << Line; 
        iss >> st_info[i];
        cout <<"STUDENT INFO:" << st_info[i] << "   ";
        i++;
        if (getline(inFile,Line,'}')){
            stringstream iss2; 
            iss2 << Line; 
            iss2 >> st_info[i];
            cout << st_info[i] << " ";
            i=0;
            success2 = true;
        }
    }
    getline(inFile,Line,'{'); 
    stringstream iss3; 
    iss3 << Line; 
    iss3 >> grades[j]; 
    cout << "GRADES: "<< grades[i] << " ";
    j++;
    while (!success3){
        getline(inFile,Line,'_');
        stringstream iss4; 
        iss4 << Line;
        iss4 >> grades[j];
        cout << grades[i] << "  ";
        j++;
        if (getline(inFile,Line,'}')){
            stringstream iss5; 
            iss5 << Line;
            iss5 >> grades[j];
            cout << grades[i] << "  ";
            j=0;
            success3 = true;
        }
    }
} 

但是,作为我得到的输出:

1 J 100
2 A 100
4 M 100

试图修复,但情况变得更糟。有谁能帮忙吗?提前致谢。

【问题讨论】:

  • 从表面上看,这绝对是矫枉过正,学习曲线非常陡峭,但我可以使用 Boost Spirit 在手腕上轻弹两下将其淘汰。见 www.boost.org。如果你做了很多解析,那么花时间学习这个工具是非常值得的。

标签: c++ ifstream formatted-input


【解决方案1】:

您的方法和代码存在几个问题:

  • istream::getline() 无法读取整数。它只能读入一个 char 数组的数组。
  • eof 是一个函数而不是一个属性
  • &lt;&lt; &gt;&gt;stringstream 混合以解析数据的方式不是最佳的。
  • 使用&gt;&gt;st_info[i] 从字符串流中提取单个字符,这将覆盖现有信息。
  • 当然还有其他问题。

因此,我建议您使用以下框架,逐行读取文件,并使用字符串流分别解析每一行。请注意,我只使用getline() 的非成员变体来读取字符串而不是 char 数组(这让我不必考虑缓冲区溢出):

...
char delim;  
int rank;
string names, grades;
string line;

while (getline(inFile, line))   // read line by line 
{
    stringstream sst{line};     // then parse the line using a string stream

    sst>>rank;                  // read an integer
    sst>>delim;                 // skip white and read a single char 
    if (delim!='{') {
        cout<<"Error on line: { expected for name instead of "<<delim<<endl; 
        continue;   // next line, please !! 
    }
    getline(sst,names, '}');  // TO DO: error handling
    sst>>delim; 
    if (delim!='{') {
        cout<<"Error on line: { expected for grades instead of "<<delim<<endl; 
        continue;   // next line, please !! 
    }
    getline(sst,grades, '}');  // TO DO: additional error handling

    cout << rank<<" "<<names<<" "<<grades<<endl; // temporary:  

    // TO DO: parse names and grades by using further stringstreams 
} 

Online demo

请注意,我使用了一种简单的解析方法:读取一个字符并检查它是否与预期的开始字符匹配,然后使用getline() 读取直到结束字符(后者被消耗但从字符串中排除)。这不允许在您的格式中嵌套 {...}

【讨论】:

  • 谢谢!我知道如何处理休息,再次感谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-05-05
  • 2017-07-30
  • 2017-07-13
  • 1970-01-01
  • 1970-01-01
  • 2016-08-02
  • 1970-01-01
相关资源
最近更新 更多