为何使用fwrite写入文件时字符间会出现空格?
为何使用fwrite写入文件时字符间会出现空格?
嗨,这个问题我之前也踩过坑,咱们来慢慢理清楚原因和解决办法~
你看到的“字符间空格”其实不是真的空格,而是宽字符编码带来的空字节在文本编辑器里的显示效果。
你代码里用的WCHAR是Windows平台的宽字符类型,每个WCHAR占2个字节(对应UTF-16编码)。举个例子,字符'C'在内存里存储的是0x43 0x00——第一个字节是字符的ASCII值,第二个字节是空字节(0x00)。而fwrite是个“实诚”的函数,它会把内存里的字节原封不动写入文件。
当你用普通文本编辑器打开这个文件时,编辑器默认会把它当成单字节的ASCII文本解析。那每个宽字符的第二个空字节0x00,就会被编辑器显示成空格(或者其他占位符),所以看起来每个字符之间都多了个空格。
给你两个常用的解决思路:
- 思路一:改用窄字符处理(适合不需要Unicode支持的场景)
把宽字符相关的类型和函数都换成窄字符版本,这样写入的就是单字节字符,不会有空字节干扰。修改后的代码如下:
FILE* clickfile; fopen_s(&clickfile, "something.txt", "w+"); int textlen; textlen = GetWindowTextLengthA(blahwnd); textlen++; char* buf; buf = new char[textlen]; GetWindowTextA(blahwnd, buf, textlen); fwrite(buf, sizeof(char), textlen, clickfile); delete[] buf; fclose(clickfile);
这里用到的GetWindowTextLengthA和GetWindowTextA都是专门处理窄字符的A版本函数。
- 思路二:保留宽字符,让文件被正确识别为UTF-16
如果你的程序需要支持Unicode,那可以用宽字符版本的文件操作函数,或者在打开文件时指定编码,让编辑器知道这是UTF-16文件。比如这样写:
FILE* clickfile; _wfopen_s(&clickfile, L"something.txt", L"w+, ccs=UTF-16LE"); int textlen; textlen = GetWindowTextLength(blahwnd); textlen++; WCHAR* buf; buf = new WCHAR[textlen]; GetWindowText(blahwnd, buf, textlen); fputws(buf, clickfile); delete[] buf; fclose(clickfile);
这里_wfopen_s是宽字符版本的文件打开函数,ccs=UTF-16LE参数会让文件开头写入UTF-16LE的BOM(字节顺序标记),普通文本编辑器看到BOM就会用UTF-16编码解析,不会再把空字节显示成空格了。
另外如果你一定要用fwrite写宽字符,那记得先在文件开头写入0xFF 0xFE(UTF-16LE的BOM),这样编辑器也能正确识别编码,只是用专门的宽字符写入函数会更省心。
内容来源于stack exchange
相关产品推荐
相关产品推荐

