问题
#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