为什么C语言中printf无法打印指针指向的字符串?
问题分析与修复
核心问题:指针位置错误
你在循环里执行*ptr_s++=c时,每次赋值后ptr_s都会向后移动一个字符位置。当循环结束给*ptr_s=0添加字符串结束符时,ptr_s已经指向了字符串的末尾(也就是'\0'所在的位置)。这时候用printf("%s", ptr_s)自然只会输出空内容——因为%s是从指针指向的位置开始输出,直到遇到'\0',而这里起始位置就是'\0'。
解决方法:保存malloc返回的初始指针,比如新增变量char *start_ptr = ptr_s;,最后打印时使用start_ptr即可。
其他潜在问题
- 内存分配未做有效性检查:
malloc可能返回NULL(内存不足时),直接使用会导致程序崩溃,必须添加判断逻辑。 - 缓冲区溢出风险:如果输入的字符串长度超过
GROW_BY(10),会越界写入未分配的内存,触发未定义行为,需要在循环中检查剩余空间,不足时用realloc扩容。 - printf格式错误:原代码里的
printf("please enter a string\n")你写成了换行直接放在引号内,应该用转义字符\n,否则部分编译器会报错。
修复后的代码
#include <stdio.h> #include <stdlib.h> #include <string.h> #define GROW_BY 10 int main(){ char *ptr_s; char *start_ptr; // 保存内存起始地址 int c; int current_len = 0; // 记录当前字符串长度 // 检查内存分配是否成功 ptr_s = malloc(GROW_BY); if (ptr_s == NULL) { fprintf(stderr, "内存分配失败\n"); return 1; } start_ptr = ptr_s; // 固定起始指针 printf("please enter a string\n"); while((c=getchar()) != '\n' && c != EOF){ // 处理输入中断情况 // 检查是否需要扩容,预留一个位置给结束符 if (current_len >= GROW_BY - 1) { char *temp = realloc(start_ptr, current_len + GROW_BY); if (temp == NULL) { fprintf(stderr, "内存扩容失败\n"); free(start_ptr); return 1; } // 重新计算当前指针位置(realloc可能移动内存) ptr_s = temp + (ptr_s - start_ptr); start_ptr = temp; } *ptr_s++ = c; current_len++; } *ptr_s = '\0'; // 添加字符串结束符 printf("the string is : %s\n", start_ptr); // 使用起始指针打印 free(start_ptr); // 释放内存,避免泄漏 return 0; }
关键修改说明
- 新增
start_ptr保存内存起始地址,确保打印时能正确指向字符串开头。 - 添加
malloc和realloc的失败检查,避免程序异常崩溃。 - 加入动态扩容逻辑,防止输入过长导致缓冲区溢出。
- 处理
EOF输入情况,应对用户强制中断输入的场景。 - 最后调用
free释放内存,避免内存泄漏。
内容的提问来源于stack exchange,提问作者lion
相关产品推荐
相关产品推荐

