伙计们,我试图放入几个不同的字符串,如下所示:
cap
to
cat
card
two
too
up
boat
boot
插入一个char *数组,如下所示:
char* result[9]
并使用for循环将所有这些字符串分配给数组后,我发现数组中的所有元素都是相同的,即“ boot”。
我的代码和结果在这里:
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
int main()
{
char* result[9];
for(int counter=0;counter<9;counter++)
{
string temp;
getline(cin,temp);
result[counter]=(char*) temp.c_str();
cout<<result[counter]<<endl;//correct
}
cout<<endl;
cout<<endl;
for(int counter=0;counter<9;counter++)
cout<<result[counter]<<endl;//false
}
此行效果很好
cout<<result[counter]<<endl;//correct
并打印所有不同的词,例如:
cap
to
cat
card
two
too
up
boat
boot
但是以某种方式,这一行
cout<<result[counter]<<endl;//false
它仅打印“启动”九次。我真的看不到这里的原因,我希望你们能帮帮我,谢谢!
答案 0 :(得分:3)
{
string temp;
getline(cin,temp);
result[counter]=(char*) temp.c_str(); /* 1 */
cout<<result[counter]<<endl;//correct
} /* 2 */
在标记为1
的行中,您正在将指向temp
的基础字符串数据的指针存储在result[counter]
中。没有字符串内容被复制;您只是将现有数据的地址存储在temp
中。 (顺便说一下,(char*)
强制转换为什么?.c_str()
已经返回了指向char
的指针。)
在标记为2
的行中,temp
被销毁(它是此块中的局部变量)。现在result[counter]
包含一个无效的指针:指向的对象不再存在。
任何尝试使用result
内容的操作都会导致不确定的行为。
解决此问题的一种方法是使用字符串数组而不是指针数组:
string result[9];
for(int counter=0;counter<9;counter++)
{
getline(cin,result[counter]);
cout<<result[counter]<<'\n';
}
(我也删除了endl
,因为不需要在每个字符串之后显式刷新流。)
这也简化了代码,因为您不再需要temp
变量:您可以直接将getline
放入数组。
答案 1 :(得分:1)
最好使用std::vector<string>
std::vector<std::string> result;
for(int counter=0;counter<9;counter++) {
std::string temp;
std::getline(std::cin, temp);
result.push_back(temp);
}
如果要使用指针,则需要复制str.c_str()的内容,因为它是一个临时变量,每次迭代后都会被破坏。
答案 2 :(得分:0)
您的代码有问题,尤其是以下一行:
result[counter]=(char*) temp.c_str();
由于temp
位于for循环中,并且c_str()
返回的地址一旦temp被破坏就将无效,因此您的代码将遭受UB的困扰。
该地址无效,因为c_str()
:
返回指向用作字符存储的基础数组的指针。
一旦温度超出范围,该基础数组就会消失,但是您现在可以在其范围之外引用它!
您应该为result
中的每个字符串分配新的内存,也许使用strdup
如下:
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
int main()
{
char* result[9];
for(int counter=0;counter<9;counter++)
{
string temp;
getline(cin,temp);
result[counter]=strdup(temp.c_str()); //now it is correct!
cout<<result[counter]<<endl;
}
cout<<endl;
cout<<endl;
for(int counter=0;counter<9;counter++)
cout<<result[counter]<<endl;
}
不要忘记strdup
将分配需要手动释放的内存。
答案 3 :(得分:0)
在下面的循环中,您声明临时字符串并一次又一次地使用它。因此在循环的每次迭代中,都将编辑相同的指针。因此,最后的值保持不变,其余的保持不变。
for(int counter=0;counter<9;counter++)
{
string temp;
getline(cin,temp);
result[counter]=(char*) temp.c_str();
cout<<result[counter]<<endl;//correct
}
相反,将您的临时字符串声明为容量为9的字符串数组。
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
int main()
{
char* result[9];
string temp[9];
for(int counter=0;counter<9;counter++)
{
getline(cin,temp[counter]);
result[counter]=(char*) temp[counter].c_str();
cout<<result[counter]<<endl;//correct
}
cout<<endl;
cout<<endl;
for(int counter=0;counter<9;counter++)
cout<<result[counter]<<endl;//false
}