C语言生成随机密码写入文件时出现截断问题求助
问题原因
你遇到的密码截断问题,核心原因是随机字符池的长度计算错误:代码里用sizeof(chars)来计算可选字符的数量,但chars是字符串字面量,sizeof会把末尾的\0终止符也算进去。当rand()随机到等于strlen(chars)的位置时,chars[choice]就是\0,这个字符会被写入password数组,导致password变成一个提前终止的字符串——fprintf用%s输出时,遇到\0就会停止写入,所以文件里的密码会被截断,而且截断位置随机(因为随机到\0的位置是不确定的)。
另外还有个小问题:代码里用了time(NULL),但没包含<time.h>头文件,可能会导致编译警告或错误。
修复方案
- 把
rand() % sizeof(chars)改成rand() % strlen(chars),用strlen获取有效字符的数量,避免选中\0。 - 在头文件中添加
#include <time.h>,为time()函数提供声明。
修复后的完整代码
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <windows.h> #include <time.h> // 补充头文件 int main(){ int i = 0; char password[65536]; char chars[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890_-+={[]}\\|;:'\",<.>/?`~!@#$^&*()"; int size; char path[512]; printf("Where should the key be saved? "); fgets(path, sizeof(path), stdin); path[strcspn(path, "\n")] = 0; Sleep(500); printf("How long should the key be? (max 65535) "); scanf("%d",&size); if(size >= sizeof(password)) { printf("Size is too large\n"); return 1; } getchar(); srand((unsigned int)(time(NULL))); for (i = 0; i < size; i++){ int choice = rand() % strlen(chars); // 替换为strlen(chars) printf("%c",chars[choice]); password[i] = chars[choice]; } password[size] = '\0'; FILE* fptr = fopen(path,"w"); if (fptr == NULL) { printf("Failed to open file for writing\n"); return 1; } fprintf(fptr, "%s", password); fclose(fptr); }
额外说明
- 控制台打印正常是因为
printf("%c", chars[choice])会直接输出\0字符,但控制台对\0不敏感(不会当作字符串终止符),所以能完整显示所有字符;但文件写入时用%s输出,遇到\0就停止,所以出现截断。 - 如果你想更稳妥,也可以用
fwrite代替fprintf,直接写入指定长度的字节,这样即使password里有\0也能完整写入:
这种方式不需要依赖fwrite(password, 1, size, fptr);\0终止符,更适合二进制数据或可能包含特殊字符的内容。
内容的提问来源于stack exchange,提问作者Nicholas Picklas
相关产品推荐
相关产品推荐

