C语言二维字符数组字符串替换问题:printf输出异常求解
问题分析与解决方案
让我看看你的问题——你遇到的这个奇怪输出是典型的缓冲区溢出导致的内存破坏问题,根源出在几个关键的代码错误上:
- 你定义的
char newword;是单个字符变量,只能容纳1个字节,但scanf("%s", &newword)会把输入的整个字符串(包括末尾的结束符\0)写入这个地址开始的内存区域。这直接超出了newword的存储空间,会覆盖掉栈上相邻的array数组内存(因为array在栈中是连续存储的,array[0]和array[1]紧挨着),破坏了array[0]的字符串结构,所以才会输出去掉首字符的内容。 - 另外,
strcpy(array[1], &newword)也存在问题:你把指向单个字符的指针当作字符串指针传递给strcpy,它会读取超出newword范围的内存,行为完全是未定义的。
修复后的完整代码
#include <stdio.h> #include <string.h> int main() { // 用足够大的字符数组存储新单词,长度比最大输入长度多1(留位置存字符串结束符\0) char newword[20]; // 用字符串字面量初始化二维数组,会自动添加\0,比手动逐个字符初始化更安全规范 char array[100][20] = {"Hello", "World"}; printf("%s\n",array[0]); printf("%s\n",array[1]); printf("Type a new word: "); // 限制输入长度为19,防止超出newword的容量(数组长度20,留1位给\0) scanf("%19s", newword); // 直接传数组名给strcpy,数组名会隐式转为指向第一个元素的指针 strcpy(array[1], newword); printf("%s\n",array[0]); printf("%s\n",array[1]); return 0; }
关键修改点解释
- 将单个字符改为字符数组:
char newword[20];确保有足够空间存储输入的字符串和结束符,避免溢出。 - 规范数组初始化:用
{"Hello", "World"}初始化,编译器会自动给每个字符串添加\0,你原来的手动字符初始化没有加\0,能正常输出其实是栈内存的巧合,非常不安全。 - 限制输入长度:
%19s告诉scanf最多读取19个字符,防止用户输入过长内容导致缓冲区溢出。 - 正确传递指针:
scanf和strcpy直接用newword即可,数组名会自动转为指向首元素的指针,不需要加&。
这样修改后,缓冲区溢出的问题就解决了,array[0]的内容不会被破坏,新输入的单词也能正确替换array[1]的内容。
内容的提问来源于stack exchange,提问作者Nick Green
相关产品推荐
相关产品推荐

