将第一个 k 的元素从一个字符串复制到一个新字符串

Copy first k's element from one string to a new string

char p[5] = "thks";
string str1(&p[0], &p[strlen(p)]); 
cout<<str1<<endl;

char *p = "thks";
string ptr(p, p+strlen(p));
cout<<str1<<endl;

上面的代码是正确的 return "thks" 在 运行ning 之后,它从 p 开始到结束的所有字符复制到 str1;

string p1 ="thks";
string str2(p1[0],p1[p1.length()]);
cout<<str2<<endl;

当我尝试按照代码1的格式编写代码2实现将第一个k的元素从一个字符串复制到一个新字符串时,上面的代码导致运行时间错误,我没看懂为什么。

我怎样才能让它正确?


感谢大家提出的所有宝贵意见和解决方案。

只是想总结一下,让其他人很容易从这里找到解决方案。

任务:将字符串 p1 的前 3 个元素复制到 str2

解决方案 1:(感谢 PeterSW 提到结束 i 运算符需要是最后一个元素之后的一个)

string p1 ="thks";
string str2(&p1[0],&p1[p1.length()-1]+1);

解决方案 2:

string p1 ="thks";
string str2 = p1.substr(0,3);

解决方案 3:

string p1 ="thks";
string str2(p1, 0, 3);
p1.length()

给出长度 4,但您想要最后一个索引为 3。

所以:

p1[p1.length()]

将尝试访问一个已通过的字符串结尾。这是一个未定义的行为,可能是您报告的 运行 时间错误。

当构造函数需要迭代器时,Aslo 'p1[0]' 将 return a 'char'。

如果你的目标是复制整个字符串,你最好使用复制构造函数:

string str2{p1};

但是:

str2(&p1[0],&p1[p1.length()-1]+1); 

如果您坚持使用基于迭代器的构造函数,应该可以工作。

我认为您一般都在滥用字符串构造函数(文档为 here)。看起来您正在尝试调用此特定表单:

string (const string& str, size_t pos, size_t len = npos);

因此,如果您只想将前 3 个字符从 str1 复制到 str2

,请稍微修改您的代码
string p1 ="thks";
string str2(p1, 0, 3);  //This means copy 3 characters starting from position 0
cout<<"p1 = "<<p1<<endl;
cout<<"str2 = "<<str2<<endl;

这让你:

p1 = thks
str2 = thk

您的第二个代码引发运行时错误,因为您让 std::string 为您管理内存。 调用 s[x] 时,它会检查 x 是否在范围内。

在第一段代码中,您传递了指向字符串开头和结尾的指针。

但是在第二段代码中您忘记了 & 符号来制作指针。要更改示例 2 以使其与示例 1 的工作方式相同:

string p1 ="thks";
string str2( & p1[0], & p1[p1.length()]);
            ^^^      ^^^

但是,这仍然是一个错误:std::string没有空终止符,所以p1[p1.length()]进行了越界访问.解决此问题的一种方法是:

if ( p1.empty() )
    throw......;

string str2( &p1[0], &p1[0] + p1.length() );

当然,在实际代码中,您只需编写:

string str2( p1 );

这很简单,即使 p1 为空也能正常工作。