You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C语言写入十六进制字符串到文件出现乱码问题排查

问题

我希望创建一个每行包含一个新字符串密钥的文本文件program.txt,但运行以下C语言代码后,生成的文件出现乱码。请问代码哪里出错了?

原代码

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <unistd.h>
#include <fcntl.h>
#include <string.h>

#define KEYSIZE 16

int main(){
  FILE *fptr;

  fptr = fopen("program.txt", "w");

  if (fptr == NULL) {
      printf("Error!");
      exit(1);
  }

  int num_keys = 1524006529 - 1523999329;
  const char *keys[num_keys];
  int idx = 0;
  int j;

  for (j = 1523999329; j<= 1524006529; j++){
    int i;
    char key[KEYSIZE];
    srand (j); 
    for (i = 0; i< KEYSIZE; i++){
      key[i] = rand()%256;
      printf("%.2x", (unsigned char)key[i]);
      fprintf(fptr, "%.2x", (unsigned char)key[i]);
    }
    fprintf(fptr, "%s", "
");
    printf("
");
    keys[idx] = key;
    idx ++;
  }
  fclose(fptr);
  return 0;
}

生成的乱码内容

h?G??+?
Mp???+??
        a?G????#*Jb`e0?H?????G??????
S6&}?Μ??G??OFf??|???s8f?G????ɼ???5q??(???K?G??  ??J????9?+???G?????cZ?n0?Jr?G?????#O9]??????jH??G???krT?̇)?A
                             ?g?v?G??????h^(?^?
                                               û/?G???^vB?~W?39???G??\????"?iJ_????G??p??>??????I???U?G????????:??o?RV???G??/?C?^?????|?۬?G??q@0.L$+??Nv?????G????u?    L?Ϩ????dv?G??[??C「<?i???G??UyM??Ƭ/??CxXUě?G?????φ
                                                          ׏:W&?G????=J???o???I??G???G%DA+"?~5?Z¡?G??øL#??O=e?b?u.O?G????*jjɥ+T?)?օ?G??2w  }a,ȃ??tC?s?G??J"/c??Mn???f?y??G????p?Ay?c????~"<??G?????Ӆ?=%??@???G??o?\??<w???4WϚBE?G??}oh??(??#HK???&?G????Vfz
???e?s?G??/?Ye??iV?؛?,-te?G??I?Ҁx??5?B!b?4?G??6Z??9?P?GcB?}???Y?~|"??dd??G??????=?ms?
    ??G?????^??[H??\:???G??2(J??A??????G???????o#?i?/???G??P?5?5?5X??

错误分析及修正

1. 换行符写入错误(直接导致乱码)

原代码中fprintf(fptr, "%s", " ");和printf(" ");的写法完全错误。C语言里字符串常量不能直接换行,这种写法会被编译器解析为无效字符串,实际写入文件的不是换行符\n,而是乱码字符。

修正方式:将换行写法改为标准的"\n":

fprintf(fptr, "\n");
printf("\n");

2. 局部变量指针悬空(严重未定义行为)

keys[idx] = key;把循环内的局部数组key的地址存入keys数组,但key是栈上的局部变量,每次循环结束后内存会被释放,keys里的指针都会变成无效的悬空指针,后续使用会触发未定义行为(虽不直接导致乱码,但必须修复)。

修正方式:若要保存密钥,需为每个密钥动态分配内存并复制内容:

// 先动态分配存储指针的数组
char** keys = malloc(num_keys * sizeof(char*));
// 循环内复制key内容
keys[idx] = malloc(KEYSIZE);
memcpy(keys[idx], key, KEYSIZE);
// 程序结束前释放内存
for(int i=0; i<num_keys; i++) free(keys[i]);
free(keys);

3. 字符类型符号问题

char key[KEYSIZE];中的char在多数系统是有符号类型(范围-128127),但`rand()%256`生成0255的数值,超过127的数值会被当作负数存储,后续操作可能出问题。

修正方式:改用unsigned char定义key:

unsigned char key[KEYSIZE];

修正后的完整代码

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <unistd.h>
#include <fcntl.h>
#include <string.h>

#define KEYSIZE 16

int main(){
  FILE *fptr;

  fptr = fopen("program.txt", "w");

  if (fptr == NULL) {
      printf("Error!");
      exit(1);
  }

  int num_keys = 1524006529 - 1523999329;
  // 动态分配存储密钥指针的数组(不需要保存密钥可删除此行)
  char** keys = malloc(num_keys * sizeof(char*));
  int idx = 0;
  int j;

  for (j = 1523999329; j<= 1524006529; j++){
    int i;
    unsigned char key[KEYSIZE];
    srand(j); 
    for (i = 0; i< KEYSIZE; i++){
      key[i] = rand()%256;
      printf("%.2x", key[i]);
      fprintf(fptr, "%.2x", key[i]);
    }
    // 写入正确的换行符
    fprintf(fptr, "\n");
    printf("\n");
    // 复制密钥到动态内存(不需要保存密钥可删除下面两行)
    keys[idx] = malloc(KEYSIZE);
    memcpy(keys[idx], key, KEYSIZE);
    idx ++;
  }
  fclose(fptr);
  // 释放动态分配的内存(不需要保存密钥可删除下面三行)
  for(int i=0; i<num_keys; i++){
    free(keys[i]);
  }
  free(keys);
  return 0;
}

内容的提问来源于stack exchange,提问作者James

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.16 18:26:17