Присвоение строки в массиве char * другому массиву char * - PullRequest
2 голосов
/ 15 марта 2019

Я пытаюсь преобразовать шестнадцатеричные значения в массиве a в двоичные значения и назначить преобразованные значения в массив b, а затем распечатать массив b. Но все значения в массиве b одинаковы. Выход:

111100001011000100010111101010001101
111100001011000100010111101010001101
111100001011000100010111101010001101

Если я использую b[i] = strdup(hexToBin(a[i])); вместо b[i] = hexToBin(a[i]);, вывод будет:

111100001011
111100001011000100010111
111100001011000100010111101010001101

Это что-то про указатели? Char * - это указатель, который указывает первый символ строки и все ли символы после указателя напечатаны? Как правильно это сделать?

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

Ответы [ 3 ]

3 голосов
/ 15 марта 2019

Функция hexToBin возвращает указатель на первый элемент глобального массива bin. Everytime! .

Это означает, что все указатели в b будут одинаковыми указателями на один и тот же первый элемент массива bin.

Если вызнаю максимальную длину строк, я рекомендую сделать b массивом массивов из char.Например,

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

Тогда вместо hexToBin, возвращающего указатель на один глобальный массив, передайте указатель на строку, которая будет заполнена в качестве аргумента, на hexToBin:

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

и назовите это как

hexToBin(a[i], b[i]);
2 голосов
/ 15 марта 2019

У вас есть только один bin. То, что делает ваш hexToBin, добавляет к этому bin, а затем возвращает bin. Другими словами, когда вы вызываете его несколько раз, результатом всегда будет один и тот же указатель, потому что вы всегда return bin;.

Итак, если вы сделаете это:

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

Затем, в конце концов, все элементы b указывают на bin, поэтому вы получаете одинаковый вывод при их печати. Если вы сделаете это вместо:

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

Тогда результат не тот, потому что все они не получают bin, а копию того, что было bin в то время. Вот почему результаты разные. Таким образом, b[0] указывает на одну копию, затем к ней добавляется bin, но это не меняет копию b[0].

Если вы используете strdup, не забудьте освободить выделенную память:

for(int i = 0; i < 3; i++) {
    free(b[i]);
}
1 голос
/ 15 марта 2019

[Мой ответ ошибочен. Я оставляю это здесь для справки, но другие ответы предпочтительнее.]

Ваш код выглядит неплохо для кода новичка, и мне нравится ваш стиль. Мне особенно нравится эта строка:

    char * b[3];

К сожалению, для этого конкретного приложения вы должны заменить его на менее элегантную строку, такую ​​как

    char b[3][5];

В предыдущей строке нет места для хранения вашей продукции. Последняя строка резервирует пять байтов на шестнадцатеричную цифру. Вам как-то нужно хранилище.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...