【问题标题】:Using same object to write wide char and char to write to the same file使用同一个对象写入宽字符和字符写入同一个文件
【发布时间】:2019-09-05 19:17:25
【问题描述】:

我有 C 代码,我正在尝试将其转换为 C++。总结一个C语言的sn-p代码如下:

    FILE *fp = fopen("temp.bin", "wb");
    wchar_t* wide_word = _T("wide char");
    char* word = "char";
    fwprintf(fp, _T("%s"), wide_word);
    fprintf(fp, "%s", word);

在 C 情况下的优点是我们可以通过简单地传递指针来继续使用相同的 fp 指针来打印 char 和 Wide char。我们是否可以在 C++ 中实现相同的功能,而无需初始化对象 ofstreamwofstream 以写入同一个文件并获得与上述 C 实现完全相同的输出?

我在 C++ 中尝试了以下内容(以及许多其他内容)

    auto os = std::ofstream("temp_cpp.bin", std::ios::binary | std::ios::out);
    wchar_t* wide_word = _T("wide char");
    char* word = "char";
    std::wstring st(wide_word);
    std::string str(st.begin(),st.end());
    os.write(reinterpret_cast<const char*>(str.c_str()), sizeof(str));
    os.write(reinterpret_cast<const char*>(word), sizeof(word));

【问题讨论】:

  • 不,出于同样的原因,代码 sn-p 要求您同时使用 fprintf()fwprintf()
  • sizeof(str) 记住sizeof()c++ 中的编译时间常数
  • 您通常应该创建相同明确编码的文件或支持适当的数据序列化。您可以对reinterpret_cast 使用一些骇人听闻的技巧,但之后您将如何读取数据?
  • 数据被用于wstring变量。
  • 你也不能做你在 C 中出现的事情,也不能得到明确定义的结果。 C 流要么是面向字节的,要么是面向宽的,这取决于要在它们上使用的第一个 I/O 函数的性质,并且您不得(根据标准“不应”)将宽函数应用于面向字节流,反之亦然。

标签: c++ c stream fstream


【解决方案1】:

是的,您可以使用相同的 write 函数将 ANSI 字节或宽字符字节写入文件。代码中有一些错误。 sizeof(str) 将返回 std::string 对象的大小,而不是字符串的长度,sizeof(word) 将返回指针的大小,而不是字符串的长度(尽管您可能很幸运在 32位系统,其中指针的大小与您的字符串长度相匹配)。此外,您要编写两次 ANSI 字符,而不是先编写宽字符,然后编写 ANSI 字符,因为您可能打算按照 fprintf 示例进行操作。你打算在那里写的可能是:

auto os = std::ofstream("temp_cpp.bin", std::ios::binary | std::ios::out);
const wchar_t* wide_word = L"wide char";
const char* word = "char";
std::wstring st(wide_word);
std::string str(st.begin(), st.end());
os.write((const char*)(st.c_str()), st.length() * sizeof(wchar_t));
os.write(word, strlen(word));

这应该会产生与您的 fprintf 示例相同的文件内容(但不能保证,因为它可能取决于 setLocale)。或者,不使用std::wstring

auto os = std::ofstream("temp_cpp.bin", std::ios::binary | std::ios::out);
const wchar_t* wide_word = L"wide char";
const char* word = "char";
os.write((const char*)wide_word, wcslen(wide_word) * sizeof(wchar_t));
os.write(word, strlen(word));

是否建议将不同的文本编码写入同一个文件是另一个问题。

【讨论】:

  • 是的,您可以写入wchar_t 数据的字节,但这不一定会产生与通过面向宽的 I/O 写入宽字符串相同的效果功能/对象。内部表示不一定与外部表示相同,宽 I/O 函数执行任何需要的转换。
  • 谢谢;我已经更新了答案。您需要以与写入字节相同的方式读回字节。我相信目的是写入同一个流,不一定要产生与fwprintf 相同的输出。
猜你喜欢
  • 1970-01-01
  • 2012-05-04
  • 2012-02-01
  • 1970-01-01
  • 2019-09-02
  • 2013-01-26
  • 1970-01-01
  • 2013-08-30
  • 2011-03-09
相关资源
最近更新 更多