2
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
int main()
{
        FILE *fp;
        fp=fopen("mydata.txt","r");
        if(fp==NULL)
        {
                perror("Error while opening");
                exit(0);
        }
        char *s=(char*)malloc(100);
        while(feof(fp)!=EOF)
        {
                fscanf(fp,"%[^\n]",s);
                printf("%s",s);
        }
        return 0;
}

我正在尝试逐行读取文件。我正在无限循环。哪里出错了?

4

4 回答 4

3

如果文件的内容是

"foo\nbar\n"

s第一次通过循环将“foo”读入后,fscanf接下来会做什么?

始终检查 scanf 的返回值

if (fscanf(fp,"%[^\n]",s) == 1) {
    /* fscanf "worked" */
} else {
    /* fscanf "didn't work" */
}

scanf编辑:返回值的示例用法

int suminputs() {
    unsigned a, b, c, d
    int sum = 0;
    switch (scanf("%u%u%u%u", &a, &b, &c, &d)) {
        case 4: sum += d; /* fall through */ /* 4 inputs converted */
        case 3: sum += c; /* fall through */ /* 3 inputs converted */
        case 2: sum += b; /* fall through */ /* 2 inputs converted */
        case 1: sum += a; /* fall through */ /* 1 inputs converted */
        case 0: break;                       /* no inputs converted */
        default: sum = -1;                   /* input error */
    }
    return sum;
}
于 2010-11-09T13:34:40.647 回答
1

采用

while (!feof(fp))

feof在 EOF 处返回非零值,不一定是EOF. 然后,您的呼叫fscanf读取到换行符。在第一次调用之后,fp指向文件中的第一个换行符,所以你必须“吞下”它,否则fscanf不会读取任何内容:

fscanf(fp,"%[^\n]\n",s);

请注意,这也会使空格和制表符变浅。您可以getc(fp)改为使用,但随后添加另一个检查以查看是否失败,否则您将打印最后一行两次。

(最后,您可能想用 打印换行符printf("%s\n", s);

于 2010-11-09T13:29:10.947 回答
0

您可以使用以下代码来执行此操作。

您的问题是您没有检查 return fromfscanf并且您实际上没有阅读换行符(因此下次阅读时,您不会转到下一行)。

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
int main (void) {
    FILE *fp;
    int x;
    fp=fopen("mydata.txt","r");
    if(fp==NULL) {
        perror("Error while opening");
        exit(0);
    }
    char *s=(char*)malloc(100);
    while(!feof(fp)) {
        x = fscanf(fp,"%[^\n]",s);
        fgetc(fp);
        if (x == 1)
            printf("%s\n",s);
    }
    return 0;
}

但是,如果您所追求的只是输入和处理行的能力,那么这fgets是一个更好的解决方案,fscanf因为没有缓冲区溢出的可能性:

#include <stdio.h>
#include <string.h>

#define OK       0
#define NO_INPUT 1
#define TOO_LONG 2
static int getLine (char *prmpt, char *buff, size_t sz) {
    int ch, extra;

    // Get line with buffer overrun protection.
    if (prmpt != NULL) {
        printf ("%s", prmpt);
        fflush (stdout);
    }
    if (fgets (buff, sz, stdin) == NULL)
        return NO_INPUT;

    // If it was too long, there'll be no newline. In that case, we flush
    // to end of line so that excess doesn't affect the next call.
    if (buff[strlen(buff)-1] != '\n') {
        extra = 0;
        while (((ch = getchar()) != '\n') && (ch != EOF))
            extra = 1;
        return (extra == 1) ? TOO_LONG : OK;
    }

    // Otherwise remove newline and give string back to caller.
    buff[strlen(buff)-1] = '\0';
    return OK;
}

 

// Test program for getLine().

int main (void) {
    int rc;
    char buff[10];

    rc = getLine ("Enter string> ", buff, sizeof(buff));
    if (rc == NO_INPUT) {
        printf ("No input\n");
        return 1;
    }

    if (rc == TOO_LONG) {
        printf ("Input too long\n");
        return 1;
    }

    printf ("OK [%s]\n", buff);

    return 0;
}

示例使用 'hello',CTRLD和一个太大的字符串运行:

pax> ./qq
Enter string> hello
OK [hello]

pax> ./qq
Enter string>
No input

pax> ./qq
Enter string> dfgdfgjdjgdfhggh
Input too long

pax> _
于 2010-11-09T13:43:55.550 回答
-1

它应该可以通过 !feof(fp) 起作用,如果仍然不起作用,请尝试 fgets()

于 2010-11-09T13:38:58.587 回答