Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/71.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 以二进制和文本模式写入的文件之间的差异_C++_C_File Io - Fatal编程技术网

C++ 以二进制和文本模式写入的文件之间的差异

C++ 以二进制和文本模式写入的文件之间的差异,c++,c,file-io,C++,C,File Io,当写入以文本模式打开的文件而不是以二进制模式打开的文件时,会发生什么转换?特别是在MS Visual C中 unsigned char buffer[256]; for (int i = 0; i < 256; i++) buffer[i]=i; int size = 1; int count = 256; 与文本模式相比: FILE *fp_text = fopen(filename, "wt"); fwrite(buffer, size, count, fp_text); 在文本

当写入以文本模式打开的文件而不是以二进制模式打开的文件时,会发生什么转换?特别是在MS Visual C中

unsigned char buffer[256];
for (int i = 0; i < 256; i++) buffer[i]=i;
int size  = 1;
int count = 256;
与文本模式相比:

FILE *fp_text = fopen(filename, "wt");
fwrite(buffer, size, count, fp_text);
在文本模式下,换行符“\n”可以转换为回车符+换行符“\r\n”

通常,您希望以二进制模式打开。尝试以文本模式读取任何二进制数据都不起作用,它将被损坏。不过,您可以在二进制模式下读取文本ok-它不会自动将“\n”转换为“\r\n”

请参见

在文本模式下,换行符“\n”可以转换为回车符+换行符“\r\n”

通常,您希望以二进制模式打开。尝试以文本模式读取任何二进制数据都不起作用,它将被损坏。不过,您可以在二进制模式下读取文本ok-它不会自动将“\n”转换为“\r\n”


请参见

另外,当您用“rt”打开文件时,输入将以Crtl-Z字符终止。

另外,当您用“rt”打开文件时,输入将以Crtl-Z字符终止。

我们在文本模式下打开文件时遇到了一个有趣的问题,其中文件混合了行结束字符:

1\n\r
2\n\r
3\n
4\n\r
5\n\r
我们的要求是,我们可以将当前位置存储在文件中(我们使用的是fgetpos),关闭文件,然后稍后重新打开文件并搜索到该位置(我们使用的是fgetpos)

但是,如果文件具有混合的行尾,则此过程无法找到实际的相同位置。在我们的例子中(我们的工具解析C++),我们正在重新读取我们已经看到的部分文件


使用二进制-然后您可以精确控制从文件中读取和写入的内容。

在文本模式下打开文件时,我们遇到了一个有趣的问题,其中文件混合了行尾字符:

1\n\r
2\n\r
3\n
4\n\r
5\n\r
#include <stdio.h>
#include <string.h>

int main() {
    FILE *f;
    char string[] = "A\nB";
    int len;
    
    len = strlen(string);
    printf("As you'd expect string has %d characters... ", len); /* prints 3*/
    f = fopen("test.txt", "w"); /* Text mode */
    fwrite(string, 1, len, f);  /* On windows "A\r\nB" is writen */
    printf ("but %ld bytes were writen to file", ftell(f)); /* prints 4 on Windows, 3 on Linux*/ 
    fclose(f);
    return 0;
}
我们的要求是,我们可以将当前位置存储在文件中(我们使用的是fgetpos),关闭文件,然后稍后重新打开文件并搜索到该位置(我们使用的是fgetpos)

但是,如果文件具有混合的行尾,则此过程无法找到实际的相同位置。在我们的例子中(我们的工具解析C++),我们正在重新读取我们已经看到的部分文件


使用二进制-这样您就可以准确地控制从文件中读取和写入的内容。

我相信大多数平台在处理流时都会忽略“t”选项或“文本模式”选项。然而,在windows上,情况并非如此。如果查看位于的fopen()函数的描述,您将看到指定“t”选项将产生以下效果:

#include <stdio.h>
#include <string.h>

int main() {
    FILE *f;
    char string[] = "A\nB";
    int len;
    
    len = strlen(string);
    printf("As you'd expect string has %d characters... ", len); /* prints 3*/
    f = fopen("test.txt", "w"); /* Text mode */
    fwrite(string, 1, len, f);  /* On windows "A\r\nB" is writen */
    printf ("but %ld bytes were writen to file", ftell(f)); /* prints 4 on Windows, 3 on Linux*/ 
    fclose(f);
    return 0;
}
  • 换行符('\n')将在输出时转换为'\r\n'序列
  • 回车/换行序列将在输入时转换为换行
  • 如果文件是以追加模式打开的,则会检查文件末尾是否有ctrl-z字符(字符26),如果可能的话,会删除该字符。它还会将该字符的存在解释为文件结尾。这是CPM时代的一个不幸的延迟(关于父母在第三代或第四代之前所犯下的罪行)。与之前的观点相反,ctrl-z字符将不会被附加

我相信大多数平台在处理流时都会忽略“t”选项或“文本模式”选项。但是,在windows上,情况并非如此。如果您查看位于的fopen()函数的说明,您会发现指定“t”选项将产生以下效果:

  • 换行符('\n')将在输出时转换为'\r\n'序列
  • 回车/换行序列将在输入时转换为换行
  • 如果文件是以追加模式打开的,则会检查文件末尾是否有ctrl-z字符(字符26),如果可能的话,会删除该字符。它还会将该字符的存在解释为文件结尾。这是CPM时代的一个不幸的延迟(关于父母在第三代或第四代之前所犯下的罪行)。与之前的观点相反,ctrl-z字符将不会被附加

另一个区别是使用
fseek

如果流以二进制模式打开,则新位置正好是从文件开头(如果原点为SEEK_设置)、从当前文件位置(如果原点为SEEK_CUR)和从文件结尾(如果原点为SEEK_end)测量的偏移字节数。某些二进制流可能不支持SEEK_end

如果流是以文本模式打开的,则偏移量的唯一支持值为零(适用于任何原点)和与同一文件(仅适用于SEEK_集合的原点)关联的流上先前调用std::ftell返回的值


另一个区别是使用
fseek

如果流以二进制模式打开,则新位置正好是从文件开头(如果原点为SEEK_设置)、从当前文件位置(如果原点为SEEK_CUR)和从文件结尾(如果原点为SEEK_end)测量的偏移字节数。某些二进制流可能不支持SEEK_end

如果流是以文本模式打开的,则偏移量的唯一支持值为零(适用于任何原点)和与同一文件(仅适用于SEEK_集合的原点)关联的流上先前调用std::ftell返回的值


在“w”模式下,文件以写入模式打开,基本编码为“utf-8”
在“wb”模式下,文件以写-二进制模式打开,并负责写入其他特殊字符,编码可能为“utf-16le”或其他

在“w”模式下,文件以写模式打开,基本编码为“utf-8” 在“wb”模式下,文件以写二进制模式打开,并负责写入其他特殊字符,编码可能为“utf-16”