C++ 使用条件语句读取文本文件

Posted

技术标签:

【中文标题】C++ 使用条件语句读取文本文件【英文标题】:C++ reading a text file with conditional statements 【发布时间】:2015-07-16 01:54:15 【问题描述】:

我正在尝试读取文本文件中的行,标记该行,然后继续对 switch 和 break 块中的下一行执行相同操作,但是在我的程序到达第一个 break 之后,它退出循环并忽略文件的其余部分。

ifstream in("test.txt");
    string line,buffer;
    unsigned int firstLetter = 0;
    //istringstream iss;

    if( in.is_open() )
        
            istringstream iss;
            while(getline(in,line))
            
                iss.str(line);
                char firstChar = line.at( firstLetter );
                switch ( firstChar )
                
                    case 'D':
                    while (getline(iss,buffer,'-'))
                    //print each token, one per line
                        cout<<"buffer: "<<buffer<<" "<<endl;
                    
                    break;
                    case 'R':
                    while ( getline(iss,buffer,'-') )
                    cout<<"buffer: "<<buffer<<" "<<endl;
                    break;
                
                           
        

这是文本文件的内容:

D-Rise of the Titans-25.50-2009-12
D-23 Jump Street-20.00-2013-5
D-Home Alone-24.00-1995-16
D-Twin Warriors-24.00-2011-14
R-XXX-Pierce-Hawthorne-11-13
R-Forbidden Kingdom-Pierce-Hawthorne-13-31
R-23 Jump Street-Troy-Barnes-1-3
R-Home Alone-Shirley-Bennett-1-3
R-Modern Family-Abed-Nadir-10-66

但是当我运行我的代码时,我得到了这个:

buffer: D 
buffer: Rise of the Titans 
buffer: 25.50 
buffer: 2009 
buffer: 12

这是文本文件中第 1 行的内容,我怎样才能转到下一行并一直这样做到文件末尾?

【问题讨论】:

出于好奇,您认为firstLetter 在评估声明char firstChar = line.at( firstLetter ); 时有什么价值?如果您的回答是“我不知道”,那么您的公司就很好,因为发布的代码也没有。该值为不确定 @WhozCraig firstLetter 为 0;我通常会省略初始化整数,因为大多数情况下它们的默认值为零,但好在你赶上了这一点,为了清楚起见,我将对其进行编辑哈哈 好,认真地,改掉这个习惯。除非在 eval 之前直接赋值是不可避免的,否则初始化应该总是在实践中进行。随机机会不是您应该寻求的路径。也就是说,将 istringstream inside 移动到 while-getline 并将其初始化为 istringstream iss(line); @WhozCraig 工作!!!!!!!!!谢谢 【参考方案1】:

您正在更改 std::istringstream 对象的内容,但状态标志保持不变(即,您的 eof 位已点亮)。一个示例,通过标准输入使用您的输入数据进行修改:

#include <iostream>
#include <fstream>
#include <sstream>
#include <string>
using namespace std;

int main()

    istream& in = std::cin;
    string line,buffer;

    istringstream iss;
    while(getline(in,line))
    
        if (!line.empty())
        
            iss.str(line);
            std::cout << "line at eof: " << iss.eof() << '\n';

            char firstChar = line.at(0);
            switch ( firstChar )
            
                case 'D':
                    while (getline(iss,buffer,'-'))
                        cout<<"buffer: "<<buffer<<" "<<endl;
                    break;

                case 'R':
                    while ( getline(iss,buffer,'-') )
                        cout<<"buffer: "<<buffer<<" "<<endl;
                    break;
            
        
    

输出

line at eof: 0
buffer: D 
buffer: Rise of the Titans 
buffer: 25.50 
buffer: 2009 
buffer: 12 
line at eof: 1
line at eof: 1
line at eof: 1
line at eof: 1
line at eof: 1
line at eof: 1
line at eof: 1
line at eof: 1

要解决这个问题,要么在每次迭代之前清除流的状态,要么只是将字符串流移动到 while 循环内,用行初始化。前者在下面完成;我把后者留给你做练习:

#include <iostream>
#include <fstream>
#include <sstream>
#include <string>
using namespace std;

int main()

    istream& in = std::cin;
    string line,buffer;

    istringstream iss;
    while(getline(in,line))
    
        if (!line.empty())
        
            iss.clear(); // <<=== ADDED HERE
            iss.str(line);
            std::cout << "line at eof: " << iss.eof() << '\n';

            char firstChar = line.at(0);
            switch ( firstChar )
            
                case 'D':
                    while (getline(iss,buffer,'-'))
                        cout<<"buffer: "<<buffer<<" "<<endl;
                    break;

                case 'R':
                    while ( getline(iss,buffer,'-') )
                        cout<<"buffer: "<<buffer<<" "<<endl;
                    break;
            
        
    

输出

line at eof: 0
buffer: D 
buffer: Rise of the Titans 
buffer: 25.50 
buffer: 2009 
buffer: 12 
line at eof: 0
buffer: D 
buffer: 23 Jump Street 
buffer: 20.00 
buffer: 2013 
buffer: 5 
line at eof: 0
buffer: D 
buffer: Home Alone 
buffer: 24.00 
buffer: 1995 
buffer: 16 
line at eof: 0
buffer: D 
buffer: Twin Warriors 
buffer: 24.00 
buffer: 2011 
buffer: 14 
line at eof: 0
buffer: R 
buffer: XXX 
buffer: Pierce 
buffer: Hawthorne 
buffer: 11 
buffer: 13 
line at eof: 0
buffer: R 
buffer: Forbidden Kingdom 
buffer: Pierce 
buffer: Hawthorne 
buffer: 13 
buffer: 31 
line at eof: 0
buffer: R 
buffer: 23 Jump Street 
buffer: Troy 
buffer: Barnes 
buffer: 1 
buffer: 3 
line at eof: 0
buffer: R 
buffer: Home Alone 
buffer: Shirley 
buffer: Bennett 
buffer: 1 
buffer: 3 
line at eof: 0
buffer: R 
buffer: Modern Family 
buffer: Abed 
buffer: Nadir 
buffer: 10 
buffer: 66 

【讨论】:

【参考方案2】:

问题是您遍历 istringstream 的内容,直到它失败。然后,您在其余行中重复使用相同的 istringstream。您需要清除其中的失败/eof 位。

使用 iss.clear() 来执行此操作。

#include <iostream>
#include <sstream>
#include <fstream>

int main()
  ifstream in('test.txt');
  if (in.is_open())
    string line, buffer;
    istringstream iss;
    while (getline(in, line))
      iss.str(line);
      iss.clear();
      char c = line[0];
      switch (c)
        case 'D':
          while (getline(iss, buffer, '-'))
            cout << "buffer: " << buffer << endl;
          
          break;
        case 'R':
          while (getline(iss, buffer, '-'))
            cout << "buffer: " << buffer << endl;
          
          break;
      
   
   return 0;

【讨论】:

以上是关于C++ 使用条件语句读取文本文件的主要内容,如果未能解决你的问题,请参考以下文章

C++之文件的读取和写入操作(文本文件和二进制文件)

将文本文件中的信息读取到文本文件中的 3 个不同数组中(c++)

C++文件读写操作逐字符读取文本和逐行读取文本

C++ 和读取大型文本文件

❥关于C++之写入/读取文本文件

Shell脚本 文本测试整数值比较字符串比较 条件测试操作 if语句应用实例