C语言程序循环正常但输入1/2/3无法执行对应功能求助
嘿,我仔细看了你的代码,发现几个关键问题——你觉得输入1/2/3后函数没执行,其实函数大概率跑了,但因为循环一直不终止,马上又回到输入提示,让你误以为没效果;另外代码里还有不少逻辑错误,导致即使执行了函数,也出不来正确结果。下面一步步给你解决:
1. 无限循环导致的“重复请求输入”问题
你的main函数里的while(loop == 0)循环,loop初始是0,但整个循环里没有任何代码修改loop的值,所以不管你输入什么,循环都会一直跑:执行完对应函数后,立刻回到输入提示那一步,看起来就像函数没执行一样。
修复方案:
给用户加个退出选项(比如输入0退出),或者执行完功能后自动终止循环,示例如下:
while (loop == 0) { printf("Please input the number you want to manipulate (input 0 to exit)\n"); scanf("%d", &user); if (user == 1) { max(dataArray); printf("Max/min calculation done! Check answer.txt\n"); // 如果想执行完就退出,加这句:loop = 1; } else if (user == 2) { integrate(dataArray); printf("Integration done! Check answer.txt\n"); } else if (user == 3) { mean(dataArray); printf("Mean/std calculation done! Check answer.txt\n"); } else if (user == 0) { printf("Exiting program...\n"); loop = 1; // 终止循环 } else { printf("Please enter a valid number (0-3)\n"); } }
2. 数组访问顺序完全搞反了(核心逻辑错误)
你读取文件时,是把数据存在dataArray[j][i](j是行索引,i是列索引),但C语言二维数组是行优先存储,格式是dataArray[行][列]。而你的max、integrate、mean函数里,却用dataArray[col][i]访问——这相当于拿列索引当行用,行索引当列用,完全访问错了数据位置,逻辑当然失效。
比如max函数里的错误写法:
// 错误:col是列索引,不能放在行的位置 if (dataArray[col][i] > largest) { largest = dataArray[col][i]; }
修复成正确的行优先访问:
// 正确:i是行索引,col是列索引(你要的Y值在第1列) if (dataArray[i][col] > largest) { largest = dataArray[i][col]; }
integrate和mean里的dataArray[1][i]也要改成dataArray[i][1],不然你访问的是第1行的第i列,根本不是你要的Y值数据。
3. 计算结果没赋值回变量(等于白算)
你的几个函数里,除法、平方根操作都只是算了值,但没存回变量,比如:
integrate里的answer / 12;→ 应该改成answer /= 12;(等价于answer = answer / 12;)mean里的mean / 80;→ 改成mean /= 80;stdDeviation / 79;→ 改成stdDeviation /= 79;sqrt(stdDeviation);→ 改成stdDeviation = sqrt(stdDeviation);
这些错误会导致你计算的结果根本没被保存,写入文件的还是初始值或者错误的累加值。
4. 极值初始化错误(min值大概率不对)
max函数里smallest和largest初始化为0,如果你的Y值全是正数,那smallest会一直是0,而不是实际的最小值;如果全是负数,largest会一直是0。
修复方案:把它们初始化为第一个Y值:
double smallest = dataArray[0][1]; double largest = dataArray[0][1];
(这里我改成了double,因为如果你的数据是小数,用int会丢失精度,后面会说这个问题)
5. 文件操作的潜在坑
- 打开文件没检查是否成功:如果
data.dat不存在或者权限不够,fopen会返回NULL,后续fscanf会直接崩溃。要加检查:
FILE* data = fopen("data.dat", "r"); if (data == NULL) { printf("Failed to open data.dat! Make sure it's in the right folder.\n"); return 1; // 直接退出程序 }
- 写入文件后没关闭:
writeToFile和writeTwoToFile里的fopen后没有fclose(answers);,这会导致文件缓冲区无法及时刷新,数据可能没写入文件,还会浪费系统资源。 - 用"w"模式会覆盖文件:如果多次执行功能,每次都会清空
answer.txt,要是想追加内容可以改成"a"模式,但根据你的需求,每次覆盖也没问题。
6. 数据类型问题(如果你的数据是浮点数)
你现在用int存储数据,但如果data.dat里的是小数,%1d格式符只会读取整数部分,导致数据完全错误。建议改成double类型存储,这样积分、均值、标准差的计算会更准确:
- 把数组改成
double dataArray[X][Y]; - 读取时用
%lf格式符:fscanf(data, "%lf", &dataArray[j][i]); - 函数参数、变量也都改成
double类型。
修复后的核心代码示例
我把关键修改后的代码贴出来,你可以参考调整:
#include <math.h> #include <stdio.h> const int X = 1001; const int Y = 2; void writeTwoToFile(double answer1, double answer2) { FILE* answers = fopen("answer.txt", "w"); if (answers == NULL) { printf("Failed to open answer.txt!\n"); return; } fprintf(answers, "Min Y: %.2f, Corresponding X: %.2f\nMax Y: %.2f, Corresponding X: %.2f\n", answer1, /* 这里你可以加对应X值的逻辑,比如记录i的值 */ 0.0, answer2, 0.0); fclose(answers); } void max(double dataArray[X][Y]) { int colY = 1; double smallest = dataArray[0][colY]; double largest = dataArray[0][colY]; int minXIndex = 0, maxXIndex = 0; // 你说的是80组数据,所以循环到79 for (int i = 0; i < 80; i++) { if (dataArray[i][colY] > largest) { largest = dataArray[i][colY]; maxXIndex = i; } if (dataArray[i][colY] < smallest) { smallest = dataArray[i][colY]; minXIndex = i; } } writeTwoToFile(smallest, dataArray[minXIndex][0], largest, dataArray[maxXIndex][0]); } int main() { int loop = 0; int user; double dataArray[X][Y]; FILE* data = fopen("data.dat", "r"); if (data == NULL) { printf("Failed to open data.dat!\n"); return 1; } // 读取80组X-Y数据 for (int j = 0; j < 80; j++) { fscanf(data, "%lf %lf", &dataArray[j][0], &dataArray[j][1]); } fclose(data); printf("Welcome to this calculator!\n"); printf("1- Find Y's min/max and corresponding X\n"); printf("2- Numerical integration\n"); printf("3- Calculate mean and standard deviation\n"); printf("0- Exit\n\n"); while (loop == 0) { printf("Enter your choice: "); scanf("%d", &user); switch(user) { case 1: max(dataArray); break; case 2: integrate(dataArray); break; case 3: mean(dataArray); break; case 0: loop = 1; printf("Bye!\n"); break; default: printf("Invalid input, try again!\n"); } } return 0; }
最后提醒下:测试的时候可以先打印几个数组里的数据,比如printf("First X: %.2f, First Y: %.2f\n", dataArray[0][0], dataArray[0][1]);,确认文件读取是否正确,避免因为数据格式不匹配导致后续逻辑全错。
内容的提问来源于stack exchange,提问作者user9800535

