首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >C while循环feof

C while循环feof
EN

Stack Overflow用户
提问于 2013-03-08 06:13:23
回答 3查看 10.9K关注 0票数 0

这是一个制作电影精灵的更大程序的一部分,由于某些原因,程序在到达while循环时崩溃,我不知道我的问题是什么。

代码语言:javascript
复制
#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;
}
EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2013-03-08 06:21:10

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

你可以使用下面的代码:

代码语言:javascript
复制
 while(fscanf(fp,"%[^\n]s",line)) {
    strcpy(arrayoffilms[i],line);
    fscanf(fp,"%[\n]s",junk);
    i++;
 }

此外,与文件指针相关的错误检查是绝对必要的,也是一个很好的习惯。您肯定会想要使用它:

代码语言:javascript
复制
fp=fopen("filmtitles.txt","r");
if(fp == NULL)  /* error handling */
    printf("Could not open file: filename\n"); 
else{
/* do stuff */
}
票数 0
EN

Stack Overflow用户

发布于 2013-03-08 08:37:22

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

不要混淆%[%s格式说明符;%[没有为%s提供扫描集;%[^\n]s告诉scanf读取“一个或多个非‘\n’字符,后面跟一个's‘字符”。这有意义吗?仔细想一想。此格式说明符的用途是什么?如果用户只按enter键,而scanf没有得到“一个或多个非‘\n’字符”,会发生什么?在查找非'\n‘字符之前,重要的是去掉任何’\n‘字符。格式字符串中的任何空白字节都将导致scanf使用尽可能多的空白,直到第一个非空白字符为止。我假设您需要%[^\n],或者甚至是%99[^\n],它可以防止行溢出。

也许你还想计算一下scanf处理的字节数,这样你就可以malloc出正确的长度并拷贝到arrayoffilm中,因为某种原因我无法想象。您可以使用%n格式说明符,它将告诉您scanf处理了多少字节。

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

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

代码语言:javascript
复制
int length;
while (fscanf(fp, " %99[^\n]%n%*[^\n]", line, &length) == 1) {
    arrayoffilms[i] = malloc(length + 1);
    strcpy(arrayoffilms[i], line);
    i++;
}
票数 1
EN

Stack Overflow用户

发布于 2018-06-24 09:34:06

类似的事情也发生在fgets()中,所以有些人建议永远不要使用它。这样看,如果你说

代码语言:javascript
复制
while (!feof(ipf)) {

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

代码语言:javascript
复制
while (!feof(ipf)) {
  if (!feof(ipf)) {
    ch = fgetc(ipf);

它也适用于fgets(),我已经这样用了很多年了。如果这是Pascal (或者可能是Perl),并且你读了“直到”,这是一个测试前的问题,而不是测试后的问题。所以测试两次。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/15282790

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档