简体   繁体   English

将char *数组中的字符串分配给另一个char *数组

[英]Assigning a string in a char * array to another char * array

I am trying to convert the hex values in array a to binary values and assign converted values to array b then print the array b. 我试图将数组a中的十六进制值转换为二进制值,并将转换后的值分配给数组b,然后打印数组b。 But all values in array b are same. 但是数组b中的所有值都相同。 The output is: 输出为:

 111100001011000100010111101010001101 111100001011000100010111101010001101 111100001011000100010111101010001101 

If I use b[i] = strdup(hexToBin(a[i])); 如果我使用b[i] = strdup(hexToBin(a[i])); instead of b[i] = hexToBin(a[i]); 而不是b[i] = hexToBin(a[i]); the output will be: 输出将是:

 111100001011 111100001011000100010111 111100001011000100010111101010001101 

Is this something about pointers? 这与指针有关吗? Char * is a pointer which points first character of the string and are all characters after the pointer printed? 字符*是一个指针,它指向字符串的第一个字符,并且该指针后的所有字符都被打印吗? What is right way of doing this? 正确的做法是什么?

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

char bin[100] = "";

char * hexToBin(char  hex[50]);

int main(void) {

    char * a[] = {
        "f0b",
        "117",
        "a8d",
    };

    char * b[3];

    for(int i = 0; i < 3; i++) {
        b[i] = hexToBin(a[i]);
    }

    for(int i = 0; i < 3; i++) {
        printf("%s\n", b[i]);
    }

}

char * hexToBin(char  hex[50]) {    

    for(int i=0; hex[i]!='\0'; i++)
    {
        switch(hex[i])
        {
            case '0':
                strcat(bin, "0000");
                break;
            case '1':
                strcat(bin, "0001");
                break;
            case '2':
                strcat(bin, "0010");
                break;
            case '3':
                strcat(bin, "0011");
                break;
            case '4':
                strcat(bin, "0100");
                break;
            case '5':
                strcat(bin, "0101");
                break;
            case '6':
                strcat(bin, "0110");
                break;
            case '7':
                strcat(bin, "0111");
                break;
            case '8':
                strcat(bin, "1000");
                break;
            case '9':
                strcat(bin, "1001");
                break;
            case 'a':
            case 'A':
                strcat(bin, "1010");
                break;
            case 'b':
            case 'B':
                strcat(bin, "1011");
                break;
            case 'c':
            case 'C':
                strcat(bin, "1100");
                break;
            case 'd':
            case 'D':
                strcat(bin, "1101");
                break;
            case 'e':
            case 'E':
                strcat(bin, "1110");
                break;
            case 'f':
            case 'F':
                strcat(bin, "1111");
                break;
            default:
                printf("Invalid hexadecimal input.");
        }
    }
    return bin;
}

The hexToBin function returns a pointer to the first element of the global bin array. hexToBin函数返回一个指向全局bin数组第一个元素的指针。 Everytime! 每次! .

That means all pointers in b will be the very same pointer to the very same first element of the bin array. 这意味着b所有指针将是指向bin数组中相同的第一个元素的完全相同的指针。

If you know the maximum length of the strings, I recommend that you make b an array of arrays of char . 如果您知道字符串的最大长度,建议您将b组成char 数组 For example 例如

char b[3][500];  // 3 arrays of 499-character strings (+1 for the null-terminator)

Then instead of hexToBin returning a pointer to a single global array, pass a pointer to the string to be filled as argument to hexToBin : 然后,不将hexToBin返回指向单个全局数组的指针, hexToBin将指向要填充的字符串的指针作为hexToBin参数hexToBin

void hexToBin(char *hex, char *bin);

and call it as 并称其为

hexToBin(a[i], b[i]);

You only have one bin . 您只有一个bin What your hexToBin does is appending to that one bin and then returning that bin . 您的hexToBin所做的是将其附加到该bin ,然后返回该bin In other words, when you call it multiple times, the result is always the same pointer, because you always return bin; 换句话说,当您多次调用它时,结果始终是相同的指针,因为您总是return bin; .

So if you do this: 因此,如果您这样做:

b[i] = hexToBin(a[i]);

Then in the end, all elements of b are pointing to bin , that's why you get the same output when you print them. 最后, b所有元素都指向bin ,这就是为什么在打印它们时会得到相同的输出。 If you do this instead: 如果您改为这样做:

b[i] = strdup(hexToBin(a[i]));

Then the result is not the same, because they all don't get bin assigned, but a copy of what bin has been at that time. 然后结果是不一样的,因为它们都没有分配bin ,而是当时有bin的副本。 That's why the results are different. 这就是为什么结果不同的原因。 So b[0] points to one copy, then bin is appended to again, but that doesn't change the b[0] copy. 因此, b[0]指向一个副本,然后将bin再次附加到该副本,但这不会更改b[0]副本。

If you use strdup , don't forget to free the memory it allocated: 如果使用strdup ,请不要忘记释放它分配的内存:

for(int i = 0; i < 3; i++) {
    free(b[i]);
}

[My answer is mistaken. [我的回答是错误的。 I leave it posted here for reference but the other answers are preferable.] 我将其保留在此处以供参考,但其他答案更可取。]

Your code looks pretty good for beginner's code and I like your style. 您的代码对于初学者的代码看起来相当不错,我喜欢您的风格。 I especially like this line: 我特别喜欢这条线:

    char * b[3];

Unfortunately, for this particular application, you must replace this with a less elegant line like 不幸的是,对于这个特定的应用程序,您必须用不太优雅的线条代替它,例如

    char b[3][5];

The former line reserves no storage for your output. 前一行不会为您的输出保留任何存储空间。 The latter line reserves five bytes per hex digit. 后一行每十六进制保留五个字节。 You need storage, somehow. 您需要某种方式的存储空间。

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

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