繁体   English   中英

C while循环特征

[英]C while loop feof

这是制作Filmgenie的更大程序的一部分,由于某种原因,程序在到达while循环时崩溃,因此我不明白我的问题是什么。

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>
#include <ctype.h>

FILE *fp, *fopen();
char *arrayoffilms[45];
int main()
{
    char line[100],junk[100];
    fp=fopen("filmtitles.txt","r");
    int i=0;
    while(!feof(fp)) {
        fscanf(fp,"%[^\n]s",line);
        strcpy(arrayoffilms[i],line);
        fscanf(fp,"%[\n]s",junk);
        i++;
    }
    fclose(fp);
    printf("%s\n\n\n",arrayoffilms[i]);
    return 0;
}

在进行实际的读取尝试并达到EOF之前, feof永远不会返回true。 读取尝试通常具有指示失败的返回值。 为什么不使用那些呢?

不要混淆%[%s格式说明符; %[不提供%s的扫描集; %[^\\n]s告诉scanf读取“一个或多个非'\\ n'字符,后跟一个's'字符”。 那有意义吗? 仔细考虑一下。 此格式说明符的目的是什么? 如果用户仅按Enter键,而scanf没有得到“一个或多个非'\\ n'字符”,会发生什么情况? 在寻找非'\\ n'字符之前,重要的是要摆脱所有'\\ n'字符。 格式字符串中的任何空白字节都将导致scanf消耗尽可能多的空白,直到第一个非空白字符为止。 我假设您需要%[^\\n]或什至%99[^\\n] ,这可以防止行溢出。

也许你想也想通过计数处理scanf函数的字节数,这样你就可以malloc正确长度和复制到arrayoffilms,由于某种原因,我无法想象。 您可以使用%n格式说明符,该说明符将告诉您scanf处理了多少字节。

我注意到您想读取并丢弃一行的其余部分。 在我的示例中,只有在遇到换行符之前读取了99个字符,行的其余部分才会被丢弃。 我将使用赋值抑制'*': %*[^\\n]

组合这些格式说明符,将导致格式字符串为" %99[^\\n]%n%*[^\\n]" ,两个参数( %[char *%nint * )以及预期的返回值1(因为分配了1个输入)。 当返回值不为1时,循环将结束,这很可能是由诸如“超出eof的读取”之类的错误引起的。

int length;
while (fscanf(fp, " %99[^\n]%n%*[^\n]", line, &length) == 1) {
    arrayoffilms[i] = malloc(length + 1);
    strcpy(arrayoffilms[i], line);
    i++;
}

问题可能出在feof 您希望while循环在到达文件末尾时终止,换句话说,当您无法使用fscanf获得任何内容时终止。

您可以使用以下代码:

 while(fscanf(fp,"%[^\n]s",line)) {
    strcpy(arrayoffilms[i],line);
    fscanf(fp,"%[\n]s",junk);
    i++;
 }

同样,与文件指针相关的错误检查是绝对必要的,并且是个好习惯。 您肯定要使用它:

fp=fopen("filmtitles.txt","r");
if(fp == NULL)  /* error handling */
    printf("Could not open file: filename\n"); 
else{
/* do stuff */
}

fgets()也会发生类似的事情,因此有人说不要使用它。 如果你说的话,这样看

while (!feof(ipf)) {

当feof()为true时,您已经到达文件末尾。 您刚刚读取的字节是垃圾,可能为NULL。 不要使用它。 这有效:

while (!feof(ipf)) {
  if (!feof(ipf)) {
    ch = fgetc(ipf);

它也适用于fgets(),多年来我一直以这种方式使用它。 如果这是Pascal(也许是Perl),并且您读到“直到”可行,那是测试前与测试后的问题。 因此测试两次。

暂无
暂无

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

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