如何从C中读取文件中的特定行?

时间:2013-02-27 01:31:35

标签: c

好吧:所以我有一个文件,我必须用它来做。过度简化,文件具有以下格式:

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⁽ⁿ⁾

因此,实际细节并不重要。 问题是:我必须声明一个变量n,我有一个数组名[MAX],我将用名称填充这个数组,从名称[0]到名称[n-1]。

好吧,问题是:如果我之前不知道我有多少名字,我怎么能得到这个输入?

例如,如果这是用户输入,我可以从键盘上做到这一点:我会这样做:

int n; char name[MAX];
scanf( "%d", &n);
int i; for (i = 0; i < n; i++)
    scanf( "%s", &N[i]);

我可以继续,完成整个代码,但你明白了。但是,我的输入现在来自一个文件。我不知道如何获得输入,我所能做的就是fscanf()整个文件,但由于我不知道它的大小(第一个数字将决定它),我不能这样做。据我所知(请纠正我,如果这不是真的,我对此很新),我们不能使用命令“for”并逐渐得到数字,好像这是来自键盘,对吗?

所以,我看到的唯一一个出口就是找到一种从文件中读取特定行的方法。如果我能做到这一点,其余的都很容易。问题是,我该怎么做? 我谷歌了,我甚至在那里发现了一些问题,尽管它根本没有任何意义。显然,从文件中读取特定行非常复杂。

这是一个初学者问题集,所以我怀疑它是一个复杂的东西。我必须遗漏一些非常简单的东西,尽管我只是不知道它是什么。

所以,问题是:例如,你会怎么做?

如何从文件中扫描第一个数字n,然后扫描其他的'n'名称,将每个名称分配给数组中的元素(名字=名字[0],姓氏=名字[n - 1])?

3 个答案:

答案 0 :(得分:1)

我建议查看文件结尾。

while(!eof(fd))
{
...code...
}

请注意我的C知识是生锈的,但这应该让你开始。

IIRC eof返回一个值(-1),这就是为什么你需要将它与某些东西进行比较的原因。这里fd是你正在阅读的文件的文件描述符。 然后在解析文本或行数后,你就得到了'n'。

编辑:因为我显然更累,所以我想(没注意到你的'n'在顶部)。
阅读第一行 用于'n'大小数组的malloc for循环来重复名称。

答案 1 :(得分:0)

由于给定的格式似乎暗示名称n的数量是文件中的第一个条目,因此可以使用OP从stdin读取时描述的阅读方式。使用fscanf从文件中读取第一个整数(n),然后使用malloc为名称分配数组,然后使用for循环到n读取名字。

但是,我不确定具有do x⁽¹⁾, y⁽¹⁾ and z⁽¹⁾格式的示例数据的含义。也许我不理解问题的一部分。如果这意味着可能有超过n个名称,那么您可以使用realloc来增加数组的大小。增长数组的一种方法是每次加倍长度。

答案 2 :(得分:0)

在这里你去..我将编译和调试作为学生的练习。

如果文件总是很小的话,我们的想法是将整个文件粘贴到一个数组中。 这比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;
}

如果你想读取任何大小的文件,你需要以块的形式读取文件,在读取之前调用每个块的calloc(),并仔细处理当前缓冲区末尾留下的行碎片,将它们移动到下一个缓冲区然后正确地继续读取。 除非您对可以读取的行数有限制,否则N可能还需要以块的形式设置,但这次remalloc()可能是您的朋友。