我在Visual Studio 2008 C ++项目中定义了一个资源文件。问题是在使用LockResource方法获取资源数据后,生成的char缓冲区包含Carriage Returns和Line Feeds,其中原始数据仅包含Line feed。例如,如果原始行包含:
00 0A FC 80 00 00 27 10 00 0A FC 80 00 00 27 10
结果char *还包含Carriage Returns(0D):
00 0D 0A FC 80 00 00 27 10 00 0D 0A FC 80 00 00
我尝试了以下代码来摆脱它们,但这会导致回车和换行都被删除:
for (int i = 0; i < sz; ++i)
{
// Ignore carriage returns
if (data[i] == '\n') continue;
// ...
}
如何摆脱回车符但保留新行字符?
编辑:
使其更具体。我正在将char缓冲区写入文件:
std::ofstream outputFile(fileName.c_str());
for (int i = 0; i < sz; ++i)
{
// Ignore carriage returns
// if (data[i] == '\r') continue; This leaves both CR and LF
// if (data[i] == 0x0D) continue; This leaves both CR and LF
if (data[i]) == '\n') continue; //This removes both CR and LF
outputFile << data[i];
}
答案 0 :(得分:6)
当您向文本文件写'\ n'时,它会转换为'行结束序列'。在你的情况下,这看起来像'\ r \ n'。当您从文本文件中读取时,“行结束序列”将转换回单个“\ n”字符。所以对于正常处理,这个额外的字符不应该影响你(假设你打开两个读/写文本文件)。
如果您不希望将'\ n'转换为'行结束序列',则将文件作为二进制文件打开。完成后,不对'\ n'字符进行处理。
std::ofstream outputFile(fileName.c_str(), std::ios::binary);
// ^^^^^^^^^^^^^^^^
但请注意:文件表示不应影响您。如果您打开并以文本形式阅读文件,'\ r \ n'将在应用程序中转换回单个'\ n'字符。
答案 1 :(得分:4)
这是一个就地转换它的例子。变量i
是要读取的字符的索引,变量j
是要写入的字符的索引。当您通过回车时,i
将开始“超越”j
:
#include <stdio.h>
int main(void)
{
char s[100] = "This is a test.\n\rThis is only a test.\n\r";
for(int i = 0, j = 0; s[i] != '\0'; i++)
if(s[i] != '\r')
s[j++] = s[i];
printf("%s", s);
}
答案 2 :(得分:2)
在给定代码中使用'\r'
代替'\n'
?
答案 3 :(得分:2)
字符'\n'
对应于换行符0x0A
。
'\r'
对应于回车0x0D
。如果您只想删除回车符,请使用该回车符。
顺便说一句,您的代码将不删除这两个代码;它只会删除换行并将回车留在原位。
此外,Windows上没有“新行字符”,因为Windows(与其他操作系统不同)通常使用两个字符序列来表示换行符:{{1 }}。这也是加载资源更改字节序列的原因:Windows认为您正在加载文本并自动将所有可能的换行符转换为规范形式。为了防止这种情况,请不要将资源作为文本加载,而是作为原始字节序列加载(如果可能的话)。
最后,根据您显示字符串的方式,其他字符序列也会导致换行符。例如,所有现代编辑器(这意味着:不是记事本)将接受任何换行序列来创建换行符,无论是"\r\n"
,'\r'
还是'\n'
答案 4 :(得分:2)
您所要做的就是以二进制模式打开文件。像这样:
std::ofstream outputFile(fileName.c_str(), std::ios::out | std::ios::binary);