C语言字符串数组补全:追加指定长度的'0'串至目标长度
解决C语言中补全反转数组末尾0字符串的问题
问题分析
你的代码存在两个关键问题,导致补0逻辑无法正常工作:
- 反转数组大小不足:你定义的
listOfNumbersReversed行数为counter(原文件中的字符串数量),但当primNum > counter时,这个数组无法容纳primNum个元素,后续补0操作会触发数组越界。 - 补0循环实现错误:循环起始值写法不规范,且内部缺少生成0字符串的逻辑,导致无法正确填充指定长度的0串。
解决方案
步骤1:调整反转数组的行数
将反转数组的行数从counter改为primNum,确保能容纳所有需要的元素:
char listOfNumbersReversed[primNum][secNum+1];
步骤2:实现补0逻辑
在counter < primNum的分支中,从counter开始循环到primNum-1,每个位置生成一个由secNum个'0'组成的字符串(记得添加字符串终止符\0):
if(counter < primNum){ for(i = counter; i < primNum; i++){ // 填充secNum个'0'字符 memset(listOfNumbersReversed[i], '0', secNum); // 手动添加字符串终止符,保证是合法C字符串 listOfNumbersReversed[i][secNum] = '\0'; } }
步骤3:修正最终输出的循环范围
原代码最后输出仅循环到counter,会漏掉补全的0串,需要改为循环到primNum:
printf("\n\nFinal List of Numbers Reversed:\n"); for (i = 0; i < primNum; i++) { printf("%s\n", listOfNumbersReversed[i]); }
完整修正后的代码
#include <stdio.h> #include <string.h> #include <errno.h> int main() { FILE *file = fopen("file.txt", "r"); if (file == NULL) { fprintf(stderr, "Cannot open file.txt: %s\n", strerror(errno)); return 1; } // 读取首行两个整数 int primNum, secNum; if (fscanf(file, "%d %d", &primNum, &secNum) != 2) { fprintf(stderr, "invalid file format\n"); fclose(file); return 1; } // 统计文件中后续字符串的数量 char line[100]; int counter; for (counter = 0; fscanf(file, "%99s", line) == 1; counter++) continue; printf("Total number of items: %d\n", counter); // 重置文件指针,重新读取内容 rewind(file); char listOfNumbers[100][100]; int i; if (fscanf(file, "%d %d", &primNum, &secNum) != 2) { fprintf(stderr, "cannot reread the numbers\n"); fclose(file); return 1; } for (i = 0; i < counter; i++) { if (fscanf(file, "%99s", listOfNumbers[i]) != 1) { printf("could only read %d numbers out of %d\n", i, counter); counter = i; break; } } fclose(file); // 输出原数组内容 printf("1st Number: %d\n", primNum); printf("2nd Number: %d\n\n", secNum); printf("List of Numbers on Array:\n"); for (i = 0; i < counter; i++) { printf("%s\n", listOfNumbers[i]); } // 生成反转数组 char listOfNumbersReversed[primNum][secNum+1]; int j = 0; for(i = counter - 1; i >=0 ; i--){ memcpy(listOfNumbersReversed[j], listOfNumbers[i], secNum+1); j++; } // 输出反转后的原数组内容 printf("\n\nList of Numbers Reversed on Array:\n"); for (i = 0; i < counter; i++) { printf("%s\n", listOfNumbersReversed[i]); } // 补全0串 if(counter < primNum){ for(i = counter; i < primNum; i++){ memset(listOfNumbersReversed[i], '0', secNum); listOfNumbersReversed[i][secNum] = '\0'; } } // 输出最终补全后的数组 printf("\n\nFinal List of Numbers Reversed:\n"); for (i = 0; i < primNum; i++) { printf("%s\n", listOfNumbersReversed[i]); } return 0; }
额外优化说明
- 移除了
fscanf中的\n,因为fscanf会自动跳过空白字符(包括换行),手动添加\n可能导致读取异常。 - 简化了
memcpy的参数写法,数组名本身就是指向首元素的指针,无需额外取地址。
内容的提问来源于stack exchange,提问作者LearningLinux
相关产品推荐
相关产品推荐

