【问题标题】:Getting the first character from a string从字符串中获取第一个字符
【发布时间】:2020-10-02 21:12:24
【问题描述】:
#include <string>
using namespace std;

ifstream input = "foo.txt";
string val;
getline(inputFile, val); //using ifstream, no empty string
//val = "hello"

cout << val[0] // \357
cout << val[3] // h

所以按照我的理解,我将指针存储在前三个字节中而不是字符值中?有没有办法让我可以访问[0]处的角色?我使用 std::string

【问题讨论】:

  • 请给我们minimal reproducible example,表明您正在获取内存地址。 std::string::operator[] 返回一个char,所以你不应该得到地址。
  • 如果它来自保存在磁盘上的 UTF-8 文件,那么前 3 个字节很可能是 UTF-8 BOM。前 3 个字节是 0xEF,0xBB,0xBF 吗?如果是这样,那就是 UTF-8 BOM,可以忽略。
  • @Dai 你应该把你的评论变成答案。
  • UTF-8 BOMs 是一个 aBOMation :(
  • @Botje 是的,但是如果您使用的是 Microsoft 软件,那么您几乎会被它们所困扰。除非您使用 BOM,否则他们的东西几乎普遍拒绝识别 UTF-8 文件。

标签: c++


【解决方案1】:

(发布我的评论作为答案并对其进行扩展)

我将指针存储在前三个字节而不是字符值中?

此语句毫无意义:getline(istream&amp;,string&amp;) 函数输出 字符,而不是字节到 string 实例中(如果您在默认情况下使用宽字符,则使用相同的代码),因此阅读您所说的“将指针存储在前三个字节中而不是字符值中”的评论就像说您将水果篮 inside 存储为橙子一样。

其次,getline 不会将指针存储在您传递给它的 string val 内 - 并且 string 本身不会存储在其内部字符数组元素内分解的指针(有趣的事实:prior to C++11@ 987654329@的字符不需要存储在连续内存中!)。

无论如何,您实际上对指针没有任何问题的最大暗示是指针在任何现代平台上都不是 3 字节(24 位)长(因为 24 位指针只会给您 16MiB 的地址空格)...所以我想,鉴于您的程序正在从文本文件(foo.txt)中读取,并且您注意到文本出现在文件means there's 3 "invisible" characters at the start of the file 的第三个字符位置 - 如果它是不寻常的不是因为微软决定为所有以 UTF-8 保存的文本文件加上字节顺序标记,这样程序就可以检测到 UTF-8 文本文件,从而正确地将它们解释为 UTF-8 而不是 ASCII 或其他一些 OEM 编码 - 因为不像比较 ASCII 和 UTF-16(其中每个其他字节 90% 的时间都是零)几乎不可能轻松比较 ASCII 文件和 UTF-8 文件(尤其是 UTF-8 文件,仅使用低于0x7F 的字符),因为编码不明确.问题是使用 UTF-8 的文件实际上不应该有 BOM 前缀,因为 BOM 只与 UTF-16 和 UTF-32 相关(因为 UTF-8 的工作原理与字节顺序和字节顺序无关)。

UTF-8 BOM 字节是 0xEF, 0xBB, 0xBF - 它们的确切值的原因很复杂 - 但我敢打赌,您的计算机上显示的 string val 的前 3 个字符是不可见的或 rendered using Mojibake characters因为计算机将0xEF 解释为可见的普通人 字符,但它不是 - 或者它向您显示了原始值,也许您的调试器可以选择解释 那些字节作为指针地址——但这只是你的调试器在做的。

【讨论】:

    猜你喜欢
    • 2015-05-21
    • 1970-01-01
    • 2015-02-08
    • 2018-07-11
    • 1970-01-01
    • 2013-03-01
    • 1970-01-01
    相关资源
    最近更新 更多