readCsv函数在main中调用报错,改为main则正常的问题求助
问题分析与解决方案
核心问题1:未初始化的row变量
代码中int row,column = 0;仅对column做了初始化,row的初始值是栈上的随机垃圾值。当readCsv()作为普通函数被调用时,这个随机值可能远大于你要查询的n,导致循环直接跳过所有行,表现为程序“运行异常”;而当它被重命名为main()时,可能恰好栈上的初始值为0,程序侥幸正常运行。
核心问题2:isdigit()的错误使用
isdigit()的参数要求是字符的ASCII码值,你传入的是输入的整数n,比如输入1时n=1,而ASCII码1对应的是控制字符,不是数字字符,导致循环逻辑完全错误。正确的做法是先读取字符串,判断输入是否为纯数字,再转换为整数。
其他问题:非标准的main函数声明
C标准规定main函数的正确声明是int main(void),而非void main(void),后者在部分编译器中可能无法正常工作。
修复后的完整代码
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <ctype.h> int readCsv(void) { int n = 0; while(n == 0) { char input[32]; printf("Enter the index of the student you want to query:"); // 先读取字符串,避免scanf的输入残留问题 fgets(input, sizeof(input), stdin); // 去除换行符 input[strcspn(input, "\n")] = '\0'; // 判断输入是否为纯数字 int is_valid = 1; for(int i=0; input[i]!='\0'; i++){ if(!isdigit((unsigned char)input[i])){ is_valid = 0; break; } } if(is_valid){ n = atoi(input); // 确保输入的索引是正整数 if(n <= 0){ is_valid = 0; } } if(!is_valid){ printf("Please enter a positive integer!\n"); n = 0; } } n++; FILE* fp = fopen("students.csv","r"); // 使用"r"只读模式即可,不需要"r+",避免不必要的权限问题 if (fp == NULL){ perror("Failed to open file"); exit(EXIT_FAILURE); } char buffer[1024]; // 初始化row为0,确保行号从1开始计数 int row = 0, column = 0; while(fgets(buffer,1024,fp)) { column = 0; row++; if(row != n) { continue; } char* value = strtok(buffer,","); while(value) { // 用switch优化列判断逻辑 switch(column){ case 0: printf("\nIndex:"); break; case 1: printf("\tName:"); break; case 2: printf("\tAge:"); break; case 3: printf("\tphone:"); break; } printf("%s",value); value = strtok(NULL,","); column++; } printf("\n"); break; } // 添加未找到对应行的提示 if(row < n){ printf("No student found with index %d\n", n-1); } fclose(fp); return 0; } // 标准main函数声明 int main(void) { readCsv(); return 0; }
关键修复点说明
- 初始化
row为0,确保行号从1开始正确计数 - 重构输入验证逻辑:先读取字符串,用
isdigit()检查每个字符是否为数字,再转换为整数,彻底修复原逻辑的错误 - 将文件打开模式改为
"r"只读,减少权限问题导致的文件打开失败 - 添加未找到对应行的提示信息,增强程序友好性
- 改用
switch语句优化列判断逻辑,代码更简洁易读 - 修正
main函数为标准的int main(void)
内容的提问来源于stack exchange,提问作者Eric 222
相关产品推荐
相关产品推荐

