如何将几个不同的字符串分配给char *数组

时间:2019-04-05 09:30:40

标签: c++

伙计们,我试图放入几个不同的字符串,如下所示:

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 

它仅打印“启动”九次。我真的看不到这里的原因,我希望你们能帮帮我,谢谢!

4 个答案:

答案 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
}