使用标签和空格读入文件

时间:2018-03-03 03:48:25

标签: c++ file io

我有一个这种格式的文本文件:

Petroleum Engineering       94600   175500 

Marine Engineering  73900   123200 

Economics and Mathematics   60000   122900 

Geophysics  54100   122200 

Cognitive Science   54000   121900 

我所拥有的是课程名称,平均早期职业薪酬和中期职业薪酬,所有这些都以标签分隔。带有多个单词的课程名称用空格分隔。

我想阅读课程名称并将其放在一个变量中,第一个支付在第二个变量中,第三个支付在第三个变量中。

    int main(){
        ifstream in;
        in.open("Salaries.txt");
        string course;
        int mid;
        int avg;
        if (in.fail()){
        cout<< "failed to open file";
        exit(1);
        }
        while(!in.eof()){
           in >> course >> avg >> mid;
           cout << course<<endl;
        }
      in.close();
     }

编译此代码时,它不输出任何内容,程序不会退出或终止。

评论中有人指出不推荐使用eof(),所以我试着改为:

        while(in >> course >> sm >> lg){     
            cout << course << endl;
       }

该过程退出而不向屏幕输出任何内容。我在输入文件上尝试了它,看起来像这样:

NCORES 1

NEW   0 

CORE   100   
INPUT 5000  
CORE 20

它接受字符串并将其放入一个变量中,然后获取数字并将其放入另一个变量中,并输出正确的输出。所以问题是原始文件中cours名称中的单词之间的空格,我不知道如何解释。

1 个答案:

答案 0 :(得分:3)

虽然您的代码确实存在其他问题,但您遇到的问题是operator>> string在遇到的第一个空格处停止读取的问题。这意味着在第一行,它会将Petroleum读入course,然后尝试将Engineering读入avg。由于avg是一个数字,但不起作用,因此转换失败。从那里开始,从流中读取的所有进一步尝试都失败了。

要解决此问题,您可能希望使用std::getline来阅读课程名称。它允许您指定将结束其读取的字符串的字符。在这种情况下,您显然希望为该参数传递制表符('\t')。

如果我这样做,我可能会将这三个项放入一个结构中,并为该结构重载operator>>

struct course {
    std::string name;
    long early_pay;
    long mid_pay;

    friend std::istream &operator>>(std::istream &is, course &c) { 
        if (std::getline(is, c.name, '\t')) {
            std::string temp;
            std::getline(is, temp, '\t');
            c.early_pay = std::stol(temp);
            std::getline(is, temp);
            c.mid_pay = std::stol(temp);
        }
        return is;
    }
};

然后读取数据并打印出课程名称将如下所示:

int main() {
    std::istringstream input(
R"(Petroleum Engineering    94600   175500 
Marine Engineering  73900   123200 
Economics and Mathematics   60000   122900 
Geophysics  54100   122200 
Cognitive Science   54000   121900 )");

    course c;

    while (input >> c)
        std::cout << c.name << '\n';
}