将一个字符串复制或分配给二维指针数组中的另一个字符串

时间:2016-01-02 22:01:26

标签: c arrays string char variable-assignment

首先,这是一个测试程序,我想测试一些特定的东西,我想看看它是否有效。让我们说我想将x分配给arr [0] [4]并想保持这个变化,以便arr [0] [4]在主函数中也是x:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

void changE(char *arr[10][5]);

int main(void){
    char *arr[10][5];
    arr[0][0] = "Johny";
    arr[0][1] = "Tony";
    arr[0][2] = "Tiki";
    arr[0][3] = "Kitty";
    arr[0][4] = "Douglas";
    arr[1][0] = "Piki";
    arr[1][1] = "Kati";
    arr[1][2] = "Sathi";
    arr[1][3] = "Dony";
    changE(arr);
    int i = 0;
    int j;
    for(i;i<=1;i++){
        for(j=0;j<=4;j++){
            printf("%s\n", arr[i][j]);
        }
        printf("\n\n\n");
    }
    return 0;
}
void changE(char *arr[10][5]){
    char x[50] = "Tinky";
    arr[0][4] = x;
}

问题是我无法将x分配给arr [0] [4],程序就关闭了。我也试过strcpy,这个:

void changE(char *arr[10][5]){

    char x[50] = "Tinky";
    strcpy(arr[0][4], x);
}

与strcpy一样,程序关闭了。 我只能这样做:

void changE(char *arr[10][5]){
    arr[0][4] = "Tinky";
}

考虑到x是一个我不知道的字符串(或来自scanf的字符串),这对我没有任何帮助。 因此,如果x来自scanf,我如何将x分配给arr [0] [4]?任何帮助,将不胜感激!谢谢:))

6 个答案:

答案 0 :(得分:4)

此方法

<div class="set">
  <span data-prefix="[1]">Duck</span>
  <span data-prefix="[2]">Dog</span>
  <span data-prefix="[3]">Cat</span>
  <span>Falcon</span>
  <span data-prefix="[4]">Parrot</span>
</div>

不起作用,因为您正在为自动存储(也称为“本地”)持续时间分配变量。函数返回后,它就不再存在了。这是未定义的行为

此方法

void changE(char *arr[10][5]){
    char x[50] = "Tinky";
    arr[0][4] = x;
}

不起作用,因为void changE(char *arr[10][5]){ char x[50] = "Tinky"; strcpy(arr[0][4], x); } 指向字符串文字。您无法修改字符串文字。同样,这是未定义的行为

此方法

arr[0][4]

是唯一正确的方法,如果你只有指针而没有为这些指针的指针分配任何内存。

  

因此,如果x来自scanf,我如何将x分配给arr [0] [4]?

对于这种情况,您需要分配内存并将其分配给void changE(char *arr[10][5]){ arr[0][4] = "Tinky"; }

arr[0][4]

但这很麻烦。该数组具有指向字符串文字的指针。但只是void changE(char *arr[10][5]){ char x[40] = "Tinky"; arr[0][4] = strdup(x); //POSIX, equivalent std C would be malloc()+strcpy() } 指向一个malloc的记忆。如果您希望能够修改它,或者稍后在致电arr[0][4]时需要跟踪此类指针 在它上面。

我建议您只使用数组而不是指针数组,如果您希望能够修改它们,因为很难跟踪各种指向malloc的指针并且其余的指向它们在字符串文字。

答案 1 :(得分:1)

在失败的第一个函数示例中,您尝试将自动字符串变量复制到字符串文字,这是只读的。这就是函数失败的原因。 arr[0][4]是指向字符串文字的指针。

void changE(char *arr[10][5]){
    char x[50] = "Tinky";
    strcpy(arr[0][4], x);
}

但是在第二个成功的例子中,你直接指定一个字符串文字指针(正如你在第一次初始化时所做的那样)。

void changE(char *arr[10][5]){
    arr[0][4] = "Tinky";
}

另外,请注意

之间的区别
char name[] = "Alex";

char *name = "Alex";

在第一种情况下,name初始化为给定数据的副本,并且可以修改。

在第二种情况下,所有name都知道是一个指针,它指向的文本(“字符串文字”)可修改。

答案 2 :(得分:1)

.container{ height: 400px; width: 500px; border: 2px solid red; overflow: hidden } .container:hover img{ height: 500px; width: 600px; } 的所有元素都是指向arr的指针。您在char中初始化它们,没有分配内存。他们只是指向字符串文字。

main的第一个版本

changeE

不起作用,因为void changE(char *arr[10][5]){ char x[50] = "Tinky"; arr[0][4] = x; } 是一个自动局部变量,返回指向它的指针会导致未定义的行为。

在功能中

x

void changE(char *arr[10][5]){ char x[50] = "Tinky"; strcpy(arr[0][4], x); } 无效,因为strcpy指向字符串文字并且无法修改。您可以通过为其分配空间来修改arr[0][4]

arr[0][4]

答案 3 :(得分:1)

首先,您应该初始化数组arr,这样它就不包含无效指针:

char *arr[10][5] = {0};

changE的第一次实现不起作用,因为char x[50]是一个局部变量(在堆栈上分配),初始化为&#34; Tinky&#34;。一旦函数返回,你就不能超过这个变量(通过derefencing指针)。

使用strcpy的实现不起作用,因为目标内存是字符串文字&#34; Douglas&#34; (在main中指定),无法覆盖。

第一个实现的指针分配很好,但你必须从堆中分配内存,如scanf示例所示:

void changE(char *arr[10][5]){
    char *x = (char *)malloc(100 * sizeof *x);
    if(!x) exit(1); // error handling
    scanf("%99s", x);
    arr[0][4] = x;
}

答案 4 :(得分:1)

字符串文字具有静态存储持续时间。所以这些作业

arr[0][0] = "Johny";
arr[0][1] = "Tony";
arr[0][2] = "Tiki";
arr[0][3] = "Kitty";
arr[0][4] = "Douglas";
arr[1][0] = "Piki";
arr[1][1] = "Kati";
arr[1][2] = "Sathi";
arr[1][3] = "Dony";

或函数changE

中的此赋值
arr[0][4] = "Tinky";

是coorect。

但是,您希望为数组分配一个您要输入的某个字符数组的地址。 在这种情况下,阵列的存储持续时间应至少与二维阵列的存储持续时间相同。

唯一合理的方法是为可读字符动态分配内存,并将其地址存储在二维数组的元素中。

您可以使用POSIX函数strdup来执行此操作。 例如

arr[0][0] = strdup( "Johny" );
arr[0][1] = strdup( "Tony" );
arr[0][2] = strdup( "Tiki" );
arr[0][3] = strdup( "Kitty" );
arr[0][4] = strdup( "Douglas" );
arr[1][0] = strdup( "Piki" );
arr[1][1] = strdup( "Kati" );
arr[1][2] = strdup( "Sathi" );
arr[1][3] = strdup( "Dony" );

或者你可以自己编写这样的功能。

在这种情况下,您还必须使用标准C函数free来释放strdup或类似函数所有已分配的内存。

在函数changE

中应该使用相同的方法

例如

void changE(char *arr[10][5]){
    char x[50] = "Tinky";
    arr[0][4] = malloc( strlen( x ) + 1 );
    strcpy(arr[0][4], x);
}

答案 5 :(得分:0)

一种可能的解决方案是使用字符数组而不是指向下面的字符的指针。在这个例子中,字符串的最大长度为50。

void changE(char arr[10][5][50]);

int main(void){

    char arr[10][5][50];

    //...

    strcpy(arr[0][0], "Johny");
    strcpy(arr[0][1], "Tony");

    //...
    changE(arr);
    //...
}
void changE(char arr[10][5][50]){
    //this works now
    char x[50] = "Tinky";
    strcpy(arr[0][4], x);

    //scanf works as usual
    scanf("%s", &arr[0][4]);
}
相关问题