typedef: когда я помещаю строки в структуру, верхняя переменная содержит строки нижних переменных в C

#c #typedef

#c #typedef

Вопрос:

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


typedef struct{
    char a[10];
    char b[1];
    char c[5];
    char d[8];
}T_TEMP_C;

int main()
{
    char* temp = "123456789012345678901234";
    T_TEMP_C* ltpa = (T_TEMP_C*) temp;


    printf("ltpa -> a : %sn", ltpa->a);
    printf("ltpa -> b : %cn", ltpa->b[0]);
    printf("ltpa -> c : %sn", ltpa->c);
    printf("ltpa -> d : %sn", ltpa->d);

    return 0;
}
  

Результаты

     ltpa -> a : 123456789012345678901234                                                                                                                                               
    ltpa -> b : 1                                                                                                                                                                      
    ltpa -> c : 2345678901234                                                                                                                                                          
    ltpa -> d : 78901234
  

Я не понимаю, почему это происходит.

почему символ a содержит всю строку, хотя размер a равен всего 10.

Я хочу содержать 1234567890 для a от 1 до b, 23456 для c и rest для d

Ответ №1:

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

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


typedef struct{
    char a[11];
    char b[1];
    char c[6];
    char d[9];
}T_TEMP_C;

int main()
{
    char* temp = "123456789012345678901234";
    T_TEMP_C* ltpa = (T_TEMP_C*) temp;

    printf("ltpa -> a : %sn", ltpa->a);
    printf("ltpa -> b : %cn", ltpa->b[0]);
    printf("ltpa -> c : %sn", ltpa->c);
    printf("ltpa -> d : %sn", ltpa->d);

    return 0;
}
  

Однако я даже не уверен, что ваш каламбур типа действительно определен для работы. Реализациям разрешено добавлять отступы между элементами структуры, поэтому нет гарантии, что b это начнется сразу после a .

Если вы не хотите изменять temp , вы не можете использовать %s формат для печати подстрок. Вы можете указать точность в строке формата, тогда она будет печатать только столько байтов строки. %.10s будет печатать до 10 байт, а не до нулевого терминатора.

     printf("ltpa -> a : %.10sn", ltpa->a);
    printf("ltpa -> b : %cn", ltpa->b[0]);
    printf("ltpa -> c : %.5sn", ltpa->c);
    printf("ltpa -> d : %sn", ltpa->d);
  

Комментарии:

1. Я не хочу менять «temp»

2. @JaceCho, хотя это может быть не тот ответ, на который вы надеялись, в вашем исходном сообщении говорилось, что вы не понимаете, почему ваша программа ведет себя так, как она есть. Это действительно отвечает на ваш вопрос.

3. @JaceCho Я внес изменения в ответ, чтобы показать, как вы можете указать количество байтов для печати в строках формата.

Ответ №2:

Я бы не рекомендовал приводить char указатель к struct указателю.

Для достижения вашей цели вы можете использовать snprintf . Т.е.,

 const char* temp = "123456789012345678901234";
T_TEMP_C thing;

snprintf(thing.a,sizeof(thing.a), "%.*s", 10, temp);
snprintf(thing.b,sizeof(thing.b), "%.*s", 1, temp 10);
snprintf(thing.c,sizeof(thing.c), "%.*s", 5, temp 11);
snprintf(thing.d,sizeof(thing.d), "%s", temp 16);