【问题标题】:Edit text file in place using C++使用 C++ 就地编辑文本文件
【发布时间】:2015-06-26 22:33:24
【问题描述】:

我有一个文本文件,我正在向其中添加标签以使其 XML 可读。为了让我们的读者识别它是有效的,每一行都必须至少包含在标签中。我的问题出现了,因为这实际上是一本叙利亚语翻译词典,所以有很多非标准字符(实际的叙利亚语单词)。我看到完成我需要的最直接的方法是简单地在每一行前面加上所需的标签,而不必访问或修改该行的其余部分。任何其他选项也将不胜感激。

ifstream in_file;
string file_name;

string line;
string line2;
string pre_text;
string post_text;

int num = 1;

pre_text = "<entry n=\"";
post_text = "</entry>";

file_name = "D:/TEI/dictionary1.txt";
in_file.open(file_name.c_str());

if (in_file.is_open()){
    while (getline(in_file, line)){
        line2 = pre_text + to_string(num) + "\">" + line + post_text;
        cout << line2;
        num++;
    }
}

有问题的文件可以下载here.

【问题讨论】:

标签: c++ text


【解决方案1】:

您正在使用std::string,默认情况下,它处理 ASCII 编码的文本,并且您正在以“文本翻译模式”打开文件。您需要做的第一件事是以二进制模式打开文件,这样它就不会对单个 char 值执行翻译:

in_file.open(file_name.c_str(), std::ios::binary);

或在 C++11 中

in_file.open(file_name, std::ios::binary);

接下来是停止使用 std::string 来存储文件中的文本。您将需要一个字符串类型来识别您正在使用的字符编码并使用适当的字符类型。

事实证明,std::string 实际上是std::basic_string&lt;char&gt; 的别名。在 C++11 中引入了几种新的 unicode 字符类型,在 C++03 中,wchar_t 支持“宽”字符(超过 8 位)。 basic_strings 的 wchar_ts 有一个标准别名:std::wstring

从以下简单测试开始:

#include <iostream>
#include <fstream>
#include <string>

int main() {
    std::string file_name = "D:/TEI/dictionary1.txt";
    std::wifstream in_file(file_name, std::ios::binary);

    if (!in_file.is_open()) {
        // "L" prefix indicates a wide string literal
        std::wcerr << L"file open failed\n";
        return 1;
    }

    std::wstring line1;
    std::getline(in_file, line1);
    std::wcout << L"line1 = " << line1 << L"\n";
}

请注意cout 等如何也以w 为前缀...

标准 ASCII 字符集包含 128 个字符,编号从 0 到 127。在 ASCII 中,\n\r 分别用 13 和 10 的 7 位值表示。

您的文本文件似乎是 UTF-8 编码的。 UTF-8 使用 8 位无符号表示,允许字符使用可变数量的字节:值 0 需要 1 个字节,值 128 需要 2 个字节,值 8192 需要 3 个字节,依此类推。

最高位 (2^7) clear 的值是单个 7 位 ascii 值或多字节序列的结尾。如果设置了最高位,则将较低位视为“前缀值”。所以字节序列{ (128+2), 0 } 将表示值(2 &lt;&lt; 7) | 0(wchar_t)256。字节序列{ 130, 13 }代表(2 &lt;&lt; 7) | 13wchar_t 269

您可以通过char 流和存储读取和写入utf-8 ,但只能作为不透明字节流。当您开始需要了解您通常需要求助于wchar_tuint16_tuint32_t 等的值时。

如果您正在使用 Microsoft 的工具集(注意“D:/”路径),您可能需要查看 TCHAR (https://msdn.microsoft.com/en-us/library/c426s321.aspx)

【讨论】:

  • std::getline(in_file, line1); 行抛出错误“没有重载函数 'std::getline' 的实例与参数列表匹配。参数类型为: (std::ifstream, std::wstring)”
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-03-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多