You have a large number of small errors. (addressed in the comments in the code). Your primary problem is understanding where and how to declare data
and how to go about getting values from your file into data
as part of your menu system. While you can declare your array data
in your userinterface
function, in general you will want to declare your variables in main()
(or the calling function) and then pass them as parameters (properly qualified) to any function that will need them.
As part of the misconception of how to fill data
you have a void dataTxtFunctions()
that is more or less randomly floating around in your code, not attached anywhere. The name also suggests a large:
"I don't know what I'm going to do with this thing, so I'll call it some generic dataTxtFunctions
and hope it works itself out somehow?"
(note: that approach to coding never works out...)
What you need is a readdata
function to prompt for a filename, open and validate the file, and then read integers from the file, providing a meaningful return of the number of integers read (or 0
indicating failure). That way you could create a " r) Read data from file\n"
menu entry to handle those operations.
(do not hardcode values or names (e.g. data.txt
) in your code, magic numbers and magic strings limit the usefulness of your code and make it hard to maintain)
The remainder of the suggestions are provide in comments below. The following example can be used with your data.txt
(I used the first 22 values you show in your question as the input file below). If I understood what you were trying to accomplish, you could do something like the following:
#include <stdio.h>
#include <limits.h>
#define MAXN 256 /* if you need a constant, define one */
/* don't skimp on array sizes */
/* empty any characters that remain in stdin -- following scanf */
void empty_stdin()
{
for (int c = getchar(); c != '\n' && c != EOF; c = getchar()) {}
}
/* print values in data (both data and number of values are const) */
void printdata (const int *data, const size_t n)
{
for (size_t i = 0; i < n; i++)
printf ("data[%3zu]: %d\n", i, data[i]);
}
/* find/return max value in data (data and n are const) */
int findmaxdatavalue (const int *data, const size_t n)
{
int max = INT_MIN; /* use INT_MIN from limits.h */
for (size_t i = 0; i < n; i++)
if (data[i] > max)
max = data[i];
return max; /* provide a return to gauge success/failure */
}
/* prompt for filename, read up to max values from file.
* returns number of values read (0 indicates failure).
*/
size_t readdata (int *data, size_t max)
{
int tmp; /* temporary value to validate read */
char filenm[PATH_MAX] = ""; /* buffer to hold filename */
FILE *fp = NULL; /* FILE stream pointer */
size_t n = 0; /* number of values read */
for (;;) { /* loop until valid filename provided or EOF */
int rtn;
printf ("\nenter filename: ");
/* if EOF, user canceled with ctrl+d (ctrl+z on windoze) */
if ((rtn = scanf ("%[^\n]", filenm)) == EOF)
return 0;
empty_stdin(); /* remove '\n' (or can chars beyond PATH_MAX) */
if (rtn == 1) /* if return 1, good string in filenm */
break;
/* otherwise, handle error */
fprintf (stderr, "error: invalid input - filename.\n");
}
if (!(fp = fopen (filenm, "r"))) { /* validate open */
fprintf (stderr, "error: file open failed '%s'\n", filenm);
return 0;
}
/* read up to 'max' values from file */
while (n < max && fscanf (fp, "%d", &tmp) == 1)
data[n++] = tmp;
fclose (fp);
return n; /* return number of integers read */
}
void userinterface (int *data, size_t *n, size_t max)
{
while (1) { /* loop continually */
char choice = 0;
int rtn; /* you only need 1 printf */
printf ("\n r) Read data from file\n"
" a) Print out the values\n"
" b) Find the maximum Value\n"
" c) Calculate the RMS (root mean square)\n"
" d) Count the number of negative values\n"
" e) Exit Back to Main Menu\n\n"
"Enter selection: ");
if ((rtn = scanf ("%c", &choice)) == EOF)
return;
empty_stdin(); /* empty '\n' (and any other chars) */
if (rtn != 1 || /* validate return and proper choice */
(choice != 'r' && (choice < 'a' || 'e' < choice))) {
fprintf (stderr, "error: invalid input - choice.\n");
continue; /* on bad choice, redisplay menu */
}
if (!*n && choice < 'e') { /* if no data, only 'e' or 'r' valid */
fprintf (stderr, "error: data is empty.\n");
continue; /* data empty, redisplay menu */
}
switch (choice) { /* handle choice */
case 'a':
printdata (data, *n);
break;
case 'b':
printf ("max value: %d\n", findmaxdatavalue (data, *n));
break;
case 'c':
fprintf (stderr, "RMS not yet implemented.\n");
break;
case 'd':
fprintf (stderr, "Negative count not yet implemented.\n");
break;
case 'e':
return;
break;
case 'r': /* read data, handle error, warn if max values read */
if (!(*n = readdata (data, max)))
fprintf (stderr, "error: nothing read from file.\n");
else if (*n == max)
fprintf (stderr, "warning: data is full.\n");
break;
default : fprintf (stderr, "error: something wrong with switch.\n");
break;
}
}
}
int main (void) {
int data[MAXN] = {0}; /* declare values in main() */
size_t max = MAXN,
n = 0;
userinterface (data, &n, max); /* pass to userinterface */
printf ("\nsuccessfully processed '%zu' integers from file.\n", n);
return 0;
}
Also, note on style, C generally avoid camelCase and MixedCase names, instead using all lowercase names for variables and functions reserving uppercase for constants and macros. Since it is style, it is completely up to you, but it does say something about your code.
Example Use/Output
$ ./bin/menureadint
r) Read data from file
a) Print out the values
b) Find the maximum Value
c) Calculate the RMS (root mean square)
d) Count the number of negative values
e) Exit Back to Main Menu
Enter selection: a
error: data is empty.
... <menu - snip>
Enter selection: z
error: invalid input - choice.
... <menu - snip>
Enter selection: r
enter filename: dat/intvalues.txt
... <menu - snip>
Enter selection: a
data[ 0]: 1
data[ 1]: 6
data[ 2]: 4
data[ 3]: 5
data[ 4]: 5
data[ 5]: 9
data[ 6]: 12
data[ 7]: 14
data[ 8]: 15
data[ 9]: -17
data[ 10]: -19
data[ 11]: 21
data[ 12]: -23
data[ 13]: 0
data[ 14]: 37
data[ 15]: 0
data[ 16]: -31
data[ 17]: 32
data[ 18]: 34
data[ 19]: -37
data[ 20]: -39
data[ 21]: 0
... <menu - snip>
Enter selection: b
max value: 37
... <menu - snip>
Enter selection: c
RMS not yet implemented.
... <menu - snip>
Enter selection: e
successfully processed '22' integers from file.
Look things over and let me know if you have further questions.