【问题标题】:How to Read and Add Numbers from txt file in C如何从 C 中的 txt 文件中读取和添加数字
【发布时间】:2020-08-07 02:27:14
【问题描述】:

我正在尝试制作一个程序,该程序从名为 numbers.txt 的文本文件中读取数字,该文件在每一行中包含不同的数字。

例如:

8321
12
423
0
...

我已经创建了这个程序,但它不能正常工作。我尝试了很多东西,不知道该怎么做。有人可以指导我正确的方向吗?谢谢!

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

#define MAX_LEN 1000

int main(int argc, char *argv[]) {
    char str[MAX_LEN];
    FILE *pFile = fopen(argv[1], "r");
    int num;
    int sum = 0;
    int count = 0;

    if (pFile == NULL) {
        printf("Error opening file.\n");
        return 1;
    }

    while (!feof(pFile) && !ferror(pFile)) {
        if (fscanf(pFile, "%d", &num) == 1) {
            count++;
            while (strcmp(fgets(str, MAX_LEN, pFile), "\0") == 0) {
                printf("%s", str);
                //sum = sum + (int)(fgets(str, MAX_LEN, pFile));
                printf("\n");
            }
        }
    }
    fclose(pFile);

    printf("count = %d \n", count);
    printf("sum = %d \n", sum);

    return 0;
}

【问题讨论】:

  • "但它不能正常工作。"缺乏信息。文件内容是什么,被看到了,期待什么?一个小例子会有很大帮助。
  • 作为一个风格挑剔的人,我反对pFile——就叫它file,不需要在变量名中编码指针。国际海事组织。
  • 刚刚编辑了问题并给出了.txt文件的示例。

标签: c file scanf fgets


【解决方案1】:

您的程序有多个问题:

  • 不测试是否通过了命令行参数。
  • while (!feof(pFile) &amp;&amp; !ferror(pFile)) 遍历文件总是错误的:feof() 仅在实际读取尝试后才提供有效信息。只需测试读取是否失败。
  • 如果fscanf(pFile, "%d", &amp;num) == 1) 添加数字而不是仅仅计算数字。
  • fgets() 返回NULL 时,strcmp(fgets(str, MAX_LEN, pFile), "\0") 将在文件末尾失败。

如果文件只包含数字,只需使用fscanf() 读取这些数字,并在您浏览文件时添加它们。

这是修改后的版本:

#include <stdio.h>

int main(int argc, char *argv[]) {
    FILE *pFile;
    int num
    int sum = 0;
    int count = 0;

    if (argc < 2) {
        printf("Missing filename\n");
        return 1;
    }
    if ((pFile = fopen(argv[1], "r")) == NULL) {
        printf("Error opening file %s\n", argv[1]);
        return 1;
    }
    while (fscanf(pFile, "%d", &num) == 1) {
        sum += num;
        count++;
    }
    fclose(pFile);

    printf("count = %d \n", count);
    printf("sum = %d \n", sum);

    return 0;
}

【讨论】:

    【解决方案2】:

    您可以使用strtok 分割每一行的数字,然后使用atoi 函数将字符串转换为int

    例如:

    while(fgets(str, MAX_LEN, pFile)) { 
       // if the numbers are separated by space character
       char *token = strtok(str, " ");
       while(token != NULL) {
           sum += atoi(token);
           strtok(NULL, " ");
       }
    }
    

    如果每行只有一个数字,则不需要使用strtok

    while(fgets(str, MAX_LEN, pFile)) { 
        sum += atoi(str);
        // OR
        sscanf(str,"%d\n", &new_number)
        sum += new_number;
    
    }
    

    【讨论】:

    • 从问题中我不清楚每行会有多个数字。如果有,那么strtok 是一个不错的建议,但是您在内部循环中缺少对token 的分配。
    • 每行只有一个数字。示例:第 1 行:812 第 2 行:4 第 3 行:999 ...
    • @Arkku 我不明白你在说什么失踪?
    • @Hitokiri 内部循环条件是token != NULL,但您没有在该循环内分配token,只是在它之前。无论如何,这无关紧要,因为 OP 已经确认每行只有一个数字。
    【解决方案3】:

    strcmp(fgets(str, MAX_LEN, pFile),"\0") 在很多方面都是错误的。一方面,strcmp 的参数必须是一个字符串(空指针不是),但fgets 在错误或文件结束时返回NULL。您需要检查它是否没有返回NULL,然后您可以比较str 中的字符串。但是,不需要strcmp"\0"(或者,在这种情况下等效地,"")来检测文件的结尾,因为那是fgets 返回NULL 的时候。

    另一个问题是您正在阅读 fscanffgets - 选择一个并坚持下去。我推荐fgets,因为它通常更容易正确处理(例如,在无效输入上,从fscanf 恢复要困难得多,并确保您不会陷入无限循环,同时也不会丢失任何输入)。当然,您需要在fgets 之后解析来自str 的整数,但是有很多标准函数可以解决这个问题(例如,strtolatoisscanf)。

    不要使用!feof(file) 作为循环条件(例如,参见Why is “while ( !feof (file) )” always wrong?)。如果您正在使用fgets 阅读,请在返回NULL 时结束循环。

    【讨论】:

    • 澄清一下,同时使用fscanffgets 阅读并没有错,但它使程序更难理解,尤其是在输入更复杂的情况下。 fgets 通常更容易正确,但不可否认,在这种情况下,您可以只使用 while (fscanf(pFile, " %d", &amp;num) == 1) { sum += num; ++count; }
    • 所以当我们执行fscanf并返回1时,这意味着该行中有一个数字,并将该数字存储到变量num中?
    • @MarkSantos 是的,*scanf 函数返回分配的项目数,在这种情况下,您只尝试读取一个 (num),因此返回值为 1 表示它成功。无论如何,您应该始终阅读您使用的函数的文档,最好将您的编辑器或 IDE 设置为自动为您显示它,并始终检查返回值是什么。
    猜你喜欢
    • 1970-01-01
    • 2011-12-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-10-09
    • 2017-08-23
    相关资源
    最近更新 更多