询问代码片段char name[] = {}; gets(name);能否存储未知长度的姓名
代码有效性分析与解决方案
原代码的问题
你贴的这段代码完全无效,还存在严重安全隐患:
char name[] = {};定义了长度为0的字符数组,连字符串必需的结束符\0都存不下,没有任何空间存储输入内容。gets(name)会强行把用户输入的所有字符写入这个0长度数组,直接触发缓冲区溢出,属于C语言的未定义行为——程序可能崩溃、数据被篡改,甚至被恶意利用。另外,gets早在C11标准里就被彻底废弃,绝对不该再用。
处理未知长度字符串输入的正确方法
要存储未知长度的姓名输入,核心是用动态内存适配输入长度,这里给两种实用方案:
方案1:fgets配合动态扩容(标准C全兼容)
先分配初始缓冲区,用fgets读取后判断是否读完整,没读完就扩容缓冲区继续读取:
#include <stdio.h> #include <stdlib.h> #include <string.h> int main() { size_t buf_size = 64; // 初始缓冲区大小可按需调整 char *name = malloc(buf_size); if (name == NULL) { perror("内存分配失败"); return 1; } char *pos; // 循环读取直到获取完整输入 while (fgets(name, buf_size, stdin) != NULL) { // 检查是否读到换行符(说明输入结束) if ((pos = strchr(name, '\n')) != NULL) { *pos = '\0'; // 替换换行符为字符串结束符 break; } // 没读完,扩容缓冲区 size_t new_size = buf_size * 2; char *temp = realloc(name, new_size); if (temp == NULL) { perror("缓冲区扩容失败"); free(name); return 1; } name = temp; buf_size = new_size; } printf("输入的姓名:%s\n", name); free(name); // 记得释放动态分配的内存 return 0; }
方案2:getline(POSIX系统适用,如Linux/macOS)
getline会自动分配足够内存存储输入,无需手动管理缓冲区,用法更简洁:
#include <stdio.h> #include <stdlib.h> int main() { char *name = NULL; size_t buf_size = 0; ssize_t read_len; // getline自动分配内存读取输入 if ((read_len = getline(&name, &buf_size, stdin)) == -1) { perror("读取输入失败"); return 1; } // 去掉换行符(如果存在) if (read_len > 0 && name[read_len - 1] == '\n') { name[read_len - 1] = '\0'; } printf("输入的姓名:%s\n", name); free(name); // 释放getline分配的内存 return 0; }
内容的提问来源于stack exchange,提问作者slim_shaddy
相关产品推荐
相关产品推荐

