为什么输出到文件里会显示一堆乱码啊

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <conio.h>
 
void printMenu(void);
int checkPwd(int type);
int encryptFile(char *sourcefile, char *secretKey, char *targetFile, int encryptionMethod);
char redo(void);
 
int main() {
    char sourcefile[30], targetFile[30], secretKey[21], action;
    int encryptionMethod; // 加密方式
 
    while (1) {
        system("cls");
        printMenu();
        scanf("%c", &action);
        fflush(stdin);
        system("cls");
 
        switch (action) {
            case 'z':
                exit(0);
                break;
            case 'a':
                while (1) {
                    printf("输入要加密的文件名(含路径):");
                    scanf("%s", sourcefile);
                    printf("输入密钥:");
                    scanf("%s", secretKey);
                    printf("加密后的文件名(含路径):");
                    scanf("%s", targetFile);
 
                    printf("选择加密方式:\n");
                    printf("1. 异或加密\n");
                    printf("2. 其他加密方式\n");
                    printf("请选择:");
                    scanf("%d", &encryptionMethod);
 
                    if (encryptFile(sourcefile, secretKey, targetFile, encryptionMethod)) {
                        printf("文件[%s]加密成功,保存在[%s]。\n", sourcefile, targetFile);
                    }
 
                    if (redo() == 'a') {
                        system("cls");
                    } else {
                        break;
                    }
                }
                break;
            case 'b':
                while (1) {
                    printf("输入要解密的文件名(含路径):");
                    scanf("%s", sourcefile);
                    printf("输入密钥:");
                    scanf("%s", secretKey);
                    printf("解密后的文件名(含路径):");
                    scanf("%s", targetFile);
 
                    printf("选择解密方式:\n");
                    printf("1. 异或解密\n");
                    printf("2. 其他解密方式\n");
                    printf("请选择:");
                    scanf("%d", &encryptionMethod);
 
                    if (encryptFile(sourcefile, secretKey, targetFile, encryptionMethod)) {
                        printf("文件[%s]解密成功,保存在[%s]。\n", sourcefile, targetFile);
                    }
 
                    if (redo() == 'a') {
                        system("cls");
                    } else {
                        break;
                    }
                }
                break;
            case 'c':
                               while(1){    
struct stu
{
    char name[10];
    int num;
    int age;
    char addr[15];
}boya[2],boyb[2],*pp,*qq;
{
    FILE *fp;
    char ch;
    int i;
    pp=boya;
    qq=boyb;
    if((fp=fopen("D:\ceshi.txt","wb+"))==NULL)
    {
        printf("Cannot open file strike any key exit!");
    }
    printf("\ninput data\n");
    for(i=0;i<2;i++,pp++)
    {
        scanf("%s%d%d%s",pp->name,&pp->num,&pp->age,pp->addr);
    }
    pp=boya;
    fwrite(pp,sizeof(struct stu),2,fp);
    //将文件指针重新指向一个流的开头
    rewind(fp);
    fread(qq,sizeof(struct stu),2,fp);
    printf("\n\nname\tnumber      age      addr\n");
    for(i=0;i<2;i++,qq++)
    {
        printf("%s\t%5d%7d     %s\n",qq->name,qq->num,qq->age,qq->addr);
    }
    fclose(fp);
}
    if(redo() == 'a'){  // 重新输入信息
                        system("cls");
                    }else{  // 回到主菜单
                        break;
                    }
                }
                break;
            default:
                printf("没有相应的菜单!按任意键回到主菜单...");
                getch();
        }
    }
 
    return EXIT_SUCCESS;
}
 
void printMenu() {
    printf("***************** 文本加密解密软件 *****************\n");
    printf("*                                                  *\n");
    printf("*      请从下面的菜单中选择你要进行的操作:        *\n");
    printf("*      a. 文件加密                                 *\n");
    printf("*      b. 文件解密                                 *\n");
    printf("*      c. 将信息存放到文件中                       *\n");
    printf("*      z. 退出系统                                 *\n");
    printf("*                                                  *\n");
    printf("****************************************************\n");
}
 
/**
 * 加密/解密文件
 *
 * @param   sourcefile    要加密/解密的文件名
 * @param   secretKey     密钥
 * @param   targetFile    加密/解密后要保存的文件名
 *
 * @return  加密成功或失败的数字表示
     0:加密失败
     1:加密成功
**/
int encryptFile(char *sourcefile, char *secretKey, char *targetFile, int encryptionMethod) {
    FILE *fpSource, *fpTarget;
    char buffer[21];
    int readCount, keyLen = strlen(secretKey), i;
 
    fpSource = fopen(sourcefile, "rb");
    if (fpSource == NULL) {
        printf("文件[%s]打开失败,请检查文件路径和名称是否输入正确!\n", sourcefile);
        return 0;
    }
 
    fpTarget = fopen(targetFile, "wb");
    if (fpTarget == NULL) {
        printf("文件[%s]创建/写入失败!请检查文件路径和名称是否输入正确!\n", fpTarget);
        return 0;
    }
 
    while ((readCount = fread(buffer, 1, keyLen, fpSource)) > 0) {
        if (encryptionMethod == 1) { // 异或加密
            for (i = 0; i < readCount; i++) {
                buffer[i] ^= secretKey[i];
            }
        } else {
          char passwd[100],encrypted[100];
    int i,j,k,t,move,tmp;
    printf("加密选择1,解密选择2:");
    scanf("%d",&tmp);
    if(tmp==1){
        printf("输入原文:");
        scanf("%s",&passwd);
        printf("自定义密匙(1-25):");
        scanf("%d",&move);
        for(i=0; i<strlen(passwd); i++)
        {
            if(passwd[i] >= 'A' && passwd[i] <= 'Z')
            {
                passwd[i] = ((passwd[i]-'A')+move)%26+'A';
            }
            else if(passwd[i] >= 'a' && passwd[i] <= 'z')
            {
                passwd[i] = ((passwd[i]-'a')+move)%26+'a';
            }
        }
        printf("加密后的密文");
        printf("%s\n",passwd);
    }
    else{
        printf("输入密文:");
        scanf("%s",&passwd);
        printf("密匙为(1-25):");
        scanf("%d",&move);
        for(i=0; i<strlen(passwd); i++)
        {
            if(passwd[i] >= 'A' && passwd[i] <= 'Z')
            {
                passwd[i] = ((passwd[i]-'A')+26-move)%26+'A';
            }
            else if(passwd[i] >= 'a' && passwd[i] <= 'z')
            {
                    passwd[i] = ((passwd[i]-'a')+26-move)%26+'a';
            }
        }
        printf("解密后的原文");
        printf("%s\n",passwd);
    }   
 
        }
 
        fwrite(buffer, 1, readCount, fpTarget);
    }
 
    fclose(fpSource);
    fclose(fpTarget);
    return 1;
}
 
char redo() {
    char action;
    printf("\n接下来你希望:\n");
    printf("a. 继续当前操作\n");
    printf("b. 回到主菜单\n");
 
    while (1) {
        fflush(stdin);
        scanf("%c", &action);
        fflush(stdin);
 
        if (action != 'a' && action != 'b') {
            printf("没有相应的菜单,请重新选择。\n");
        } else {
            return action;
            break;
        }
    }
}

img

img

这个问题通常是由编码设置导致的。有几个可能的原因:
向文件写入内容时未指定编码格式

# 在打开文件时指定编码
FILE *fp = fopen("file.txt", "w", "UTF-8");

或者在文件开头添加编码声明:

# -*- coding: UTF-8 -*-

wb 这是 二进制模式写入的

wb表示二进制方式写入,对应的rb是二进制方式读取
那么你写入的本质上是个二进制文件,必须用代码读取才能还原数据
你用记事本打开,本质上是将文件里的所有字节当做char变成字符
问题是里面本来是个int,你强制按char显示肯定是乱码呀

  • 你可以看下这个问题的回答https://ask.csdn.net/questions/7672889
  • 这篇博客你也可以参考下:树的双亲表示法存储结构
  • 除此之外, 这篇博客: 整数的表示中的 浮点数规格化 部分也许能够解决你的问题, 你可以仔细阅读以下内容或跳转源博客中阅读:
  • 浮点数的尾数决定浮点数的有效位数,有效位数越多,精度就越高。
    规格化的目的: 为了在浮点数运算过程中尽可能地保留有效数字的位数,使有效数字尽量占满尾数数位,必须要在运算过程中对浮点数进行 规格化 操作
    左规和右规

    • 当尾数出现形如 ±0.00…00bb…b时,需要进行左规。左规时,尾数每左移一位,阶码就减1,直到化为规格化形式(±0.bbbbb…b)。
    • 当有效数位进到小数点前面时,要右规。每移动一位,阶码加1,直至…

    #烂尾了 不想写 都是树上的内容

  • 您还可以看一下 陈槐老师的零基础新手入门软件测试必知必会课程中的 大型项目测试用例模板内容详细讲解小节, 巩固相关知识点