C ++ - 我是否正确使用fin.ignore()?

问题描述 投票:0回答:1

我有一个名为“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 << "Fail\n";
}

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文件,则无法手动删除。此外,我不打算下载新的软件,如Notepad ++

这是我在“1.txt”文件中的全部内容:

ÐÏࡱá你好!

这个网站的格式不允许我显示它,但在实际文件中,BOM和Hello之间大约有15个空格!

c++ file file-io ifstream byte-order-mark
1个回答
2
投票

根据cppreference,值为\ 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  ................

目前还不清楚删除前缀的最佳方法是没有更多信息。

© www.soinside.com 2019 - 2024. All rights reserved.