Fscanf还是Fgets?逐行读取文件

Fscanf还是Fgets?逐行读取文件,c,fgets,scanf,C,Fgets,Scanf,我必须用C编写一个程序来读取包含几行文本的文件,每行包含两个变量:一个数字(%f)和一个字符串: EX: file.txt ============ 24.0 Torino 26.0 Milano 27.2 Milano 26.0 Torino 28.0 Torino 29.4 Milano 这是我的代码: #include <stdio.h> #include <stdlib.h> #include <string.h> int main (int ar

我必须用C编写一个程序来读取包含几行文本的文件,每行包含两个变量:一个数字(%f)和一个字符串:

EX: file.txt
============
24.0 Torino
26.0 Milano
27.2 Milano
26.0 Torino
28.0 Torino
29.4 Milano
这是我的代码:

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

int main (int argc, char *argv[])
{
    int r, line = 0, found = 0;
    float temp, t_tot = 0;
    char loc[32];


    FILE *fp;

    fp = fopen(argv[1], "r");

    if (fp == NULL)
    {
        printf ("Error opening the file\n\n'");
        exit(EXIT_FAILURE);
    }

    if (argc == 3)
    {
        r = fscanf(fp, "%f %s\n", &temp, loc);

        while (r != EOF)
        {
            line++;

            if (r == 2)
            {
                if(strcmp(argv[2], loc) == 0)
                {
                    t_tot += temp;
                    found++;
                }
            }
            else
                printf ("Error, line %d in wrong format!\n\n", line);
        }

        printf ("The average temperature in %s is: %.1f\n\n", argv[2], (t_tot/found);
    }

}
#包括
#包括
#包括
int main(int argc,char*argv[])
{
int r,line=0,found=0;
浮子温度,t_tot=0;
char-loc[32];
文件*fp;
fp=fopen(argv[1],“r”);
如果(fp==NULL)
{
printf(“打开文件时出错\n\n”);
退出(退出失败);
}
如果(argc==3)
{
r=fscanf(fp、%f%s\n、&temp、loc);
while(r!=EOF)
{
line++;
如果(r==2)
{
如果(strcmp(argv[2],loc)==0)
{
t_tot+=温度;
发现++;
}
}
其他的
printf(“错误,第%d行格式错误!\n\n”,第行);
}
printf(“以%s为单位的平均温度为:%.1f\n\n”,argv[2],(t_tot/found);
}
}
程序需要读取所有行并找到我在
argv[2]
上写的城市。然后它会告诉我该城市的平均温度,并通知我文件中的行是否格式错误

该程序对我来说编译正确,但没有在屏幕上输出任何内容…我如何解决这个问题?在这种情况下使用
fscanf
是正确的还是更好的
fgets


我是一名学生,所以,请给我一个“学术”方法来解决它:)

你的代码不会像它应该的那样在循环中调用
fscanf
:读取完成一次,然后如果文件为空,程序要么立即存在,要么无限循环

您应该在
while
循环中移动
fscanf
的调用。一种典型的编码方式是将赋值放在循环头中,如下所示:

while ((r = fscanf(fp, "%f %s\n", &temp, loc)) != EOF) {
    ...
}

像这样修改代码。。。只需在while语句中添加另一个fscanf

if (argc == 3)
{
 r = fscanf(fp, "%f %s\n", &temp, loc);
  while(r != EOF )

    {
        r = fscanf(fp, "%f %s\n", &temp, loc);  
        line++;

        if (r == 2)
        {
            if(strcmp(argv[2], loc) == 0)
            {
                t_tot += temp;
                found++;
            }
        }
        else
            printf ("Error, line %d in wrong format!\n\n", line);
    }

    printf ("The average temperature in %s is: %.1f\n\n", argv[2], t_tot);
}

}

您必须将fscanf行放入while循环中

    while (1)
    {
        r = fscanf(fp, "%f %s\n", &temp, loc);
        if( r == EOF ) 
           break;
        .........................
    }
最后关闭文件

如果您使用的是FGET,则更改如下

  char s[256];
  while( fgets( s, 256, fp) != NULL )
  {
     sscanf( s, "%f %s", &temp, loc);
     .............
  }

有几件事。

首先,必须使用fclose()。
其次,您的代码需要对文件中的每一行执行fscan()。不仅在while()循环之前,而且在每个while循环中,您必须为下一次迭代执行fscan() 第三,你不是在计算平均温度,而是在计算所有温度的总和。通过将上次printf()中的“t_tot”更改为“(t_tot/found)”来修复此问题

最后,我不知道你为什么没有得到任何输出。您的输入类似于“myprogram file.txt Milano”,对吗?对我有用。无论如何,这是您的(编辑过的)代码:

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

int main (int argc, char *argv[])
{
    int r, line = 0, found = 0;
    float temp, t_tot = 0;
    char loc[32];

    FILE *fp;
    fp = fopen(argv[1], "r");

    if (fp == NULL)
    {
        printf ("Error opening the file\n\n'");
        exit(EXIT_FAILURE);
    } else {

        if (argc == 3)
        {
            r = fscanf(fp, "%f %s\n", &temp, loc);
            while (r != EOF)
            {
                line++;
                if (r == 2)
                {
                    if(strcmp(argv[2], loc) == 0)
                    {
                        t_tot += temp;
                        found++;
                    }
                }
                else
                    printf ("Error, line %d in wrong format!\n\n", line);
                r = fscanf(fp, "%f %s\n", &temp, loc);
            }
            printf ("The average temperature in %s is: %.1f\n\n", argv[2], (t_tot / found));
        }

    fclose(fp);

    }
}
#包括
#包括
#包括
int main(int argc,char*argv[])
{
int r,line=0,found=0;
浮子温度,t_tot=0;
char-loc[32];
文件*fp;
fp=fopen(argv[1],“r”);
如果(fp==NULL)
{
printf(“打开文件时出错\n\n”);
退出(退出失败);
}否则{
如果(argc==3)
{
r=fscanf(fp、%f%s\n、&temp、loc);
while(r!=EOF)
{
line++;
如果(r==2)
{
如果(strcmp(argv[2],loc)==0)
{
t_tot+=温度;
发现++;
}
}
其他的
printf(“错误,第%d行格式错误!\n\n”,第行);
r=fscanf(fp、%f%s\n、&temp、loc);
}
printf(“以%s为单位的平均温度为:%.1f\n\n”,argv[2],(t_tot/found));
}
fclose(fp);
}
}

谢谢您的回答。我才意识到我的错误!如果我想用fgets而不是fscanf制作另一个解决方案,我该怎么做呢?@l_core您需要做一些更改:首先,您需要为
fgets
设置一个缓冲区;然后用循环中的
NULL
检查取代对
EOF
的检查;最后,您需要手动解析缓冲区,找到第一个空格,将初始部分输入到
atof
,然后在
strdup
中复制其余部分。