#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;
}
我正在尝试逐行读取文件。我正在获得无限循环。它出错了吗?
答案 0 :(得分:3)
如果文件的内容是
"foo\nbar\n"
在第一次循环中将“foo”读入s
之后,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;
}
答案 1 :(得分:1)
使用
while (!feof(fp))
feof
在EOF处返回非零值,不一定是EOF
。然后,您对fscanf
的调用会读取换行符。第一次通话后,fp
指向您文件中的第一个换行符,因此您必须“吞下”该行,否则fscanf
不会读取任何内容:
fscanf(fp,"%[^\n]\n",s);
请注意,这也会使空格和制表符变浅。您可以使用getc(fp)
代替,然后添加另一项检查以查看是否失败,否则您将打印最后一行两次。
(最后,您可能希望使用printf("%s\n", s);
)
答案 2 :(得分:0)
您可以使用以下代码执行此操作。
你的问题是你没有检查fscanf
的回复,而你实际上并没有读取换行符(所以下次你读的时候,你不会去下一行)。< / p>
#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', CTRL D 运行,并且字符串太大了:
pax> ./qq
Enter string> hello
OK [hello]
pax> ./qq
Enter string>
No input
pax> ./qq
Enter string> dfgdfgjdjgdfhggh
Input too long
pax> _
答案 3 :(得分:-1)
它应该工作!feof(fp)如果仍然不起作用,请尝试fgets()