字符串文字如何存储在 C++ 的内存中?
How are string literals stored in memory for c++?
我对 C++ 的字符串文字如何存储在内存中有疑问。我知道 char
是根据他们的 ascii 代码存储的,但我更喜欢 unicode 字符集。这样做的原因是我尝试处理一些语言环境。让我们假设我正在尝试做的是将小写字符转换为大写字符。这适用于 Xcode 终端,
#include <iostream>
#include <string>
#include <cctype>
#include <clocale>
using namespace std;
int main()
{
wcout.imbue(std::locale("sv_SE.Utf-8"));
const std::ctype<wchar_t>& f = std::use_facet< std::ctype<wchar_t> >(std::locale("sv_SE.Utf-8"));
wstring str {L"åäö"}; // Swedish letters
f.toupper(&str[0], &str[0] + str.size());
std::wcout << str.length() << std::endl;
std::wcout << str << std::endl;
}
Output:
3
ÅÄÖ
然而,当我尝试在 OS X 终端中 运行 它时,我得到了垃圾,
Output:
3
ÅÄÖ
此外,当我提示用户输入时,
#include <iostream>
#include <string>
#include <cctype>
#include <clocale>
using namespace std;
int main()
{
wcin.imbue(std::locale(""));
wcout.imbue(std::locale("sv_SE.Utf-8"));
const std::ctype<wchar_t>& f = std::use_facet< std::ctype<wchar_t> >(std::locale("sv_SE.Utf-8"));
//wstring str {L"åäö"};
wcout << "Write something>> ";
wstring str;
getline(wcin, str);
f.toupper(&str[0], &str[0] + str.size());
std::wcout << str.length() << std::endl;
std::wcout << str << std::endl;
}
我从 Xcode 终端收到垃圾,
Output:
Write something>> åäö
6
åäö
当我使用这些字母时,OS X terminal 实际上挂了。可以修改 wcin
流以假定 C 编码 wcin.imbue(std::locale());
,它仍然在 Xcode 中提供相同的输出,但在 OS X 终端中提供以下内容:
Output:
Write something>> åäö
3
ŒŠš
所以问题很明显与编码有关。所以我想知道字符串文字实际上是如何存储在 C++ 的内存中的。这可以分为两种不同的情况。
案例 1:在源代码中键入的字符串文字,例如 wstring str {L"åäö"};
.
情况 2:通过标准输入流输入的字符串(在本例中为 wcin
)。
这两种情况存储字符串的方式不一定相同。我知道 unicode 是一个字符集,而 utf-8 是一种编码,所以我想知道的是,字符串文字在存储在内存中时是否进行了编码,在这种情况下如何进行编码。
此外,如果有人知道如何以自动方式识别当前终端中使用的编码,那就太好了。
BR
帕特里克
编辑
我收到一些评论,尽管其中一些评论不错,但与问题并不完全相关。这意味着这个问题可能需要一些澄清。这个问题可以被看作是一个相当糟糕的问题的概括:
"Can I assume that string literals are stored with their unicode pointcode in memory?"
至少出于两个原因,这个问题的表述很糟糕。首先,它假设字符串文字是如何存储的(使用它们的 unicode 代码点)。这意味着答案必须与 unicode 相关,即使这种关系可能完全没有意义。此外,这个问题是一个是或否类型的问题,如果答案是否定的,这将没有任何帮助。
我也知道这可以通过将代码点转换为它的等效整数并打印出来进行测试,但这需要我对整个 unicode 字符集进行测试(这似乎是一种不合理的做法) .
首先,文件被解释为字符序列的方式是实现定义的。您必须查阅编译器文档才能确定这一点。
其次,所使用的字符集也是实现定义的。所以你必须再次咨询你的编译器。
当您插入非 ascii 字符时(也可能在使用 ascii 时)可能发生的情况是编译器会对它们进行不同的解释。您必须检查不同的编译器是否真的可以处理相同的编码,最有可能可移植工作的源编码是 UTF-8。
此外,也许您最好为程序的大部分内容使用 UTF-8 编码的文本(只有在需要 wchar_t 的 API 附近才需要以这种方式处理字符串) .
底线。确保您的编译器逐字存储字符串文字并使用普通(窄)字符串,并使用以 UTF-8 编码保存的编辑器。
在此处看到的 string_literal
页面中有很好的背景介绍
https://en.cppreference.com/w/cpp/language/string_literal
我提出这个问题不是为了字节和编码存储的问题,而是关于它们在内存中的位置,即在应用程序的静态内存中:
String literals have static storage duration, and thus exist in memory for the life of the program.
我对 C++ 的字符串文字如何存储在内存中有疑问。我知道 char
是根据他们的 ascii 代码存储的,但我更喜欢 unicode 字符集。这样做的原因是我尝试处理一些语言环境。让我们假设我正在尝试做的是将小写字符转换为大写字符。这适用于 Xcode 终端,
#include <iostream>
#include <string>
#include <cctype>
#include <clocale>
using namespace std;
int main()
{
wcout.imbue(std::locale("sv_SE.Utf-8"));
const std::ctype<wchar_t>& f = std::use_facet< std::ctype<wchar_t> >(std::locale("sv_SE.Utf-8"));
wstring str {L"åäö"}; // Swedish letters
f.toupper(&str[0], &str[0] + str.size());
std::wcout << str.length() << std::endl;
std::wcout << str << std::endl;
}
Output:
3
ÅÄÖ
然而,当我尝试在 OS X 终端中 运行 它时,我得到了垃圾,
Output:
3
ÅÄÖ
此外,当我提示用户输入时,
#include <iostream>
#include <string>
#include <cctype>
#include <clocale>
using namespace std;
int main()
{
wcin.imbue(std::locale(""));
wcout.imbue(std::locale("sv_SE.Utf-8"));
const std::ctype<wchar_t>& f = std::use_facet< std::ctype<wchar_t> >(std::locale("sv_SE.Utf-8"));
//wstring str {L"åäö"};
wcout << "Write something>> ";
wstring str;
getline(wcin, str);
f.toupper(&str[0], &str[0] + str.size());
std::wcout << str.length() << std::endl;
std::wcout << str << std::endl;
}
我从 Xcode 终端收到垃圾,
Output:
Write something>> åäö
6
åäö
当我使用这些字母时,OS X terminal 实际上挂了。可以修改 wcin
流以假定 C 编码 wcin.imbue(std::locale());
,它仍然在 Xcode 中提供相同的输出,但在 OS X 终端中提供以下内容:
Output:
Write something>> åäö
3
ŒŠš
所以问题很明显与编码有关。所以我想知道字符串文字实际上是如何存储在 C++ 的内存中的。这可以分为两种不同的情况。
案例 1:在源代码中键入的字符串文字,例如 wstring str {L"åäö"};
.
情况 2:通过标准输入流输入的字符串(在本例中为 wcin
)。
这两种情况存储字符串的方式不一定相同。我知道 unicode 是一个字符集,而 utf-8 是一种编码,所以我想知道的是,字符串文字在存储在内存中时是否进行了编码,在这种情况下如何进行编码。
此外,如果有人知道如何以自动方式识别当前终端中使用的编码,那就太好了。
BR 帕特里克
编辑
我收到一些评论,尽管其中一些评论不错,但与问题并不完全相关。这意味着这个问题可能需要一些澄清。这个问题可以被看作是一个相当糟糕的问题的概括:
"Can I assume that string literals are stored with their unicode pointcode in memory?"
至少出于两个原因,这个问题的表述很糟糕。首先,它假设字符串文字是如何存储的(使用它们的 unicode 代码点)。这意味着答案必须与 unicode 相关,即使这种关系可能完全没有意义。此外,这个问题是一个是或否类型的问题,如果答案是否定的,这将没有任何帮助。
我也知道这可以通过将代码点转换为它的等效整数并打印出来进行测试,但这需要我对整个 unicode 字符集进行测试(这似乎是一种不合理的做法) .
首先,文件被解释为字符序列的方式是实现定义的。您必须查阅编译器文档才能确定这一点。
其次,所使用的字符集也是实现定义的。所以你必须再次咨询你的编译器。
当您插入非 ascii 字符时(也可能在使用 ascii 时)可能发生的情况是编译器会对它们进行不同的解释。您必须检查不同的编译器是否真的可以处理相同的编码,最有可能可移植工作的源编码是 UTF-8。
此外,也许您最好为程序的大部分内容使用 UTF-8 编码的文本(只有在需要 wchar_t 的 API 附近才需要以这种方式处理字符串) .
底线。确保您的编译器逐字存储字符串文字并使用普通(窄)字符串,并使用以 UTF-8 编码保存的编辑器。
在此处看到的 string_literal
页面中有很好的背景介绍
https://en.cppreference.com/w/cpp/language/string_literal
我提出这个问题不是为了字节和编码存储的问题,而是关于它们在内存中的位置,即在应用程序的静态内存中:
String literals have static storage duration, and thus exist in memory for the life of the program.