为什么在使用 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)
所以,你有两个选择:
不要在你的输入文件中使用 \n
,而是像往常一样将行分开,然后使用 istream::read
或类似的函数来读取文件中的所有字节.
如果不允许更改输入文件,请编写一个函数在字符串中搜索“\n”(2 个字符的子字符串)并用单个文字替换它们 \n
(0x0a)
网上有很多例子,这里举一个:Convert string with explicit escape sequence into relative character
遗憾的是,标准库中没有预先存在的函数可以做到这一点,但是自己编写的代码又短又简单,如果只需要翻译就更简单了\n
并且没有其他转义字符。
当我创建 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)
所以,你有两个选择:
不要在你的输入文件中使用
\n
,而是像往常一样将行分开,然后使用istream::read
或类似的函数来读取文件中的所有字节.如果不允许更改输入文件,请编写一个函数在字符串中搜索“\n”(2 个字符的子字符串)并用单个文字替换它们
\n
(0x0a)
网上有很多例子,这里举一个:Convert string with explicit escape sequence into relative character
遗憾的是,标准库中没有预先存在的函数可以做到这一点,但是自己编写的代码又短又简单,如果只需要翻译就更简单了\n
并且没有其他转义字符。