How to I get the counter to work in this C program?

风流意气都作罢 提交于 2020-01-25 08:14:11

问题


#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);
}

I have a project for a Unix and C programming class due on Monday and I cannot figure out how to work the counter. Essentially, we're learning about using Arrays in C, pointers in C, and using File Input/Output. On our homework, we have to take input from a text file, and we have to print out all the values in the text file as an array. That's the easy part. The hard part is counting each specific variable in the array. I feel it would be easier to do this in Java as that's what we've been doing before taking this 200 level course. However, we cannot do this in java, thus I am not sure how to proceed.

Could you help a brother out?


回答1:


You are confusing things by using too many variables. All you need to do is read each integer into the next array element while the number of elements is within your array bounds. You need the array and a single counter.

Before looking at that problem, a quick lesson: Don't use Magic-Numbers and don't Hardcode-Filenames. Instead, if you need a constant, #define one, e.g.

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

Then use the constant within your code to size your array and set any other limits needed, e.g.

    int num[NELEM];     /* array */

and

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

The main() function takes arguments, int main (int argc, char **argv), pass the filename to read as an argument to main() or take the filename as input, e.g.

    /* 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;
    }

That way you don't have to recompile every time you want to change the input file.

Now to the read. Whenever you are reading input, you always condition the next read on the successful completion of reading the current value (or line preferably). In that case as shown above, you simply have 2-conditions to meet, (1) you do not try and read more values than you can store in your array, and (2) when using any Xscanf() function, that the return is equal to the number of conversions anticipated. (you can also simply loop continually, checking the return within the loop and breaking the loop when one of your exit conditions is met)

In your case:

    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 */

The code above reads integer values into you array until (1) the array is full, or (2) the first failed conversion occurs (which can be on either a matching-failure or EOF)

You are done at that point. You have the values stored in num and you have the count of values stored in n. To output the values, simply loop from 0 to n-1, which covers your filled elements. Example:

    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 */

(note: the loop is the important part, you can format how it is output as you like. It is just shown in 10-columns with each value being 6-digits wide (including +/-))

The complete example could be:

#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 */
}

Example Use/Output

Reading a file with 61 integer values:

$ ./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

Look things over and let me know if you have any further questions.



来源:https://stackoverflow.com/questions/59232015/how-to-i-get-the-counter-to-work-in-this-c-program

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!