c++的字符串字面值如何存储在内存中?
How are string literals stored in memory for c++?
我有一个关于c++中字符串字面值如何存储在内存中的问题。我知道char
是根据它们的ascii码存储的,但我更喜欢unicode字符集。这样做的原因是我试图处理一些区域。假设我要做的是将小写字符转换为大写字符。
#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终端实际上会挂起。可以修改wcin
流以假定C编码wcin.imbue(std::locale());
,这在Xcode中仍然给出相同的输出,但在OS X终端中给出以下内容:
Output:
Write something>> åäö
3
ŒŠš
所以这个问题很明显与编码有关。我想知道在c++中字符串是如何存储在内存中的。这可以分为两种不同的情况。
情形1:在源代码中键入的字符串字面值,例如wstring str {L"åäö"};
。
案例2:通过标准输入流(本例中为wcin
)输入的字符串。
这两种情况不一定以相同的方式存储字符串。我知道unicode是一个字符集,而utf-8是一种编码,所以我更想知道的是字符串字面值在存储在内存中时是否被编码,在这种情况下如何编码。
此外,如果有人知道如何自动识别当前终端中使用的编码,那就太好了。
BR帕特里克•
编辑
我得到了一些评论,尽管其中一些是好的,但与问题并不完全相关。这意味着这个问题可能需要一些澄清。
这个问题可以看作是对那个表述很差的问题的概括:"我可以假设字符串字面值与它们的unicode pointcode一起存储在内存中吗?"
这个问题表述得很糟糕,至少有两个原因。首先,它假设字符串字面值是如何存储的(使用它们的unicode码点)。这意味着答案必须与unicode相关,即使这种关系可能完全没有意义。此外,这个问题是一个"是"或"否"类型的问题,如果答案是"否",它将没有任何帮助。
我也明白,这可以测试转换代码点到它的整数等效并打印它,但这将要求我测试它对整个unicode字符集(这似乎是一个不合理的方式这样做)。
首先,将文件解释为字符序列的方式是实现定义的。您必须参考您的编译器文档来确定。
其次,所使用的字符集也是实现定义的。所以你还是要咨询你的编译器
当您插入非ascii字符(也可能使用ascii)时,编译器可能会以不同的方式解释它们。您必须检查不同的编译器实际上可以处理相同的编码,最可能移植工作的源编码是UTF-8。
此外,也许你最好在程序的大部分使用utf -8编码的文本(只有在需要wchar_t的API附近才需要以这种方式处理字符串)。
底线。确保您的编译器逐字存储字符串文字并使用普通(窄)字符串,并使用以UTF-8编码保存的编辑器。
在string_literal
页面中有关于这个主题的很好的背景
我在这个问题上着陆不是字节和编码存储的问题,而是关于它们在内存中的位置,这是在应用程序的静态内存:
字符串字面值具有静态存储时间,因此在程序的整个生命周期中都存在于内存中。
- 将字符串存储在c++中的稳定内存中
- 类型总是使用其大小存储在内存中吗
- 使用无符号字符数组有效存储内存
- 具有内存顺序的原子负载存储
- CertGetCertificateChain 具有支持的内存存储和证书信任列表
- 为什么 bool 和 _Bool 如果它们在内存中占用 1 个字节,它们只能存储 0 或 1
- 具有相同特征的两个对象是否只在内存中存储一次?无论定义它们的函数是什么,都是不同的
- 存储在哪个内存段(代码/数据段)类(员工)中?
- 可用存储空间会消耗更多剩余内存吗?
- 是否可以仅通过将分配的指针地址存储在C++中来分析内存?
- 将数据存储在内存中以供以后访问
- 英特尔将指令存储在重叠的内存区域
- 整数数据如何以位为单位存储在内存中?不是右对齐吗?
- std::set 是否将对象连续存储在内存中?
- 原子加载和存储与内存顺序放宽
- 我应该以字符形式存储数字以节省内存吗?
- std::unordered_set 中的元素如何存储在C++内存中?
- 是否可以更早地销毁对象,使其存储内存被后续对象重用
- SSE加载/存储内存事务
- 在类- c++中存储内存内容