【问题标题】:C++ File Write includes the memory address of the string instead of the contentsC++ 文件写入包括字符串的内存地址而不是内容
【发布时间】:2016-02-19 07:53:37
【问题描述】:

所有, 我仍在学习 C++,但我在一个我正在修补的项目中遇到了一个我很好奇的问题。我注意到,当我尝试打印作为类成员的字符串的内容时,我得到的是内存地址而不是内容。我知道这是因为该项目是一个指针,但我感到困惑的是我使用-> 运算符来尊重它。

为什么我可以在 if 语句中使用 -> 运算符对类成员进行评估以取消引用它,但是当以相同的方式打印到文件字符串时,我却获得了内存地址?

一个例子如下:

假设我有一个名为 pClass 的类,其中有一个名为 m_strEmployeeName 的成员。作为旁注(我不知道这是否重要),m_strEmployeeName 的值是CString 而不是std::string,因此也可能存在一些未知的转换问题。

如果我使用下面的简单代码,我会得到一个内存地址。

std::ofstream file("testfile.text");
file << pClass->m_strEmployeeName;
file.close();

我使用以下解除引用方法得到了相同的行为(我期望这是因为 -> 是同一件事)。

std::ofstream file("testfile.text");
file << (*pClass).m_strEmployeeName;
file.close();

知道我做错了什么吗?

【问题讨论】:

  • 问题是CString 而不是您如何引用该成员。只需创建一个CString 类型的变量并尝试打印它。
  • 只是为了确保,您知道您取消引用 pClass,而不是 m_strEmployeeName,对吗?因为在I understand that this is because the item is a pointer, but what I"m confused about is that I am using the -&gt; operator to deference it.这句话中你似乎暗示了其他的意思。
  • 我添加了MFC 标签,因为您使用的是CStringCString 不是标准 C++ 库的一部分,iostreams 对此一无所知(因此打印了地址)。如果您需要坚持使用CString,ebyrob 的答案将起作用。
  • 查看CString 的文档以了解正确的使用方法。

标签: c++ string pointers mfc filestreams


【解决方案1】:

这是因为您的 CString 类实际上是 CStringW 类,其中包含 wchar_t 字符串,因此 std::ofstream 不包含支持 wchar_t* 字符串的 operator &gt;&gt; 重载。要打印CStringW 类对象,您可以使用这种类型的流std::wofstream,它可以正确识别wchar_t* 字符串并且输出是正确的。

std::wofstream file("testfile.text");
file << pClass->m_strEmployeeName;
file.close();

您还可以创建支持多字节字符的程序。它可以在您的项目设置中指定。但我建议你继续使用 UNICODE。

【讨论】:

  • 这会创建一个 ASCII (UTF-8) 或 UNICODE (UTF-16) 文件作为输出吗?
  • MFC 不再支持 MBCS(并且问题用 MFC 标记)。
  • @Vlad Feinstein:实际上它支持,但必须从 Microsoft 网站单独下载。
【解决方案2】:

尝试将CString 转换为char 指针:

file << (LPCTSTR)pClass->m_strEmployeeName;

见:How to convert CString and ::std::string ::std::wstring to each other?

注意:这仅在您将 TCHAR 定义为 8 位时才有效。如果您使用的是 16 位 UNICODE TCHAR,则需要再进行一次转换。

这是进行TCHAR 转换的一种方法:

char c_str[1000];
size_t ret;    
wcstombs_s(
   &ret,
   c_str,
   sizeof(c_str),
   (LPCTSTR)pClass->m_strEmployeeName,
   pClass->m_strEmployeeName.GetLength()
);

std::ofstream file("testfile.text");
file << c_str;
file.close();

如果您需要 8 位 ASCII 文件但有一个 UNICODE CString 可以使用,这很有用。

【讨论】:

  • 我建议使用std::string 而不是转换。
  • @Slava 同意,但如果有充分的理由使用CString,这将起作用。
  • 输出将保持不变,因为定义了UNICODE,所以LPCTSTR 将是LPCWSTR,它是const wchar_t*T 字母表示TCHAR 和何时定义UNICODE它将是WCHAR 或者它是CHAR
猜你喜欢
  • 2015-07-10
  • 1970-01-01
  • 1970-01-01
  • 2012-08-09
  • 2014-07-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-05-03
相关资源
最近更新 更多