[英]How can I read a specific line from a file, in C?
All right: So I have a file, and I must do things with it. 好吧:所以我有一个文件,我必须使用它来做。 Oversimplifying, the file has this format:
过度简化,文件具有以下格式:
n
first name
second name
...
nth name
random name
do x⁽¹⁾, y⁽¹⁾ and z⁽¹⁾
random name
do x⁽²⁾, y⁽²⁾, z⁽²⁾
...
random name
do x⁽ⁿ⁾, y⁽ⁿ⁾, z⁽ⁿ⁾
So, the actual details are not important. 因此,实际细节并不重要。 The problem is: I'll have to declare a variable n, I have an array name[MAX], and I'll fill this array with the names, from name[0] to name[n-1].
问题是:我必须声明一个变量n,我有一个数组名[MAX],然后用名称(从name [0]到name [n-1])填充此数组。
Alright, the problem is: How can I get this input, if I don't know previously how many names do I have? 好的,问题是:如果以前不知道我有多少个名字,如何获得此输入?
For example, I could do it just fine if that was an user input, from the keyboard: I would do it like this: 例如,如果这是用户通过键盘输入的内容,我可以做到这一点:我可以这样做:
int n; char name[MAX];
scanf( "%d", &n);
int i; for (i = 0; i < n; i++)
scanf( "%s", &N[i]);
And I could go on, do the whole code, but you get the point. 我可以继续进行全部代码,但是您明白了。 But, my input now comes from a file.
但是,我的输入现在来自文件。 I don't know how can I get the input, all I can do is to fscanf() the whole file, but since I don't know its size (the first number will determine it), I can't do it.
我不知道如何获取输入,我只能做fscanf()整个文件,但是由于我不知道它的大小(第一个数字会确定它的大小),所以我不能这样做。 As far as I know (please correct me if that's not true, I am very new to this), we can't use the command "for" and get the numbers gradually as if that was coming from the keyboard, right?
据我所知(如果不正确,请更正我,我对此很陌生),我们不能使用命令“ for”来逐渐获取数字,就好像是从键盘来的一样,对吗?
So, the only exit I see is to find a way to read a particular line from the file. 因此,我看到的唯一出口是找到一种从文件中读取特定行的方法。 If I can do this, the rest is easy.
如果我可以做到,剩下的就很容易了。 The thing is, how can I do that?
问题是,我该怎么办? I google'd it, I even found some questions in there, though it didn't make any sense at all.
我用谷歌搜索,甚至没有发现任何问题。 Apparently, reading a particular line from a file is really complicated.
显然,从文件中读取特定行确实很复杂。
This is from a beginner problem set, so I doubt it is something that complicated. 这是来自初学者的问题集,因此我怀疑它是否太复杂了。 I must be missing something very simple, though I just don't know what it is.
我一定会错过一些非常简单的东西,尽管我只是不知道它是什么。
So, the question is: How would you do it, for instance? 因此,问题是:例如,您将如何做?
How to scan the first number n from the file, and then, scan the others 'n' names, assigning each one to an element in an array (first name = name[0], last name = name[n - 1])? 如何扫描文件中的第一个数字n,然后扫描其他“ n”个名称,将每个名称分配给数组中的一个元素(名字= name [0],姓= name [n-1]) ?
I would suggest looking into End Of File. 我建议调查文件结尾。
while(!eof(fd))
{
...code...
}
Mind you my C knowledge is rusty, but this should get you started. 请注意,我的C语言知识很生锈,但这应该可以帮助您入门。
IIRC eof returns a value (-1) so that's why you need to compare it to something. IIRC eof返回值(-1),这就是为什么您需要将其与某些值进行比较的原因。 Here fd being file descriptor of the file you are reading.
这里fd是您正在读取的文件的文件描述符。 Then after parse of text or count of lines you have your 'n'.
然后,在解析文本或行数之后,您将得到“ n”。
EDIT: Since I'm obviously more tired then I thought(didn't notice your 'n' at the top). 编辑:既然我显然更累了,那么我想(没注意到您的'n'在顶部)。
Read first line malloc for 'n' size array for loop to iterate names. 读取第一行malloc中的'n'大小数组,以循环访问名称。
Since the given format seems to imply that the number of names n
is given as the first entry in the file, it would be possible to use the style of reading that the OP describes when reading from stdin. 由于给定的格式似乎暗示名称的数量
n
作为文件中的第一个条目给出,因此从stdin读取时可以使用OP描述的读取方式。 Use fscanf
to read the first integer from the file ( n
), then use malloc
to allocate the array(s) for the names, then use a for
loop up to n
to read the names. 使用
fscanf
从文件( n
)中读取第一个整数,然后使用malloc
为名称分配数组,然后使用直到n
的for
循环读取名称。
However, I am unsure of the meaning of the example data following that with the do x⁽¹⁾, y⁽¹⁾ and z⁽¹⁾
format. 但是,我不确定示例数据的含义是否遵循
do x⁽¹⁾, y⁽¹⁾ and z⁽¹⁾
格式。 Perhaps I am not understanding part of the question. 也许我不理解问题的一部分。 If it means there are potentially more than
n
names, then you can use realloc
to grow the size of the array. 如果这意味着可能有
n
名称,则可以使用realloc
增加数组的大小。 One way of growing the array that is not uncommon is to double the length each time. 增长阵列的一种常见方法是每次将长度加倍。
Here you go.. I leve compiling and debugging as an exercise for the student. 在这里,您可以开始学习。我将编译和调试作为学生的练习。
The idea is to slurp the whole file into a single array if you files are always small. 想法是如果文件总是很小,则将整个文件包含到单个数组中。 This is so much more efficient than scanf().
这比scanf()更有效。
char buf[100000], *bp, *N[1000]; // plenty big memset( buf, '\0', sizeof buf ); if ( fgets( buf, sizeof(buf), fd ) ) { int n = 0; char *bp; if ( buf[(sizeof buf)-2)] != '\0' ) { // file too long for buffer printf( stderr, "trouble: file too large: %d\n", (int)(sizeof buf)); exit(EXIT_FAILURE); } // now replace each \n with a \0, remembering where each line is. for ( bp = buf, bp = strchr( bp, '\n' ); bp++ ) N[n++] = bp; }
If you want to read any size files you need to read the file in chunks, calloc()ing each chunk before a read, and carefully handling of the line fragments left at the end of the current buffer to move them to the next buffer and then properly continuing you reads. 如果要读取任何大小的文件,则需要以块的形式读取文件,在读取之前对每个块进行calloc(),并仔细处理当前缓冲区末尾的行片段,以将它们移至下一个缓冲区,然后正确继续阅读。 Unless you have a limit on how many lines you can read the N may need to also be set up in chunks, but this time remalloc() might be your friend.
除非您对可以读取的行数有限制,否则可能还需要以块的形式设置N,但是这次remalloc()可能是您的朋友。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.