简体   繁体   English

C ++将文件读入结构

[英]C++ reading a file into a struct

Using fstreams I have a file opened that contains numerous lines. 使用fstreams,我打开了一个包含许多行的文件。 Each contiguos set of 4 lines are such that: the first line is an int, the second and third are strings and fourth is a double. 每组连续的4行是这样的:第一行是int,第二行和第三行是字符串,第四行是双精度。 This sequence continues till EOF. 此序列一直持续到EOF。

I'm attempting to load these lines into a struct array: 我正在尝试将这些行加载到struct数组中:

struct Library {
    int id;
    string title;
    string artist;
    double price;
};

and the code I'm trying to implement to load data into the struct is this: 我试图实现的将数据加载到结构中的代码是这样的:

const int LIMIT = 10
Library database[LIMIT];
ifstream file;
file.open("list.txt");

if(file) {
    while(!(file.eof()) && counter < LIMIT) {
        file >> database[counter].id;
        getline(file, database[counter].title;
        getline(file, database[counter].artist;
        file >> database[counter].price;
    }
} else {
   ...
}

// Using the following to debug output
for(int i = 0; i < counter; i++) {
    cout << "ID:     " << database[i].id << endl
         << "Title:  " << database[i].title << endl
         << "Artist: " << database[i].artist << endl
         << "Price:  " << database[i].price << endl
         << "-----------------------" << endl;
}

The file I'm trying to throw at this thing is 我要扔给这个东西的文件是

1234
Never Gonna Give You Up
Rick Astley
4.5
42
Thriller
Michael Jackson
32.1

The problem I'm having here is that between reading the id and title using file >> ... and getline(...) is that somewhere a newline bite is being introduced screwing up the output, which displays this monstrosity... 我在这里遇到的问题是,在使用file >> ...getline(...)读取idtitle之间的问题是,在某处引入了换行符,从而破坏了输出,从而显示了这种怪异...

ID:     1234
Title:  
Artist: Never Gonna Give You Up
Price:  0
--------------------
ID:     0
Title:  
Artist:
Price:  0
--------------------

The solution is probably the most basic of solutions, but mainly because I can't figure out exactly what is going on with the newline bite I can't combobulate a phrase to shove into google and do my stuff there, and I'm at the stage where I've been looking at a problem so long, basic knowledge isn't working properly - such as how to handle basic input streams. 该解决方案可能是最基本的解决方案,但是主要是因为我无法弄清楚换行符到底是怎么回事,我无法梳理要推入google并在那做我的工作的短语,而我在在我一直在研究问题的阶段,基础知识无法正常工作-例如如何处理基本输入流。

Any form of help would be much appreciated! 任何形式的帮助将不胜感激! Thanks in advance :) 提前致谢 :)

This happens because the >> operator for the input stream only grabs part of a line, and does not always grab the newline character at the end of the line. 发生这种情况是因为输入流的>>运算符仅捕获行的一部分,而并不总是捕获行尾的换行符。 When followed by a call to getline , the getline will grab the rest of the line previously parsed, not the line after it. 在调用getlinegetline将获取先前解析的其余行,而不是其后的行。 There are a few ways to solve this: you can clear the buffer from the input stream after each read, or you can simply get all your input from getline and just parse the resulting strings into an integer or a double when you need to with calls to stoi or stod . 有几种解决方法:可以在每次读取后从输入流中清除缓冲区,或者可以简单地从getline获取所有输入,并在需要进行调用时仅将结果字符串解析为整数或双精度型。到stoistod

As a side note, you don't want to detect the end of your file the way you presently are. 附带说明一下,您不想像现在那样检测文件的结尾。 See why is eof considered wrong inside a loop condition? 看看为什么在循环条件下eof被认为是错误的?

You can solve this problem by adding: 您可以通过添加以下内容来解决此问题:

fflush(file);

everytime before you use getline(file, ...) . 每次使用getline(file, ...) Basically this will clear the input buffer before you use the getline() function. 基本上,这将在使用getline()函数之前清除输入缓冲区。 And fflush() is declared in the cstdio library. fflush()在cstdio库中声明。

file >> database[counter].id;

will read, in this case, a whitespace separated sequence of characters that is interpreted as an int. 在这种情况下,将读取由空格分隔的字符序列,该序列被解释为int。 The newline is considered whitespace. 换行符被认为是空格。 You should now be sitting on that newline character, thus the getline() will read nothing -- successfully -- and increment the file position just past that. 现在,您应该坐在该换行符上,因此getline()将不会读取任何内容 -成功-并在该位置之后增加文件位置。

You may be better off using getline() for each line and then separately interpreting the lines from the reading. 您最好对每行使用getline(),然后从读数中分别解释各行。 For example, the first line read could be interpreted with a subsequent std::stoi() to get the integer representation from the string. 例如,可以使用后续的std :: stoi()解释读取的第一行,以从字符串中获取整数表示形式。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM