如何将字符串文字存储在内存中以供c ++使用?

时间:2015-10-16 06:15:15

标签: c++ c++11 xcode6 osx-mavericks string-literals

我有一个关于如何在c ++的内存中存储字符串文字的问题。我知道根据他们的ascii代码存储char,但我更喜欢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的术语实际上会挂起。可以修改wcin流以假设C编码wcin.imbue(std::locale());,它仍然在Xcode中提供相同的输出,但在OS X终端中给出以下内容:

Output:
Write something>> åäö
3
ŒŠš

所以问题与编码有很明显的关系。所以我想知道字符串文字实际上是如何在c ++中存储在内存中的。这可以分为两种不同的情况。

案例1:源代码中输入的字符串文字,例如wstring str {L"åäö"};

案例2:通过标准输入流(在这种情况下为wcin)输入的字符串。

这两种情况不一定以相同的方式存储字符串。我知道unicode是一个字符集,并且utf-8是一个编码,所以我想知道如果字符串文字在存储在内存中时被编码,那就更好了。

此外,如果有人知道如何以自动方式识别当前终端中使用的编码,那就太棒了。

BR 帕特里克

修改

我得到一些评论,即使其中一些是好的,但与这个问题并不完全相关。这意味着这个问题可能需要一些澄清。这个问题可以看作是一个相当不合理的问题的概括:

&#34;我可以假设字符串文字与其unicode点代码一起存储在内存中吗?&#34;

这个问题由于至少两个原因而制定得很糟糕。首先,它假设字符串文字是如何存储的(使用它们的unicode代码点)。这意味着答案必须与unicode相关,即使这种关系可能完全没有意义。此外,这个问题是肯定的或没有问题的类型,如果答案是否定的话,将不会提供任何帮助。

我也明白这可以测试将代码点转换为整数等价并打印它,但这需要我对整个unicode字符集进行测试(这似乎是一种不合理的方式)。 / p>

2 个答案:

答案 0 :(得分:1)

首先,将文件解释为字符序列的方式是实现定义的。您必须查阅编译器文档以确定这一点。

其次,使用的字符集也是实现定义的。所以,你必须再次咨询你的编译器。

插入非ascii字符时可能会发生什么(可能在使用ascii时),编译器会以不同的方式解释它们。你必须检查不同的编译器实际上可以处理相同的编码,最可能的源代码编码可以移植到UTF-8。

另外,也许你最好在程序的大部分时间内使用UTF-8编码的文本(只有接近需要wchar_t的API需要以这种方式处理字符串)。

底线。确保您的编译器逐字存储字符串文字并使用普通(窄)字符串,并使用以UTF-8编码保存的编辑器。

答案 1 :(得分:0)

trigger: - develop pool: vmImage: 'windows-latest' steps: - task: UseDotNet@2 displayName: 'Install .NET 5 SDK' inputs: packageType: 'sdk' version: '5.0.100' - task: DotNetCoreCLI@2 displayName: 'Publish using a specific publish profile' inputs: command: 'publish' publishWebProjects: false projects: 'SomeProject.Host/SomeProject.Host.csproj' arguments: '/p:PublishProfile=profile-name /p:Password=$(SomeSecretVariable)' zipAfterPublish: false modifyOutputPath: false 页上看到的关于此主题的背景很好

https://en.cppreference.com/w/cpp/language/string_literal

我提出的问题不是字节和编码存储问题,而是它们在内存中的位置,即应用程序的静态内存中的位置:

字符串文字具有静态的存储期限,因此在程序生命周期内存在内存中。