【问题标题】:How to I get the counter to work in this C program?如何让计数器在这个 C 程序中工作?
【发布时间】:2019-12-08 02:45:40
【问题描述】:
#include <stdio.h>
#include <stdlib.h>

int main()
{
    FILE *myFile;
    int x, b, n = -1, i, count = 1;
    int num[101];

    myFile = fopen("a.txt", "r");
    b = fscanf(myFile, "%d", &x);
    while (b != -1){
        n++;
        num[n] = x;
        b = fscanf(myFile, "%d ", &x);
    }
        for (int i = 0; i <= n; i++){
            printf("%d ", num[i]);
        }
        printf("\n");
        for(int i = 1; i <= 100; i++){
        if(num[i] == i) {
            printf("%i has occurred: %d times\n", i, count);
            count++;
        }
    }
        fclose(myFile);
}

我有一个 Unix 和 C 编程课程的项目将于周一到期,但我不知道如何使用计数器。本质上,我们正在学习如何在 C 中使用数组、在 C 中使用指针以及使用文件输入/输出。在我们的作业中,我们必须从一个文本文件中获取输入,并且我们必须将文本文件中的所有值打印为一个数组。那是容易的部分。困难的部分是计算数组中的每个特定变量。我觉得在 Java 中这样做会更容易,因为这是我们在参加这门 200 级课程之前一直在做的事情。但是,我们不能在 java 中执行此操作,因此我不确定如何进行。

你能帮助一个兄弟吗?

【问题讨论】:

  • 你的意思是while (b != EOF)?您的条件必须是while (b == 1),否则您将不会遇到匹配失败

标签: c file-io counter codeblocks


【解决方案1】:

使用太多变量会使事情变得混乱。您需要做的就是将每个整数读入下一个数组元素,同时元素的数量在您的数组范围内。你需要数组和一个计数器。

在查看该问题之前,快速学习一下:不要使用 Magic-Numbers 也不要Hardcode-Filenames。相反,如果您需要一个常量,#define 一个,例如

#define NELEM 101   /* if you need a constant, #define one (or more) */

然后使用代码中的常量来调整数组大小并设置所需的任何其他限制,例如

    int num[NELEM];     /* array */

    /* read integers while n < NELEM && good read */
    while (n < NELEM && fscanf(myFile, "%d", &num[n]) == 1)
        n++;    /* advance counter */

main() 函数接受参数 int main (int argc, char **argv),将要读取的文件名作为参数传递给 main() 或将文件名作为输入,例如

    /* read filename from 1st argument (stdin by default) */
    FILE *myFile = argc > 1 ? fopen (argv[1], "r") : stdin;

    if (!myFile) {  /* validate myfile is open for reading */
        perror ("fopen-myfile");
        return 1;
    }

这样您就不必在每次要更改输入文件时都重新编译。

现在开始阅读。每当您读取输入时,您总是以成功完成读取当前值(或最好是行)为条件进行下一次读取。在这种情况下,如上所示,您只需满足 2 个条件,(1)您不会尝试读取比您可以存储在数组中的值更多的值,以及(2)当使用任何 Xscanf() 函数时,返回等于预期的转换次数。 (您也可以简单地不断循环,检查循环内的返回并在满足您的退出条件之一时中断循环)

在你的情况下:

    int n = 0;          /* counter */
    int num[NELEM];     /* array */
    /* read filename from 1st argument (stdin by default) */
    FILE *myFile = argc > 1 ? fopen (argv[1], "r") : stdin;
    ...
    /* read integers while n < NELEM && good read */
    while (n < NELEM && fscanf(myFile, "%d", &num[n]) == 1)
        n++;    /* advance counter */

上面的代码将整数值读取到您的数组中,直到 (1) 数组已满,或 (2) 发生第一次失败的转换(可以在 matching-failure 或 @987654331 @)

到那时你就完成了。您将值存储在num 中,并且将值的计数存储在n 中。要输出这些值,只需从0 循环到n-1,它会覆盖您填充的元素。示例:

    for (int i = 0; i < n; i++) {   /* output in 10-col format */
        if (i && i % 10 == 0)
            putchar ('\n');
        printf (" %6d", num[i]);
    }
    putchar ('\n');     /* tidy up with \n */

(注意:循环是重要的部分,你可以根据需要格式化它的输出方式。它只显示在 10 列中,每个值是 6 位宽(包括 @ 987654337@))

完整的例子可以是:

#include <stdio.h>

#define NELEM 101   /* if you need a constant, #define one (or more) */

int main(int argc, char **argv) {

    int n = 0;          /* counter */
    int num[NELEM];     /* array */
    /* read filename from 1st argument (stdin by default) */
    FILE *myFile = argc > 1 ? fopen (argv[1], "r") : stdin;

    if (!myFile) {  /* validate myfile is open for reading */
        perror ("fopen-myfile");
        return 1;
    }

    /* read integers while n < NELEM && good read */
    while (n < NELEM && fscanf(myFile, "%d", &num[n]) == 1)
        n++;    /* advance counter */

    if (myFile != stdin)    /* close file if not stdin */
        fclose (myFile);

    for (int i = 0; i < n; i++) {   /* output in 10-col format */
        if (i && i % 10 == 0)
            putchar ('\n');
        printf (" %6d", num[i]);
    }
    putchar ('\n');     /* tidy up with \n */
}

使用/输出示例

读取包含 61 个整数值的文件:

$ ./bin/fscanfintarray dat/n_61_ints.txt
     60   1984  -7093   1236  -3680  -3184  -3936   6671   8906  -5207
  -9698   3681    952   -137    664   8798    -30  -6392   7155   7797
  -7665   4829  -4115   -435   7194   -279  -5619  -5154  -3755  -3818
  -7186  -8420  -4602  -4279  -9952   1718   2537  -3888  -1611   8676
    905   5924   2357  -8143   3019    253  -2113  -7011  -8907  -4958
  -1982  -6572  -2897   3904  -9774  -5703  -6375  -5393   6375   7102
    789

查看一下,如果您有任何其他问题,请告诉我。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-04-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-11-13
    相关资源
    最近更新 更多