C语言指针实现多字符串扫描程序:内存访问违例错误求助
解决指针扫描多字符串的内存访问违例问题
让我们一步步拆解你的问题并修复它:
错误根源分析
你遇到的0xC0000005内存访问违例,主要来自两个核心问题:
函数参数类型不匹配
你的scan_names和print_names函数声明的参数是char* names[LENGH]——这表示一个包含LENGH个字符指针的数组。但在main函数中,你传递的是char names[LINE][LENGH],这是一个二维字符数组,它会退化为指向长度为LENGH的字符数组的指针(类型为char (*)[LENGH])。两种类型不兼容,导致函数内部对指针的操作完全偏离了正确的内存地址,最终触发访问错误。错误的数组初始化
代码里char names[LINE][LENGH] = { NULL };是不恰当的:NULL是指针常量(通常定义为0),用来初始化字符数组会把第一个元素设为\0,但剩余元素是随机值,虽然这不是直接导致崩溃的原因,但不符合字符数组的初始化规范。
修正后的完整代码
#include <stdio.h> #include <string.h> // 用于strcspn处理换行符 #define LINE 3 #define LENGTH 10 // 修正拼写错误:LENGH -> LENGTH // 修改参数类型为二维字符数组的兼容形式 void print_names(char names[][LENGTH], int line) { printf("\nYour names are:\n"); for (size_t i = 0; i < line; i++) { puts(names[i]); } } void scan_names(char names[][LENGTH], int line) { for (int i = 0; i < line; i++) { printf("\nEnter name %d: ", i + 1); // 读取字符串,最多LENGTH-1个字符(留位置存终止符) fgets(names[i], LENGTH, stdin); // 去掉fgets读入的换行符(如果存在) names[i][strcspn(names[i], "\n")] = '\0'; } } int main(void) { // 用空字符串初始化二维数组,确保每个元素都是合法的空字符串 char names[LINE][LENGTH] = {""}; scan_names(names, LINE); print_names(names, LINE); return 0; }
关键修改说明
- 参数类型修正:将函数参数改为
char names[][LENGTH],这是C语言中接收二维字符数组的标准写法,它允许函数接受任意行数、每行长度为LENGTH的二维字符数组,和main中的数组类型完全兼容。 - 处理换行符:
fgets会把用户输入时按下的回车(\n)也读入字符串,我们用strcspn找到换行符的位置,将其替换为字符串终止符\0,避免输出时多出空行。 - 修正拼写错误:把
LENGH改为LENGTH,避免拼写混淆。 - 正确初始化:用
{""}初始化二维数组,确保每个子数组的第一个元素是\0,初始状态为合法的空字符串。
额外注意事项
- 如果用户输入的名字长度超过
LENGTH-1,fgets会截断多余的字符,同时剩余的输入会留在输入缓冲区中,可能影响后续的输入操作。如果需要处理超长输入,可以在fgets后检查是否读取到换行符,若没有则清空缓冲区。 - 如果你想使用指针数组的方式实现(比如每个名字指向动态分配的内存),那需要在
main中声明char* names[LINE];,然后在scan_names中用malloc为每个名字分配内存,记得最后要free避免内存泄漏。
内容的提问来源于stack exchange,提问作者shalom shalom
相关产品推荐
相关产品推荐

