为何使用strcpy()后二维数组首索引输出所有字符串连在一起?
问题根源分析
你的问题核心是字符串缺少正确的终止符'\0',导致打印时越界读取内存,把后续数组内容连在一起输出,具体原因有两点:
time_arr的每个元素长度为4,仅能容纳3个有效字符+1个'\0',但fgets会将文件中的换行符'\n'一并读入data。比如文件中一行是"123",fgets会读取成"123\n"(长度为4),用strcpy复制到time_arr[k]时,这4个字符会占满数组空间,没有位置存放'\0'——C语言字符串必须以'\0'结尾才能被正确识别,缺少它的话printf会持续读取内存直到遇到下一个'\0',因此会把后续字符串连在一起输出。- 如果文件中每行内容长度超过3,
strcpy会直接溢出time_arr[k]的内存,破坏相邻存储空间,同样会引发字符串终止异常。
解决方案
针对上述问题,按以下步骤修复:
- 每次用
fgets读取后,先移除换行符:检查data的最后一个字符是否为'\n',若是则替换为'\0'。 - 用
strncpy替代strcpy,限制复制长度避免内存溢出,并且手动添加终止符(strncpy在源字符串长度超过限制时不会自动添加'\0')。 - 确认
time_arr的长度匹配实际需求:如果你的时间字符串是4个字符(比如"0930"),需要将time_arr改为[57][5],预留出'\0'的空间。
修改后的代码示例
char mer_mod[20], input_mer[20], input_mer_vel[20], data[25]; // 调整time_arr长度为5,容纳4个字符+1个终止符 char line[20], time_arr[57][5]; double val_arr[57]; int flag = 0, offsets[5], n=1, j = 0, dates_arr[57], min_date, k =0; if(strcmp(mer_mod, input_mer_vel) == 0 && flag == 1) { flag = 0; for(int i=0; i<3; i++) { memset(data,0,sizeof(data)); fgets(data, sizeof data, *pp_file); // 移除fgets读取的换行符 size_t len = strlen(data); if(len > 0 && data[len-1] == '\n') { data[len-1] = '\0'; } switch (i) { case 0: val_arr[k] = strtod(data, NULL); break; case 1: // 用strncpy限制复制长度,手动添加终止符 strncpy(time_arr[k], data, sizeof(time_arr[k])-1); time_arr[k][sizeof(time_arr[k])-1] = '\0'; break; case 2: dates_arr[k] = atoi(data); break; } } printf("%s\n", time_arr[0]); k++; }
内容的提问来源于stack exchange,提问作者Majerník Tomáš
相关产品推荐
相关产品推荐

