简体   繁体   English

带有Char数组的结构正在打印垃圾……如何解决?

[英]Struct with Char array is printing garbage… How to fix?

I have the code below. 我有下面的代码。 When I print out the data I assign to the character arrays in the struct it prints out a bunch of junk unless I add an extra character to the array and put "/0". 当我打印出分配给该结构中的字符数组的数据时,除非我在数组中添加额外的字符并放入“ / 0”,否则它会打印出一堆垃圾。 The problem with this is later on I need to grab the birth day and month as an integer (4 bytes). 问题出在后面,我需要获取出生日期和月份为整数(4个字节)。 Can anyone tell me how to make it print out the appropriate data? 谁能告诉我如何使其打印出适当的数据? I need the char array to be the exact size in memory of the size of the data. 我需要char数组是数据大小在内存中的确切大小。

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

struct Info
{
        char studentID[6];
        char firstName[5];
        char lastName[4];
        char birthDay[2];
        char birthMonth[2];
        char birthYear[4];
};

void printFunction( struct Info studentInfo );

int main()
{
        struct Info studentInfo = {"999999", "first", "last", "01", "07", "1993"};
        void *baseptr;
        asm("movl %%ebp,%0;":"=r"(baseptr));
        printf("The value of the basepointer main:\n");
        printf("%p\n", baseptr);
        printf("%-15s %s \n", "Student ID:", studentInfo.studentID);
        printf("%-15s %s \n", "First Name:", studentInfo.firstName);
        printf("%-15s %s \n", "Last Name:", studentInfo.lastName);
        printf("%-15s %s \n", "Birth Day:", studentInfo.birthDay);
        printf("%-15s %s \n", "Birth Month:", studentInfo.birthMonth);
        printf("%-15s %s \n", "Birth Year:", studentInfo.birthYear);

        printFunction( studentInfo );
        return 0;
}

void printFunction( struct Info studentInfo )
{
        printf("The value of basepointer printFunction is:\n");
        int *baseptr;
        asm("movl %%ebp,%0;":"=r"(baseptr));
        printf("%p\n", baseptr);
        printf("The value at basepointer address is:\n");
        printf("%p\n", *baseptr);
        printf("%-25s %p \n", "Address of Student ID:", &studentInfo.studentID);
        printf("%-25s %p \n", "Address of First Name:", &studentInfo.firstName);
        printf("%-25s %p \n", "Address of Last Name:", &studentInfo.lastName);
        printf("%-25s %p \n", "Address of Birth Day:", &studentInfo.birthDay);
        printf("%-25s %p \n", "Address of Birth Month:", &studentInfo.birthMonth);
        printf("%-25s %p \n", "Address of Birth Year:", &studentInfo.birthYear);
        printf("%s %x \n", "The address of my birth day and month is at address: ", &studentInfo.birthDay );
        printf("%s \n", "The integer value of my birth day and month is: ");
}

Change your struct definition with sizes sufficient to accommodate the C string termination character: \\0 . 更改结构定义,使其大小足以容纳C字符串终止字符: \\0

struct Info
{
        char studentID[7];
        char firstName[50];
        char lastName[50];
        char birthDay[3];
        char birthMonth[3];
        char birthYear[5];
};

Sizes shown are arbitrary in length, but for illustration of your use case, sufficient. 所示的大小在长度上是任意的,但是对于您的用例而言,足够了。

In memory, the member: studentID[6] is only created with enough space contain 6 characters, ie "999999", but not the all important string termination character: \\0 . 在内存中,仅以足够的空间包含6个字符(即“ 999999”)创建成员: studentID[6] ,而不创建所有重要的 字符串终止字符: \\0 C does not actually have a _string typeP. C实际上没有_string typeP。 Instead, in C, a string is defined as a character array terminated by a '\\0' 相反,在C中,字符串定义为以'\\ 0'结尾的字符数组

So, studentID[7] would look like this: 因此,studentID [7]如下所示:

|'9'|'9'|'9'|'9'|'9'|'9'|0|  

An important point, when you create a string variable (or a char array) such as: 重要的一点是,在创建字符串变量(或char数组)时,例如:

char string[10]  = {0};//space for 10 char

then fill it with something like: 然后用类似的东西填充它:

strcpy(string, "nine char"); //9 spaces used  

The null terminator is appended as a function of calling strcpy() , giving you: 空终止符被附加为调用strcpy()的函数,从而为您提供:

|'n'|'i'|'n'|'e'|' '|'c'|'h'|'a'|'r'|0| //9 characters AND a NULL terminator

In your structure 在你的结构中

struct Info
{
        char studentID[6];
        char firstName[5];
        char lastName[4];
        char birthDay[2];
        char birthMonth[2];
        char birthYear[4];
};

variables are not having enough memory to store the null terminator. 变量没有足够的内存来存储空终止符。 So, printing as string is wrong. 因此,打印为字符串是错误的。

To avoid, always allow one more char to store the null terminator. 为避免这种情况,请始终允许再有一个char存储空终止符。 With the same set of initializer, 使用相同的初始化程序集,

struct Info
{
        char studentID[7];
        char firstName[6];
        char lastName[5];
        char birthDay[3];
        char birthMonth[3];
        char birthYear[5];
};

should work just fine. 应该工作正常。

也许您想要这样:

printf("Birth Day: %c%c \n", studentInfo.birthDay[0], studentInfo.birthDay[1]);

If you want to print out the character values in this struct, and you don't want to change the struct to contain null-terminated strings (as you suggest in comments), then you have to tell printf a limit on how many characters to print. 如果要在此结构中打印出字符值,并且不想将结构更改为包含以空字符结尾的字符串(如您在注释中所建议的那样),则必须告诉printf限制要输入多少个字符打印。

Normally %s prints until it encounters a null terminator, but your struct does not contain any null terminators, so you have to specify the maximum field width: 通常%s打印直到遇到空终止符,但是您的结构不包含任何空终止符,因此必须指定最大字段宽度:

 printf("%-15s %.6s \n", "Student ID:", studentInfo.studentID);
 //             ^^

You can find this value programmatically instead of relying on magic numbers: 您可以通过编程找到此值,而不是依靠幻数:

 printf("%-15s %.*s \n", "Student ID:", 
        (int)(sizeof studentInfo.studentID), studentInfo.studentID);

Optionally you could wrap all these lines up in a macro: 您可以选择将所有这些行包装在宏中:

#define PRINT_ITEM(prompt, field) \
    printf("%-15s %.*s\n", prompt, (int)sizeof(field), field)

PRINT_ITEM("Student ID:", studentInfo.studentID);
PRINT_ITEM("First Name:", studentInfo.firstName);
PRINT_ITEM("Last Name:" , studentInfo.lastName);
// etc.

NB. 注意 The initializers for this struct are correct: in C it is permitted to initialize a char array from a string literal containing exactly as many non-null characters as the size of the array; 这个结构的初始化方法是正确的:在C语言中,可以从包含与数组大小一样多的非null字符的字符串文字中初始化char数组; and that fills the char array with those characters. 并且用这些字符填充char数组。 (This is not permitted in C++). (这在C ++中是不允许的)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM