#include <stdio.h>
int main()
{
char *str;
gets(str);
puts(str);
return(0);
}
可以说全是错误
首先char *str
没有指向一个分配好的地址,就直接读入,危险
ps:
怎么理解char *str = "Hello World"
是将一个存储在一个只读的数据段中字符串常量"Hello World"
的首地址赋值给了str
gets(str);
尝试从标准输入读取一个字符串并存储在 str
指向的位置。但是,由于 str
没有被初始化为指向有效的内存,gets
函数可能会尝试写入一个随机的内存地址,这会导致程序崩溃或更糟糕的后果。
puts(str);
试图打印从 gets
读取的字符串。但是,由于 gets
可能导致未定义行为,str
指向的内容可能是不确定的,所以 puts
的行为也是不确定的。
更糟糕的是,gets
函数已被认为是不安全的,并且在 C11 标准中已被移除,因为它不提供任何方式来防止缓冲区溢出。如果输入的数据超过了 str
实际指向的缓冲区的大小,就会发生缓冲区溢出,这可能导致程序崩溃、数据损坏或更严重的安全漏洞(如栈溢出攻击)。
为了避免这种危害,你应该:
使用 malloc
或其他动态内存分配函数为字符串分配内存,并确保 str
指向这块内存。
使用 fgets
替代 gets
,因为 fgets
允许你指定一个缓冲区大小,从而防止缓冲区溢出。
关于fgets
char *fgets(char *str, int n, FILE *stream);
str
:指向一个字符数组的指针,用于存储读取的数据。
n
:要读取的最大字符数(包括结尾的空字符 \0
)。
stream
:指向 FILE
对象的指针,指定要从中读取数据的输入流。
fgets
函数返回一个指向 str
的指针,如果发生错误或达到文件末尾,则返回 NULL
。读取的数据包括任何结尾的换行符(如果存在的话),并且字符串总是以空字符 \0
结尾。
#include <stdio.h>
#define MAX_INPUT 100 // 定义输入的最大长度
int main() {
char str[MAX_INPUT];
// 从标准输入读取一行,最多读取 MAX_INPUT - 1 个字符,保留一个位置给空字符
if (fgets(str, MAX_INPUT, stdin) != NULL) {
// 移除可能的换行符
str[strcspn(str, "\n")] = 0;
puts(str);
} else {
printf("Failed to read input.\n");
}
return 0;
}