C++ - 我是否错误地使用了fin.ignore()?

C++ - Am I using fin.ignore() incorrectly?

本文关键字:fin ignore 是否 错误 C++      更新时间:2023-10-16

我有一个名为"1.txt"的.txt文件,我想读入它。 由于文件以 8 个 BOM 字符开头,如果我执行以下操作:

ifstream fin("1.txt");
string temp = "";
char c = fin.get();
while (!fin.eof())
{
if (c >= ' ' && c <= 'z')
{
temp += c;
}
c = fin.get();
}
cout << temp;

由于 BOM 正在执行的操作,这将不打印任何内容。

因此,我决定使用 fin.ignore() 函数,以忽略文件的开头 BOM 字符。 但是,仍然没有打印任何内容。 这是我的完整程序:

#include <iostream>
#include <fstream>
#include <string>
#include <istream>
using namespace std;
int main()
{
ifstream fin("1.txt");
if (fin.fail())
{
cout << "Failn";
}
else
{
string temp = ""; // Will hold 1.txt's contents.
fin.ignore(10, ' ');
// Ignore first 10 chars of the file or stop at the first space char,
// since the BOM at the beginning is causing problems for fin to read the file.
// BOM is 8 chars, I wrote 10 to just be safe.
char c = fin.get();
while (!fin.eof())
{
if (c >= ' ' && c <= 'z') // checks if c stores a standard char.
{
temp += c;
}
c = fin.get();
}
cout << temp;
// PROBLEM:  No text is printed to the screen from the above command.
cout << temp.size(); // prints 0
}
}

我假设在以下之后:ifstream fin("1.txt"); 行,已经太晚了,因为 BOM 可能影响了 FIN 的事情。 所以我需要以某种方式告诉 fin 在读取文件之前忽略 BOM 字符,但我不能使用 fin.ignore(),因为我还没有声明 fin 对象。

另外,我知道我可以从.txt文件中手动删除 BOM,但我正在寻找一种只涉及我编写C++程序的解决方案。 如果我有数千或数百万个.txt文件,则无法手动删除。 另外,我不想下载新软件,例如记事本++

这是我在文件"1.txt"中的所有内容:

你好±!

这个网站的格式不允许我显示它,但在实际文件中,BOM 和 Hello!

根据 cpp首选项,值为 \x1a 的字符以文本模式终止 Windows 上的输入。你大概在开头就有这样一个角色。我的空.doc文件有一个作为第 7 个字节。

您应该以二进制模式读取文件:

std::ifstream fin("1.txt", std::ios::binary);

您仍然可以使用ignore忽略前缀。但是,在某个特定角色之前,它有点片状的忽略。二进制前缀可以包含该字符。如果这些前缀始终具有相同的长度,则忽略特定数量的字节就足够了。此外,您不能依靠在记事本中查看文件来计算字节数。有不少看不见的字符。您应该改为查看文件的十六进制视图。许多优秀的文本编辑器都可以做到这一点,或者您可以使用Powershell的Format-Hex -Path <path>命令。例如,这是我的前几行:

00000000   D0 CF 11 E0 A1 B1 1A E1 00 00 00 00 00 00 00 00  ÐÏ.ࡱ.á........
00000010   00 00 00 00 00 00 00 00 3E 00 03 00 FE FF 09 00  ........>...þ...
00000020   06 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00  ................

目前尚不清楚删除前缀的最佳方法是什么,而无需更多信息。