C 数组作为参数传递时发生更改

C 数组作为参数传递时发生更改,c,arrays,C,Arrays,我正在尝试将文件中的负数和正数读入数组 这是我的密码 #include <stdio.h> #include <stdlib.h> #include <math.h> #include <errno.h> #include <string.h> void printData(int data[]) { for (int i = 0; i < 21; i++) { printf("%d\n", data[i]);

我正在尝试将文件中的负数和正数读入数组

这是我的密码

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

void printData(int data[]) {
  for (int i = 0; i < 21; i++) {
    printf("%d\n", data[i]);
  }
}

void findMaximumDataValue(int data[]) {
  int max = -INFINITY;
  for (int i = 0; i < 21; i++) {
    if (data[i] > max) {
      max = data[i];
    }
  }
  printf("The maximum value in the file is: %d\n", max);
}

void userInterface(int data[]) {
  while(1) {
    char choice;
    printf("a) Print out the values\n");
    printf("b) Find the maximum Value\n");
    printf("c) Calculate the RMS (root mean square)\n");
    printf("d) Count the number of negative values\n");
    printf("e) Exit Back to Main Menu\n");
    printf("Enter selection: ");
    scanf("%s", &choice);
    printf(" %c", choice);
    switch (choice) {
      case 'a': {
        printData(data);
        break;
      }
      case 'b': {
        findMaximumDataValue(data);
        break;
      }
      case 'e': {
        return;
      }
    }
  }
}

void dataTxtFunctions() {
  FILE* fp;
  int data[21];
  // Failed to open file
  if ( !(fp = fopen("data.txt", "r")) ) {
    printf("%s\n", strerror(errno));
    return;
  }
  for (int i = 0; i < 21; i++) {
    fscanf (fp, "%d", &data[i]);
  }
  fclose(fp);
  userInterface(data);
}


int main() {
  dataTxtFunctions();

}
第一部分,在菜单显示文件中的正确值之前,但是,当进行选择并传递数组时,数据会发生更改


为什么会这样?

这是读取文件的正确方法:
而(fread(&data[i],sizeof(int),1,fp))

您有大量小错误。(在准则中的注释中说明)。您的主要问题是了解在何处和如何声明
数据
,以及如何将文件中的值作为菜单系统的一部分输入
数据
。虽然您可以在
用户界面
函数中声明数组
数据
,但通常您需要在
main()
(或调用函数)中声明变量,然后将它们作为参数(正确限定)传递给任何需要它们的函数

作为如何填充
数据
的错误观念的一部分,您有一个
void dataTxtFunctions()
,它或多或少随机地漂浮在代码中,而不是附着在任何地方。这个名字也暗示了一个巨大的:

“我不知道我将如何处理这件事,所以我将它称为一些通用的
datatxtformations
,希望它能自行解决?”

注意:这种编码方法永远不会奏效…)

您需要的是一个
readdata
函数来提示输入文件名,打开并验证文件,然后从文件中读取整数,提供读取整数数量的有意义返回(或
0
表示失败)。这样,您就可以创建一个
“r)从文件读取数据\n”
菜单项来处理这些操作

(不要硬编码代码中的值或名称(例如,
data.txt
),魔法数字和魔法字符串会限制代码的用途,并使其难以维护)

其余建议见下文评论。以下示例可用于
data.txt
(我将您在问题中显示的前22个值用作下面的输入文件)。如果我了解您试图实现的目标,您可以执行以下操作:

#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;
}
#包括
#包括
#定义MAXN 256/*如果需要常数,请定义一个*/
/*不要吝啬于数组大小*/
/*清空stdin中保留的所有字符——在scanf之后*/
void empty_stdin()
{
对于(int c=getchar();c!='\n'&&c!=EOF;c=getchar()){}
}
/*打印数据中的值(数据和值数均为常量)*/
无效打印数据(常量整数*数据,常量大小)
{
对于(大小i=0;i最大值)
max=数据[i];
返回最大值;/*返回到仪表成功/失败*/
}
/*提示输入文件名,从文件中读取最大值。
*返回读取的值数(0表示失败)。
*/
大小读取数据(整数*数据,大小最大值)
{
int tmp;/*用于验证读取的临时值*/
char filenm[PATH_MAX]=“”;/*用于保存文件名的缓冲区*/
FILE*fp=NULL;/*文件流指针*/
大小\u t n=0;/*读取的值数*/
for(;;){/*循环,直到提供了有效的文件名或EOF*/
int rtn;
printf(“\n输入文件名:”);
/*如果是EOF,用户使用ctrl+d(windoze上的ctrl+z)取消*/
if((rtn=scanf(“%[^\n]”,filenm))==EOF)
返回0;
空的_stdin();/*删除“\n”(或超出路径_MAX的can字符)*/
如果(rtn==1)/*如果返回1,则在filenm中为良好字符串*/
打破
/*否则,处理错误*/
fprintf(stderr,“错误:无效输入-文件名。\n”);
}
如果(!(fp=fopen(filenm,“r”)){/*验证打开*/
fprintf(stderr,“错误:文件打开失败“%s”\n”,filenm);
返回0;
}
/*从文件中最多读取“max”值*/
而(na) 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
a0
0
0
0
0
0
0
0
192327
0
0
0
8
48
1497598080
32767
1
6
4
5
5
#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;
}
$ ./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.