为什么在使用 prinft() 和 string::c_str() 打印时,程序中定义的 NOT std::string 等于从文件加载的 std::string?

Why is NOT std::string defined in program equal to std::string loaded from file when printing out using prinft() and string::c_str()?

当我创建 std::string 并像这样在程序中定义它并将其打印到控制台时,它看起来像这样:

std::string shader = "#version 330\nlayout(location = 0) in vec3 vp;void main(){gl_Position = vec4(vp, 1.0);}";
printf("Original: %s\n", shader.c_str());

输出:

但是当我按照下面的方式从文件加载 std::string 然后将其打印到控制台时,它看起来像这样:

std::string shader;
std::ifstream inputStream(path, std::ifstream::in);
if (inputStream.is_open())
{
    while (inputStream.good())
    {
        std::string line;
        getline(inputStream, line);
        shader.append(line);
    }
}
printf("LOADED: %s\n", shader.c_str());

文本文件:

#version 330\n
layout(location=0) in vec3 vp;
void main ()
{
     gl_Position = vec4 (vp, 1.0);
}

输出:

我需要从文件加载时做同样的事情。更具体地说,我需要它使用特殊字符 \n.

当我尝试删除“\n”时:

这里的问题是我需要在“..330”和“布局...”之间换行

getline 只是逐行读取输入,停在它会找到的第一个马车 return 处。在文件中手动添加 \ 和 n 只会让 getline 将其解释为更多文本,它只是等待真正的 carriagr return。 您所要做的就是在 .append() 调用中添加 \n。

解决方案是按每个字符读取文本文件,然后打印正确的字符串。

std::string shader;
std::ifstream inputStream(path, std::ifstream::in);
char character;
if (inputStream.is_open())
{
    while (inputStream.get(character))
    {
        shader += character;
    }
}

打印着色器时的输出:

在每个 getline 之后添加 \n 也应该有效。

\n 和类似的形式称为 "escape sequences",它们由编译器在翻译您的代码时处理。

所以像 printf 这样的函数从来没有见过它们,也不知道如何处理它们。 相反,他们看到的是真正的“换行”字符,它是不可见的,并且具有字符代码 10 (0x0a)。

当您在文本编辑器(如记事本)中书写文本时,每次按 Enter 键时它都会自动添加此字符,并且还会保存到文件。 如果您使用十六进制编辑器查看,您可以在任何文本文件中看到这些字符。

(注意,在 Windows 上可能会添加 2 个字符“换行符”和“回车符 return”,即 13 或 0x0d)

所以,你有两个选择:

  1. 不要在你的输入文件中使用 \n ,而是像往常一样将行分开,然后使用 istream::read 或类似的函数来读取文件中的所有字节.

  2. 如果不允许更改输入文件,请编写一个函数在字符串中搜索“\n”(2 个字符的子字符串)并用单个文字替换它们 \n (0x0a)

网上有很多例子,这里举一个:Convert string with explicit escape sequence into relative character

遗憾的是,标准库中没有预先存在的函数可以做到这一点,但是自己编写的代码又短又简单,如果只需要翻译就更简单了\n并且没有其他转义字符。