[英]Struct with Char array is printing garbage… How to fix?
我有下面的代码。 当我打印出分配给该结构中的字符数组的数据时,除非我在数组中添加额外的字符并放入“ / 0”,否则它会打印出一堆垃圾。 问题出在后面,我需要获取出生日期和月份为整数(4个字节)。 谁能告诉我如何使其打印出适当的数据? 我需要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: ");
}
更改结构定义,使其大小足以容纳C字符串终止字符: \\0
。
struct Info
{
char studentID[7];
char firstName[50];
char lastName[50];
char birthDay[3];
char birthMonth[3];
char birthYear[5];
};
所示的大小在长度上是任意的,但是对于您的用例而言,足够了。
在内存中,仅以足够的空间包含6个字符(即“ 999999”)创建成员: studentID[6]
,而不创建所有重要的 字符串终止字符: \\0
。 C实际上没有_string typeP。 相反,在C中,字符串定义为以'\\ 0'结尾的字符数组
因此,studentID [7]如下所示:
|'9'|'9'|'9'|'9'|'9'|'9'|0|
重要的一点是,在创建字符串变量(或char数组)时,例如:
char string[10] = {0};//space for 10 char
然后用类似的东西填充它:
strcpy(string, "nine char"); //9 spaces used
空终止符被附加为调用strcpy()
的函数,从而为您提供:
|'n'|'i'|'n'|'e'|' '|'c'|'h'|'a'|'r'|0| //9 characters AND a NULL terminator
在你的结构中
struct Info
{
char studentID[6];
char firstName[5];
char lastName[4];
char birthDay[2];
char birthMonth[2];
char birthYear[4];
};
变量没有足够的内存来存储空终止符。 因此,打印为字符串是错误的。
为避免这种情况,请始终允许再有一个char
存储空终止符。 使用相同的初始化程序集,
struct Info
{
char studentID[7];
char firstName[6];
char lastName[5];
char birthDay[3];
char birthMonth[3];
char birthYear[5];
};
应该工作正常。
也许您想要这样:
printf("Birth Day: %c%c \n", studentInfo.birthDay[0], studentInfo.birthDay[1]);
如果要在此结构中打印出字符值,并且不想将结构更改为包含以空字符结尾的字符串(如您在注释中所建议的那样),则必须告诉printf
限制要输入多少个字符打印。
通常%s
打印直到遇到空终止符,但是您的结构不包含任何空终止符,因此必须指定最大字段宽度:
printf("%-15s %.6s \n", "Student ID:", studentInfo.studentID);
// ^^
您可以通过编程找到此值,而不是依靠幻数:
printf("%-15s %.*s \n", "Student ID:",
(int)(sizeof studentInfo.studentID), studentInfo.studentID);
您可以选择将所有这些行包装在宏中:
#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.
注意 这个结构的初始化方法是正确的:在C语言中,可以从包含与数组大小一样多的非null字符的字符串文字中初始化char数组; 并且用这些字符填充char数组。 (这在C ++中是不允许的)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.