无法从 C 中的结构打印字符串

Can´t print a String from a structure in C

typedef struct listaDocente nodoDocente;
struct listaDocente{            //teacherList
    char Rut[12];               //ID
    char Nombre[50];            //Name
    char Correo[70];            //Email
    char Cod_Curso[6];          //Grade_Code
    char Asignatura[15];        //Grade_Name
    nodoDocente *siguiente;     //Next (Node)
};

int main(){
    nodoDocente *D = ((nodoDocente * )malloc(sizeof(nodoDocente)));
    strcpy(D->Nombre, "Charlie");
    strcpy(D->Rut, "18123456");
    strcpy(D->Asignatura, "EDD");
    strcpy(D->Cod_Curso, "INS123");
    strcpy(D->Correo, "charlie@test.com");
    printf("%s\n", D->Nombre);
    printf("%s\n", D->Rut);
    printf("%s\n", D->Asignatura);
    printf("%s\n", D->Cod_Curso);
    printf("%s\n", D->Correo);

    return 0;
}

首先,抱歉,如果有些词是西班牙语。 我试图打印这些值,但我得到了一个空白 space。

Charlie
18123456

INS123
charlie@test.com

它应该在哪里打印出 EDD,就像这样。

Charlie
18123456
EDD
INS123
charlie@test.com

不要忘记 C 中的字符串总是有一个尾随 [=13=] 字符。所以你的:

INS123

写成

INS123[=11=]

它的长度是 7 个字符,而不是 6。所以你所做的是在 Asignatura 的第一个字符上写一个额外的 [=13=],因此它的长度变为 0。

要解决此问题,您应该声明 Cod_Curso 足够:

char Cod_Curso[7];          //Grade_Code

您已声明:

char Cod_Curso[6];

并用 :

填充
strcpy(D->Cod_Curso, "INS123");

但是 INS123 后跟字符串的终止字符 [=15=]。因此,字符串 INS123 并不是您想象的 6 个字符,而是实际上占据了 7 个字符。因此,您不能期望语句 :

printf("%s\n", D->Asignatura);

以在您使用上一行调用 时正常工作。

解决方案:声明Cod_Curso大小为7(或更多),像这样:

char Cod_Curso[7];

还有,看看这个link on why not to cast the result of malloc

一个字符串需要一个额外的字节来存储 [=11=] 这使得一个字符数组被视为字符串。你在这里违反了这条规则,

char Cod_Curso[6];
strcpy(D->Cod_Curso, "INS123");

这会将 [=11=] 覆盖到分配给其他变量的内存,这会导致代码中出现 UB

如果您确定每个字符串的长度,您可以为您的 char 数组使用一个精确定义的长度,或者您可以将它们全部声明为 char* 并 malloc 每个来存储您提供的字符串或为所有人提供足够的数组长度 (buffer)。

此外,您的代码中存在内存泄漏。您应该 free 使用 malloccallocrealloc 分配的内存。

malloc returns void* 隐式提升为 C 中的任何其他指针类型,因此您无需转换 malloc.

您已使用 strcpyINS123 复制到 Cod_Curso[6]。现在 strcpy 从 src 读取直到它看到 '\0' 并将读取的内容(包括 '\0')复制到 dest。因此这里 7 个字符将被复制到 Cod_Curso.

指向的缓冲区

问题来了。目标缓冲区中分配的 space 只有 6 个字符。因此,将 7 个字符复制到其中将导致缓冲区溢出,即额外的字符将被复制到不属于 Cod_Curso 的内存中,而是复制到堆栈中它上面的变量中,这里是 Asignatura[15]。所以现在额外的字符 '\0' 被复制到 Asignatura[0].

现在 printf'%s' 打印,直到它在传递的缓冲区中看到 '[=21=]'。由于 Asignatura[0]'[=21=]',因此打印了一个空字符串。

解决方案

最好使用 strcpy 的安全版本,例如 strncpy。或者您可以增加缓冲区大小。