C++ 内存中字符串表示差异在map::at()中引发错误

C++ 内存中字符串表示差异在map::at()中引发错误,c++,string,c++11,memory,gdb,C++,String,C++11,Memory,Gdb,当字符串填充构造函数创建s时,调用strRom\u map\u intAra.at时,我遇到一个超出范围的异常(请参见#5) 当我声明并初始化一个字符串时,它返回预期值。使用GDB,我可以看到两种不同方法的值的实现方式似乎有所不同:s=“\001I”。。。test=“I”当c='I' 这是字符串表示法还是map::at()方法的问题?如果这两个变量都是字符串,那么为什么它们的实现细节很重要呢 // Roman_int.cpp // Roman Constants extern const int

当字符串填充构造函数创建
s
时,调用
strRom\u map\u intAra.at
时,我遇到一个超出范围的异常(请参见#5)

当我声明并初始化一个字符串时,它返回预期值。使用GDB,我可以看到两种不同方法的值的实现方式似乎有所不同:
s=“\001I”。。。test=“I”
c='I'

这是字符串表示法还是
map::at()
方法的问题?如果这两个变量都是字符串,那么为什么它们的实现细节很重要呢

// Roman_int.cpp
// Roman Constants
extern const int M = 1000;
extern const int CM = 900;
extern const int D = 500;
extern const int CD = 400;
extern const int C = 100;
extern const int XC = 90;
extern const int L = 50;
extern const int XL = 40;
extern const int X = 10;
extern const int IX = 9;
extern const int V = 5;
extern const int IV = 4;
extern const int I = 1;

extern const unordered_map<string, int> strRom_map_intAra
{
    {"M",M},
    {"CM",CM},
    {"D",D},
    {"CD",CD},
    {"C",C},
    {"XC",XC},
    {"L",L},
    {"XL",XL},
    {"X",X},
    {"IX",IX},
    {"V",V},
    {"IV",IV},
    {"I",I}
};

istream& operator>>(istream& is, Roman_int& r)
{
    // throw exception if stream bad()
    is.exceptions(is.exceptions()|ios_base::badbit);

    string romStr;
    get_contig_str(is,romStr);
    vector<int> intRoms;
    for (char c : romStr)
    {
            string s{1,c};
            string test = "I";
            intRoms.push_back(strRom_map_intAra.at(s));
    }
//...

// GDB Snippit
142             for (char c : romStr)
(gdb)
144                     string s{1,c};
(gdb) print c
$1 = 73 'I'
(gdb) n
145                     string test = "I";
(gdb) print s
$2 = "\001I"
(gdb) n
146                     intRoms.push_back(strRom_map_intAra.at(s));
(gdb) print test
$3 = "I"
//Roman_int.cpp
//罗马常数
外部常数int M=1000;
外部常数int CM=900;
外部常数int D=500;
外部常数int CD=400;
外部常数int C=100;
外部常数int XC=90;
外部常数int L=50;
外部常数int XL=40;
外部常数int X=10;
外部常数int IX=9;
外部常数INTV=5;
外部常数int IV=4;
外部常数int I=1;
外部常数无序图结构图内部
{
{“M”,M},
{“CM”,CM},
{“D”,D},
{“CD”,CD},
{“C”,C},
{“XC”,XC},
{“L”,L},
{“XL”,XL},
{“X”,X},
{“IX”,IX},
{“V”,V},
{“IV”,IV},
{“I”,I}
};
istream&operator>>(istream&is,Roman_int&r)
{
//如果流错误()则引发异常
is.exceptions(is.exceptions()| ios_base::badbit);
字符串romStr;
获得重叠染色体(is,romStr);
载体内含子;
for(字符c:romStr)
{
字符串s{1,c};
字符串测试=“I”;
引子。推回(在(s)处绘制地图);
}
//...
//GDB狙击手
142用于(字符c:romStr)
(gdb)
144串s{1,c};
(gdb)打印c
$1=73“I”
(gdb)n
145字符串测试=“I”;
(gdb)打印
$2=“\001I”
(gdb)n
146引子。推回(在(s)处绘制地图);
(gdb)打印测试
$3=“I”
总而言之:GDB显示
c='I',s{1,c}=“\001I”,test=“I”
strRom\u map\u intAra.at(s)
导致
超出范围
异常,而
测试

尝试使用

string s(1,c);
反而

string s{1,c};
请看下面的程序

#include <iostream>

int main()
 {
   std::string s1(1, 'I');
   std::string s2{1, 'I'};

   std::cout << "size s1: " << s1.size() << std::endl;
   std::cout << "size s2: " << s2.size() << std::endl;
 }
那是因为有

std::string s1(1, 'I');
如果使用给定大小(本例中为1)对字符串进行序列化,并使用给定字符初始化所有字符(
I
,本例中为),则调用构造函数

您可以使用字符列表对字符串进行序列化:

  • 值为1的字符(
    '\x01'

  • 和一个字符
    'I'

尝试使用

string s(1,c);
反而

string s{1,c};
请看下面的程序

#include <iostream>

int main()
 {
   std::string s1(1, 'I');
   std::string s2{1, 'I'};

   std::cout << "size s1: " << s1.size() << std::endl;
   std::cout << "size s2: " << s2.size() << std::endl;
 }
那是因为有

std::string s1(1, 'I');
如果使用给定大小(本例中为1)对字符串进行序列化,并使用给定字符初始化所有字符(
I
,本例中为),则调用构造函数

您可以使用字符列表对字符串进行序列化:

  • 值为1的字符(
    '\x01'

  • 和一个字符
    'I'