简体   繁体   English

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

[英]How to assign several different strings to a char* array

guys I was trying to put several different strings like these: 伙计们,我正在尝试输入以下几个不同的字符串:

cap
to
cat
card
two
too
up
boat
boot

into a char* array like this: 变成一个char *数组,如下所示:

char* result[9]

and after assigning every one of those strings into the array with a for loop, I found that all the elements in the array is the same, which is "boot". 在使用for循环将所有这些字符串分配给数组后,我发现数组中的所有元素都是相同的,即“ boot”。

My code and result are down here: 我的代码和结果在这里:

#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
}

This line works well, 这条线很好用,

 cout<<result[counter]<<endl;//correct

and it prints all the different words like: 并打印所有不同的词,例如:

cap
to
cat
card
two
too
up
boat
boot

but somehow, this line 但不知何故,这条线

 cout<<result[counter]<<endl;//false 

it only prints "boot" nine times. 它只打印“启动”九次。 I really can't see the reason here and I am hoping you guys can give me a hand, thx! 我真的看不到这里的原因,希望你们能帮帮我,谢谢!

{
    string temp;
    getline(cin,temp);
    result[counter]=(char*) temp.c_str();   /* 1 */
    cout<<result[counter]<<endl;//correct
}  /* 2 */

In the line marked 1 , you're storing a pointer to the underlying string data of temp in result[counter] . 在标记为1的行中,您将一个指向temp的基础字符串数据的指针存储在result[counter] None of the string contents are copied; 没有字符串内容被复制; you're just storing the address of the existing data in temp . 您只是将现有数据的地址存储在temp (By the way, what is the (char*) cast for? .c_str() already returns a pointer to char .) (顺便说一下, .c_str()(char*)是什么.c_str()已经返回了一个指向char的指针。)

In the line marked 2 , temp is destroyed (it was a local variable in this block). 在标记为2的行中, temp被销毁(这是该块中的局部变量)。 Now result[counter] contains an invalid pointer: The object it was pointing to doesn't exist anymore. 现在, result[counter]包含无效的指针:指向的对象不再存在。

Any attempt to use the contents of result after this result in undefined behavior. 在此之后尝试使用result的内容会result未定义的行为。

One way you could fix this is to use an array of strings instead of an array of pointers: 解决此问题的一种方法是使用字符串数组而不是指针数组:

string result[9];
for(int counter=0;counter<9;counter++)
{
    getline(cin,result[counter]);
    cout<<result[counter]<<'\n';
}

(I've also removed endl because there is no need to explicitly flush the stream after every single string.) (我也删除了endl因为不需要在每个字符串之后显式刷新流。)

This also simplifies the code a bit because you no longer need a temp variable: You can just getline directly into the array. 这也简化了代码,因为您不再需要temp变量:您只需将getline直接插入数组即可。

Better yet use std::vector<string> 最好还是使用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);
}

If you want to use pointers, you need to copy the contents of str.c_str() as it is a temp that is destroyed after each iteration. 如果要使用指针,则需要复制str.c_str()的内容,因为它是一个临时变量,每次迭代后都会被销毁。

There is a problem with your code and specifically with this line: 您的代码有问题,尤其是以下代码行:

result[counter]=(char*) temp.c_str();

Since temp lives within the for loop and c_str() returns an address that will be invalid once temp is destructed, your code suffers from UB. 由于temp存在于for循环中,并且c_str()返回的地址一旦temp被破坏将是无效的,因此您的代码将遭受UB的困扰。 The address is invalid because c_str() : 该地址无效,因为c_str()

Returns a pointer to the underlying array serving as character storage. 返回指向用作字符存储的基础数组的指针。

Once temp is out of scope, that underlying array is gone, but you now have a reference to it outside its scope! 一旦temp超出范围,该基础数组就消失了,但是您现在可以在其范围之外对其进行引用!

You should allocate new memory for each of the string in result maybe using strdup as in the following: 你应该为每个在字符串分配新的内存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;
}

Do not forget that strdup will allocate memory that needs to be deallocated manually. 不要忘记strdup将分配需要手动释放的内存。

In following loop you are declaring temp string and using it again and again. 在以下循环中,您将声明临时字符串并一次又一次地使用它。 so in each iteration of the loop, same pointer is being edited. 因此在循环的每次迭代中,都将编辑相同的指针。 hence the last value stays and rest are overwritten. 因此,最后的值保持不变,其余值被覆盖。

for(int counter=0;counter<9;counter++)
   {
        string temp;
        getline(cin,temp);
        result[counter]=(char*) temp.c_str();
        cout<<result[counter]<<endl;//correct
    }

Instead declare your temp string outside as a string array with capacity of 9. 相反,将您的临时字符串声明为容量为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
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM