好吧:所以我有一个文件,我必须用它来做。过度简化,文件具有以下格式:
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])?
答案 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()可能是您的朋友。