当前位置: 首页 > ai >正文

【VS2017】cpp文件字符编码异常导致编译报错

这是一个 wav 转 pcm 的简单demo,但VS2017编译报错

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <inttypes.h>
#pragma pack(push, 1)
struct TWavHead
{int8_t   riff[4];				/*!< (4)资源交换文件标志 RIFF */uint32_t file_size;				/*!< (4)文件总长度*/int8_t   wave[4];				/*!< (4)wav文件标志 WAVE */int8_t   fmt[4];				/*!< (4)波形格式标志 FMT */uint32_t fmt_size;				/*!< (4)过滤字节 一般为 0x00000010H */uint16_t aud_fmt;				/*!< (2)格式种类, 为1时,表示数据为线性PCM编码 */uint16_t channels;				/*!< (2)声道数 */uint32_t sample_rate;			/*!< (4)采样率 */uint32_t byte_rate;				/*!< (4)波形数据传输速率,每秒平均字节数 */uint16_t block_align;			/*!< (2)数据调整数,按字节算 */uint16_t bits_pre_sample;		/*!< (2)样本位宽(位深) */
};
struct TWavInfo
{int8_t   data_flag[4];			/*!< (4)数据标识符 data */uint32_t date_size;				/*!< (4)数据长度 */
};
#pragma pack(pop)int main(int argc, char const *argv[])
{if (argc < 2){fprintf(stdout, "no input file\n");return -1;}const char* pchSrcName = argv[1];char achDstName[128] = {0};snprintf(achDstName, 128, "%s.pcm", pchSrcName);FILE* ptSrcFile = fopen(pchSrcName, "rb");FILE* ptDstFile = fopen(achDstName, "wb");TWavHead tHead;TWavInfo tInfo;fread(&tHead, 1, sizeof(TWavHead), ptSrcFile);fseek(ptSrcFile, 2, SEEK_CUR);fread(&tInfo, 1, sizeof(TWavInfo), ptSrcFile);fprintf(stdout, "           riff:%c%c%c%c\n", tHead.riff[0], tHead.riff[1], tHead.riff[2], tHead.riff[3]);fprintf(stdout, "      file_size:%u\n", tHead.file_size);fprintf(stdout, "           wave:%c%c%c%c\n", tHead.wave[0], tHead.wave[1], tHead.wave[2], tHead.wave[3]);fprintf(stdout, "            fmt:%c%c%c%c\n", tHead.fmt[0], tHead.fmt[1], tHead.fmt[2], tHead.fmt[3]);fprintf(stdout, "       fmt_size:%u\n", tHead.fmt_size);fprintf(stdout, "        aud_fmt:%u\n", tHead.aud_fmt);fprintf(stdout, "       channels:%u\n", tHead.channels);fprintf(stdout, "    sample_rate:%u\n", tHead.sample_rate);fprintf(stdout, "      byte_rate:%u\n", tHead.byte_rate);fprintf(stdout, "    block_align:%u\n", tHead.block_align);fprintf(stdout, "bits_pre_sample:%u\n", tHead.bits_pre_sample);fprintf(stdout, "      data_flag:%c%c%c%c\n", tInfo.data_flag[0], tInfo.data_flag[1], tInfo.data_flag[2], tInfo.data_flag[3]);fprintf(stdout, "      date_size:%u\n", tInfo.date_size);uint32_t dwBitNum = tHead.block_align;uint8_t abyBit[128];uint32_t dwRdLen = 0;uint32_t dwSum = 0;for (;;){dwRdLen = fread(&abyBit, 1, dwBitNum, ptSrcFile);if (dwRdLen != dwBitNum){break;}fwrite(&abyBit, 1, dwBitNum, ptDstFile);dwSum += dwBitNum;if (dwSum >= tInfo.date_size){break;}}fflush(ptDstFile);fclose(ptDstFile);fclose(ptSrcFile);fprintf(stdout, "trans over:%u\n", dwSum);return 0;
}

VS2017编译报错:

1>------ 已启动生成: 项目: demo, 配置: Release Win32 ------
1>main.cpp
1>f:\demo\demo\main.cpp : warning C4819: 该文件包含不能在当前代码页(936)中表示的字符。请将该文件保存为 Unicode 格式以防止数据丢失
1>f:\demo\demo\main.cpp(45): error C2039: “wave”: 不是“TWavHead”的成员
1>f:\demo\demo\main.cpp(5): note: 参见“TWavHead”的声明
1>f:\demo\demo\main.cpp(45): warning C4473: “fprintf”: 没有为格式字符串传递足够的参数
1>f:\demo\demo\main.cpp(45): note: 占位符和其参数预计 4 可变参数,但提供的却是 0 参数
1>f:\demo\demo\main.cpp(45): note: 缺失的可变参数 1 为格式字符串“%c”所需
1>已完成生成项目“demo.vcxproj”的操作 - 失败。
========== 生成: 成功 0 个,失败 1 个,最新 0 个,跳过 0==========

根据您提供的代码和编译错误信息,以下是问题分析及解决方案:

1. 字符编码问题

错误信息:

warning C4819: 该文件包含不能在当前代码页(936)中表示的字符。请将该文件保存为 Unicode 格式以防止数据丢失

原因分析:

  • 您的源代码文件中包含了中文注释(如 /*!< (4)资源交换文件标志 RIFF */),而编译器当前使用的代码页(936,简体中文GBK)无法正确表示这些字符。
  • 这可能导致编译器在解析字符串字面量时出现问题,尤其是像 int8_t riff[4]; 这样的数组初始化,如果其中的字符超出了当前代码页的范围,可能会引发错误。

解决方案:

  • 保存文件为 UTF-8 编码:

    • 使用支持选择编码的编辑器(如 Visual Studio、Notepad++ 等)打开您的 .cpp 文件。
    • 将文件编码更改为 UTF-8(无 BOM)。
    • 保存文件后重新编译。
  • 或者,确保所有非ASCII字符都在当前代码页内:

    • 如果必须使用代码页936,确保所有注释和字符串字面量中的字符都在该代码页的支持范围内。
    • 但这种方法较为复杂,推荐使用UTF-8编码。

2. 结构体成员访问错误

错误信息:

error C2039: “wave”: 不是“TWavHead”的成员
note: 参见“TWavHead”的声明

原因分析:

  • 由于字符编码问题,编译器可能误解析了结构体 TWavHead 中的成员,导致 wave 成员未被正确识别。
  • 另外,检查结构体定义是否正确,确保没有拼写错误或遗漏。

解决方案:

  • 解决字符编码问题后,重新检查结构体定义:

    • 确保 struct TWavHead 中确实定义了 int8_t wave[4];
    • 确认没有拼写错误,例如是否写成了 wav 或其他类似名称。
  • 示例检查:

    struct TWavHead
    {int8_t riff[4];          /*!< 资源交换文件标志 RIFF */uint32_t file_size;      /*!< 文件总长度 */int8_t wave[4];          /*!< wav文件标志 WAVE */int8_t fmt[4];           /*!< 波形格式标志 FMT */// 其他成员...
    };
    

3. fprintf 参数不匹配警告

警告信息:

warning C4473: “fprintf”: 没有为格式字符串传递足够的参数
note: 占位符和其参数预计 4 可变参数,但提供的却是 0 参数

原因分析:

  • 由于前面的结构体解析错误,编译器可能误认为 tHead.wave 不存在或类型不正确,导致传递给 fprintf 的参数数量不足。
  • 例如,如果 tHead.wave 被错误地解析为一个单一的 int8_t 而不是 int8_t[4],则 %c%c%c%c 需要四个参数,但实际上只传递了一个。

解决方案:

  • 首先解决字符编码和结构体成员识别问题。
  • 确保 tHead.wave 是一个包含4个元素的数组:
    • 在结构体定义中,int8_t wave[4]; 应该正确解析为一个长度为4的数组。
    • 如果编译器仍然报错,可以尝试显式传递数组元素:
      fprintf(stdout, "          wave:%c%c%c%c
      

",
tHead.wave[0], tHead.wave[1], tHead.wave[2], tHead.wave[3]);
```

4. 其他建议

  • 检查文件路径和权限:

    • 确保输入文件存在且程序有读取权限。
    • 确保输出文件路径正确且有写入权限。
  • 调试编译错误:

    • 逐步注释掉部分代码,确认具体是哪一部分引发错误。
    • 使用编译器提供的详细错误信息,定位问题源头。

总结

主要问题源于源代码文件的字符编码与编译器的代码页不匹配,导致结构体成员无法正确识别。通过将文件保存为 UTF-8 编码,并确保结构体定义正确,可以解决大部分编译错误。同时,注意 fprintf 的参数传递,确保格式字符串与提供的参数数量一致。


解决

修改demo的cpp文件的字符编码方式,由 UTF-8 修改成 GB2312 后,编译成功!
请添加图片描述
请添加图片描述
字符编码修改为 GB2312 后编译成功!
请添加图片描述

http://www.xdnf.cn/news/7819.html

相关文章:

  • 老牌硬件检测工具的现代应用场景分析
  • 【动手学深度学习】1.3. 各种机器学习问题
  • spring的注入方式都有什么区别
  • 网页表格转换为markdown
  • 仅修改文件名会导致文件的MD5值发生变化吗?
  • 制造业ERP系统选型与实施避坑探讨
  • java加强 -网络编程
  • iframe加载或者切换时候,短暂的白屏频闪问题解决
  • Oracle Enqueue Names
  • MySQL中的重要常见知识点(入门到入土!)
  • QT中信号和事件的区别
  • Panasonic松下焊接机器人节气
  • Web3 领域中的一些专业术语
  • Nginx负载均衡配置详解
  • 14、自动配置【源码分析】-初始加载自动配置类
  • 双活数据中心解决方案
  • KubeVirt虚拟机热迁移
  • 第六章 Freertos智能小车循迹模块
  • 【Oracle 专栏】清理用户及表空间
  • STM32 I2C硬件读写
  • MLXJAX框架学习
  • 时源TS4RPSA2-3-3导电硅胶
  • 【已解决】docker search --limit 1 centos Error response from daemon
  • React中使用 Ant Design Charts 图表
  • 31-35【动手学深度学习】深度学习硬件
  • Spark Core 源码关键环节的深度解析
  • [Vue]跨组件传值
  • PCB 横截面几何形状
  • 几种超声波芯片的特点和对比
  • 【东枫科技】usrp rfnoc 开发环境搭建