Как скопировать данные из строки в поля в структуре - PullRequest
0 голосов
/ 27 августа 2018

Я знаю, что этот код небрежный, я пытаюсь переучить строковые манипуляции в C. Если у меня есть строка ABBCCCD и я хочу сохранить отдельные буквы в структуре, есть ли эффективный способ сделать это? У меня есть код ниже, чтобы продемонстрировать длинный путь того, что я пытаюсь сделать. (Кроме того, мне нужно вручную добавлять нулевой терминатор, когда я делаю strncpy?)

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

typedef struct dst_struct {
    char a[2];
    char b[3];
    char c[4];
    char d[2];
} dst_struct_t;

int main(void) {
    char* test = "ABBCCCD";
    char* src = malloc(strlen(test)+1);
    strncpy(src, test, strlen(test)+1);
    printf("%s\n", src);

    dst_struct_t dst;

    strncpy(dst.a, src,  1);
    strncpy(dst.b, src+1, 2);
    strncpy(dst.c, src+3, 3);
    strncpy(dst.d, src+6, 1);


    printf("dst.a: %s\n", dst.a);
    printf("dst.b: %s\n", dst.b);
    printf("dst.c: %s\n", dst.c);
    printf("dst.d: %s\n", dst.d);

    free(src);


}

Ответы [ 2 ]

0 голосов
/ 27 августа 2018

Из справочной страницы strcpy / strncpy:

char * strcpy (char * dest, const char * src);

char * strncpy (char * dest, const char * src, size_t n);

Функция strcpy () копирует строку, на которую указывает src, , включая завершающий нулевой байт ('\ 0') , в буфер, на который указывает dest. Строки могут не перекрываться, и строка назначения dest должна быть достаточно большой, чтобы получить копию. Остерегайтесь переполнения буфера! (См. ОШИБКИ.)

Функция strncpy () аналогична, за исключением того, что копируется не более n байтов src. Предупреждение: если среди первых n байтов src нет нулевого байта, строка, помещенная в dest, не будет заканчиваться нулем.

Аргумент n strncpy обычно подразумевает длину буфера назначения, так как точка функции должна быть такой же, как strcpy, но предотвращает переполнение буфера назначения, если строка источника слишком длинная или не заканчивается NULL. Если используется таким образом, ваша строка назначения будет заканчиваться NULL, если исходная строка соответствует этой длине, в противном случае последний байт буфера будет содержать n -й символ исходной строки.

Однако вы, похоже, используете strncpy, чтобы установить точное количество символов, которые вы хотите скопировать из исходного буфера для помещения в целевой буфер. Это не совсем намеченная цель strncpy. Вместо этого вам нужно использовать memcpy, поскольку вы на самом деле не озабочены нулевым окончанием исходной строки, а просто копируете заданное количество символов из заданного местоположения. И да, вам придется вручную добавить нулевой терминатор, если вы используете memcpy.

0 голосов
/ 27 августа 2018

Нет лучшего способа сделать это, кроме того, что вам не нужно сначала копировать test в src.

Вам также необходимо добавить нулевые терминаторы ко всем строкам. Вероятно, было бы лучше написать функцию, которая выполняет оба шага: strncpy() и добавление нулевого терминатора.

function copy_n(char *dest, char *src, size_t offset, size_t len) {
    strncpy(src+offset, dest, len);
    dest[len] = '\0';
}

int main(void) {
    char* test = "ABBCCCD";

    copy_n(dst.a, test, 0, 1);
    copy_n(dst.b, test, 1, 2);
    copy_n(dst.c, test, 3, 3);
    copy_n(dst.d, test, 6, 1);

    printf("dst.a: %s\n", dst.a);
    printf("dst.b: %s\n", dst.b);
    printf("dst.c: %s\n", dst.c);
    printf("dst.d: %s\n", dst.d);
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...