简体   繁体   English

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

[英]copy or assign one string to another string in a 2 dimensional array of pointers

First of all, this is a test program, i wanna test something specific that i wanted to see if it works. 首先,这是一个测试程序,我想测试一些特定的东西,我想看看它是否有效。 Lets say that i wanna assign x to arr[0][4] and wanna keep this change so that arr[0][4] is x in the main function too: 让我们说我想将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;
}

The problem is that i cant assign x to arr[0][4], the program just shuts down. 问题是我不能将x分配给arr [0] [4],程序就会关闭。 I also tried strcpy, this: 我也试过strcpy,这个:

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

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

Its the same thing with strcpy the program just shuts down. 与strcpy一样,程序刚刚关闭。 I can only do this: 我只能这样做:

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

Which doesnt help me at all, considering that x is a string that i dont know(or a string from scanf). 考虑到x是一个我不知道的字符串(或者来自scanf的字符串),这对我没有任何帮助。 So if x comes from a scanf how can i assign x to arr[0][4]? 因此,如果x来自scanf,我如何将x分配给arr [0] [4]? Any help would be appreciated! 任何帮助,将不胜感激! Thanks :) 谢谢 :)

This method 这种方法

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

doesn't work because you are assigning a variable with automatic storage (aka "local") duration. 不起作用,因为您正在分配一个具有自动存储(也称为“本地”)持续时间的变量。 Once the function returns, it doesn't exist anymore. 函数返回后,它就不再存在了。 This is undefined behaviour . 这是未定义的行为

This method 这种方法

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

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

doesn't work because the arr[0][4] is pointing to a string literal. 不起作用,因为arr[0][4]指向字符串文字。 You can't modify a string literal. 您无法修改字符串文字。 Again, this is undefined behaviour . 同样,这是未定义的行为

This method 这种方法

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

is the only correct way if you only have pointers and not allocated any memory for the pointees of those pointers. 如果你只有指针而没有为那些指针的指针分配任何内存,那么这是唯一正确的方法。

So if x comes from a scanf how can i assign x to arr[0][4]? 因此,如果x来自scanf,我如何将x分配给arr [0] [4]?

For such scenario, you need to allocate memory and assign it to arr[0][4] . 对于这种情况,您需要分配内存并将其分配给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()
}

This is quite messy though. 虽然这很麻烦。 The array has pointers to string literals. 该数组具有指向字符串文字的指针。 But just arr[0][4] is pointing to a malloc'ed memory. 但只是arr[0][4]指向一个malloc的记忆。 You need to track such pointers if you want to be able to modify it or later when you call free() on it. 如果您希望能够修改它,或者稍后在调用free()时需要跟踪这些指针。

I would suggest you use just arrays instead of arrays of pointers if you want to be able to modify them as it's hard to keep track various pointers that are malloc'ed and with rest of them pointing at string literals. 如果你想能够修改它们,我建议你只使用数组而不是指针数组,因为很难跟踪各种指向malloc的指针,其余指针指向字符串文字。

In the first function example that fails, you are trying to copy an automatic string variable to a string literal , which is read-only. 在第一个失败的函数示例中,您尝试将自动字符串变量复制到字符串文字 ,该文字是只读的。 That's why the function fails. 这就是函数失败的原因。 arr[0][4] is a pointer to a string literal . arr[0][4]是一个指向字符串文字的指针。

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

But in the second example that succeeds, you assign a string literal pointer directly (as you did in the first initialisation). 但是在成功的第二个示例中,您直接分配了一个字符串文字指针(就像您在第一次初始化时所做的那样)。

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

As an aside, note the difference between 另外,请注意两者之间的区别

char name[] = "Alex";

and

char *name = "Alex";

In the first case, name is initialised with a copy of the data given, and it is modifiable. 在第一种情况下, name使用给定数据的副本进行初始化,并且可以修改。

In the second case, all name knows is a pointer, and the text it points to (a "string literal") is not modifiable. 在第二种情况下,所有name知道是一个指针,它指向的文本(“字符串文字”)是不可修改的。

All the elements of arr are pointers to char . arr所有元素都是char指针。 You initialized them in main , no memory is allocated. 你在main初始化它们,没有分配内存。 They just point to string literals. 他们只是指向字符串文字。

The first version of changeE changeE的第一个版本

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

doesn't work because x is an automatic local variable and returning pointer to it leads to undefined behavior. 不起作用,因为x是一个自动局部变量,返回指向它的指针会导致未定义的行为。

In function 在功能上

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

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

strcpy wouldn't work because arr[0][4] is pointing to a string literal and it can't be modified. strcpy不起作用,因为arr[0][4]指向字符串文字并且无法修改。 You can modify arr[0][4] by allocating space for it 你可以通过为它分配空间来修改arr[0][4]

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

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

At first, you should initialize your array arr , so that, it contains no invalid pointers: 首先,你应该初始化你的数组arr ,这样它就不包含无效的指针:

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

Your first implementation of changE does not work because char x[50] is a local variable (allocated on the stack) initialized to "Tinky". 你的第一个changE实现不起作用,因为char x[50]是一个初始化为“Tinky”的局部变量(在堆栈上分配)。 You cannot excess this variable (by derefencing the pointer) once the function returns. 一旦函数返回,你不能超过这个变量(通过derefencing指针)。

The implementation using strcpy does not work, because the destination memory is the string literal "Douglas" (as assigned in main ) which cannot be overriden. 使用strcpy的实现不起作用,因为目标内存是字符串文字“Douglas”(在main指定),无法覆盖。

The pointer assignment from the first implementation is just fine, but you have to allocate memory from the heap as in this scanf example: 来自第一个实现的指针分配很好,但您必须像在此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;
}

String literals have static storage duration. 字符串文字具有静态存储持续时间。 So these assignments 所以这些任务

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";

or this assignment in function changE 或者在函数changE这个赋值

arr[0][4] = "Tinky";

are coorect. 是coorect。

However you want to assign an element of the array with address of some character array that you are going to enter. 但是,您希望为数组分配一个您要输入的某个字符数组的地址。 In this case the storage duration of the array should be at least the same as the storage duration of the two-dimensional array. 在这种情况下,阵列的存储持续时间应至少与二维阵列的存储持续时间相同。

The only reasonable approach is to dynamically allocate memory for readable characters and store their addresses in elements of the two-dimensional array. 唯一合理的方法是为可读字符动态分配内存并将其地址存储在二维数组的元素中。

You could use POSIX function strdup to do this. 您可以使用POSIX函数strdup来执行此操作。 For example 例如

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" );

Or you could write such a function yourself. 或者你可以自己编写这样的功能。

In this case you have to use also standard C function free to free all allocated memory by strdup or similar function. 在这种情况下,您还必须使用标准C函数free来通过strdup或类似函数释放所有已分配的内存。

The same approach should be used in the function changE 在函数changE应该使用相同的方法

For example 例如

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

A possible solution is to have character arrays instead of pointers to characters like below. 一种可能的解决方案是使用字符数组而不是指向下面的字符的指针。 The strings' maximum length is 50 in this example. 在此示例中,字符串的最大长度为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]);
}

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

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