C语言 C、读取多行文本文件
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/5827931/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
C, reading a multiline text file
提问by JC Leyba
I know this is a dumb question, but how would I load data from a multiline text file?
我知道这是一个愚蠢的问题,但我如何从多行文本文件加载数据?
while (!feof(in)) {
fscanf(in,"%s %s %s \n",string1,string2,string3);
}
^^This is how I load data from a single line, and it works fine. I just have no clue how to load the same data from the second and third lines.
^^这就是我从一行加载数据的方式,它工作正常。我只是不知道如何从第二行和第三行加载相同的数据。
Again, I realize this is probably a dumb question.
再次,我意识到这可能是一个愚蠢的问题。
Edit: Problem not solved. I have no idea how to read text from a file that's not on the first line. How would I do this? Sorry for the stupid question.
编辑:问题没有解决。我不知道如何从不在第一行的文件中读取文本。我该怎么做?对不起,这个愚蠢的问题。
回答by jiman
Try something like:
尝试类似:
/edited/
/编辑/
char line[512]; // or however large you think these lines will be
in = fopen ("multilinefile.txt", "rt"); /* open the file for reading */
/* "rt" means open the file for reading text */
int cur_line = 0;
while(fgets(line, 512, in) != NULL) {
if (cur_line == 2) { // 3rd line
/* get a line, up to 512 chars from in. done if NULL */
sscanf (line, "%s %s %s \n",string1,string2,string3);
// now you should store or manipulate those strings
break;
}
cur_line++;
}
fclose(in); /* close the file */
or maybe even...
或者甚至……
char line[512];
in = fopen ("multilinefile.txt", "rt"); /* open the file for reading */
fgets(line, 512, in); // throw out line one
fgets(line, 512, in); // on line 2
sscanf (line, "%s %s %s \n",string1,string2,string3); // line 2 is loaded into 'line'
// do stuff with line 2
fgets(line, 512, in); // on line 3
sscanf (line, "%s %s %s \n",string1,string2,string3); // line 3 is loaded into 'line'
// do stuff with line 3
fclose(in); // close file
回答by Random832
Putting \nin a scanf format string has no different effect from a space. You should use fgets to get the line, then sscanf on the string itself.
把\n在scanf格式串中具有从空间没有什么不同的效果。您应该使用 fgets 来获取行,然后在字符串本身上使用 sscanf。
This also allows for easier error recovery. If it were just a matter of matching the newline, you could use "%*[ \t]%*1[\n]"instead of " \n"at the end of the string. You should probably use %*[ \t]in place of all your spaces in that case, and check the return value from fscanf. Using fscanf directly on input is very difficult to get right (what happens if there are four words on a line? what happens if there are only two?) and I would recommend the fgets/sscanf solution.
这也允许更容易的错误恢复。如果只是匹配换行符的问题,您可以使用"%*[ \t]%*1[\n]"而不是" \n"在字符串的末尾。%*[ \t]在这种情况下,您可能应该使用代替所有空格,并检查 fscanf 的返回值。直接在输入上使用 fscanf 很难做到正确(如果一行中有四个单词会怎样?如果只有两个会怎样?)我推荐 fgets/sscanf 解决方案。
Also, as Delan Azabani mentioned... it's not clear from this fragment whether you're not already doing so, but you have to either define space [e.g. in a large array or some dynamic structure with malloc] to store the entire dataset, or do all your processing inside the loop.
此外,正如 Delan Azabani 所提到的......从这个片段中不清楚你是否还没有这样做,但是你必须定义空间[例如在一个大数组或一些带有 malloc 的动态结构中] 来存储整个数据集,或在循环内进行所有处理。
You should also be specifying how much space is available for each string in the format specifier. %sby itself in scanf is always a bug and may be a security vulnerability.
您还应该在格式说明符中指定每个字符串有多少可用空间。%sscanf 本身总是一个错误,可能是一个安全漏洞。
回答by Jonathan Leffler
First off, you don't use feof()like that...it shows a probable Pascal background, either in your past or in your teacher's past.
首先,您不会那样使用feof()……它显示了可能的 Pascal 背景,无论是在您的过去还是在您老师的过去。
For reading lines, you are best off using either POSIX 2008 (Linux) getline()or standard C fgets(). Either way, you try reading the line with the function, and stop when it indicates EOF:
对于阅读行,最好使用 POSIX 2008 (Linux)getline()或标准 C fgets()。无论哪种方式,您都可以尝试使用该函数读取该行,并在它指示 EOF 时停止:
while (fgets(buffer, sizeof(buffer), fp) != 0)
{
...use the line of data in buffer...
}
char *bufptr = 0;
size_t buflen = 0;
while (getline(&bufptr, &buflen, fp) != -1)
{
...use the line of data in bufptr...
}
free(bufptr);
To read multiple lines, you need to decide whether you need previous lines available as well. If not, a single string (character array) will do. If you need the previous lines, then you need to read into an array, possibly an array of dynamically allocated pointers.
要读取多行,您需要决定是否还需要可用的前几行。如果不是,则可以使用单个字符串(字符数组)。如果您需要前面的几行,那么您需要读入一个数组,可能是一个动态分配的指针数组。
回答by Delan Azabani
Every time you call fscanf, it reads more values. The problem you have right now is that you're re-reading each line into the same variables, so in the end, the three variables have the last line's values. Try creating an array or other structure that can hold all the values you need.
每次调用时fscanf,它都会读取更多值。您现在遇到的问题是您将每一行重新读取到相同的变量中,因此最后,这三个变量具有最后一行的值。尝试创建一个数组或其他结构来保存您需要的所有值。
回答by Manuel Mangual
I have an even EASIER solution with no confusing snippets of puzzling methods (no offense to the above stated) here it is:
我有一个更简单的解决方案,没有令人费解的方法片段(没有冒犯上述内容),这里是:
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
int main()
{
string line;//read the line
ifstream myfile ("MainMenu.txt"); // make sure to put this inside the project folder with all your .h and .cpp files
if (myfile.is_open())
{
while ( myfile.good() )
{
getline (myfile,line);
cout << line << endl;
}
myfile.close();
}
else cout << "Unable to open file";
return 0;
}
}
Happy coding
快乐编码

