Как добавить символ к строковому литералу в C

Итак, я видел, что некоторые люди не рекомендуют использовать литералы String для создания символа в C. Однако я обнаружил, что это самый полезный метод, и у меня есть набор символов как

char a[] = "456";

Я так понимаю, что в этом типе данных фиксируется память. Однако в моем задании я считаю, что мне нужно перераспределить память для моего значения char, поскольку я добавляю целые числа, которые представлены в виде строк. Например:

char b[] = "500";
char c[] = "501";
//add function for adding b and c. have a char d[] equal to "1000". 

Для этого я использую длинное сложение. Я пробовал экспериментировать с функцией realloc, но это не сработало. Как бы я постоянно добавлял новые символы в строку?


person Hard_Programmer    schedule 10.02.2019    source источник
comment
Возможно, вы можете собрать минимально воспроизводимый пример, чтобы мы могли увидеть, что вы пытаетесь сделать.   -  person Retired Ninja    schedule 10.02.2019
comment
Полезным свойством сложения является то, что сумма двух чисел имеет не более чем на одну цифру больше, чем большее из двух слагаемых.   -  person user3386109    schedule 10.02.2019
comment
Если вы пытаетесь использовать realloc для массива, ожидается, что это не сработает. Вы не можете перераспределить массив.   -  person William Pursell    schedule 10.02.2019
comment
stackoverflow.com/questions/10279718/append- char-to-string-in-c   -  person Islam Mustafa    schedule 10.02.2019
comment
Как указал Уильям, на самом деле в char a[] = "456" не создаются строковые литералы, строковый литерал является инициализатором массива a.   -  person stensal    schedule 10.02.2019
comment
Функция realloc() работает, если используется правильно; его не особенно сложно использовать правильно, хотя очень легко использовать его неправильно. Лучшее описание было бы таким: я пробовал экспериментировать с функцией realloc(), но не смог понять, как правильно ее использовать.   -  person Jonathan Leffler    schedule 10.02.2019
comment
@JonathanLeffler, я считаю, что он не может использовать realloc, если он настаивает на использовании char a[] = "456"; для объявления хранилища. Насколько я понимаю, realloc может перераспределять только хранилище, выделенное в куче. Поправьте меня если я ошибаюсь.   -  person stensal    schedule 10.02.2019
comment
@stensal — ваше право, что одним из шагов будет проверка размещения данных; один из простых способов неправильного использования realloc() состоит в том, чтобы попытаться realloc() использовать память, которая ранее не была выделена. Решение с использованием realloc() и друзей потребует тщательной переработки кода. Тем не менее, это можно было сделать; realloc() не сломан.   -  person Jonathan Leffler    schedule 10.02.2019


Ответы (2)


Для вашего назначения вы должны определить целевой массив с достаточным пространством для хранения результата, который для добавления легко определить: это длина самого длинного аргумента плюс один символ для возможной дополнительной цифры плюс один символ для завершающего нуля. .

Вы можете выделить этот массив с помощью malloc() и вернуть указатель.

Вот пример:

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

char *bigadd(const char *a, const char *b) {
    size_t alen = strlen(a);
    size_t blen = strlen(b);
    size_t clen = (alen > blen) ? alen : blen;
    size_t mlen = (alen > blen) ? blen : alen;
    char *c = malloc(clen + 2);
    if (c != NULL) {
        size_t i;
        int carry = 0;
        c[clen] = '\0';
        for (i = 1; i <= mlen; i++) {
            carry += a[alen - i] - '0' + b[blen - i] - '0';
            c[clen - i] = '0' + carry % 10;
            carry /= 10;
        }
        for (; i <= alen; i++) {
            carry += a[alen - i] - '0';
            c[clen - i] = '0' + carry % 10;
            carry /= 10;
        }
        for (; i <= blen; i++) {
            carry += b[blen - i] - '0';
            c[clen - i] = '0' + carry % 10;
            carry /= 10;
        }
        if (carry) {
            memmove(c + 1, c, clen + 1);
            c[0] = (char)('0' + carry);
        }
    }
    return c;
}

int main(int argc, char *argv[]) {
    const char *a = argc > 1 ? argv[1] : "123456890123456890123456890";
    const char *b = argc > 2 ? argv[2] : "2035864230956204598237409822324";
    char *c = bigadd(a, b);
    printf("%s + %s = %s\n", a, b, c);
    free(c);
    return 0;
}
person chqrlie    schedule 10.02.2019

поэтому я вижу это, набрав:

char a[] = "456";

вы инициализируете массив символов размером 4 (3 символа + '\ 0'). сохранение чего-либо более длинного в том же массиве может привести к неопределенному поведению, и этого следует избегать. Короче говоря: вы можете изменить значение этого массива, если его размер не изменится. Вы можете инициализировать массив следующим образом:

char a[100] = "456";

чтобы оставить дополнительное пространство для любых возможных дополнений к строке, но это все, поскольку размер массива известен при компиляции и никогда не меняется. также обратите внимание, что это не будет работать:

char * a = "456";

это строковый литерал, доступный только для чтения, который нельзя изменить или перераспределить.

PS: я новичок, поправьте меня, если я не прав!

person Duck Ling    schedule 10.02.2019