0

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". The problem with this is later on I need to grab the birth day and month as an integer (4 bytes). 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.

#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: ");
}
10
  • NUL terminator. NUL terminator. NUL terminator. NUL terminator. NUL terminator. Commented Dec 8, 2014 at 20:57
  • possible duplicate of null terminating a string Commented Dec 8, 2014 at 20:58
  • 1
    Your arrays are not big enough. You need 1 more to store the zero terminator. Commented Dec 8, 2014 at 20:59
  • Shouldn't &studentInfo.studentID be &studentInfo->studentID or studentInfo.studentID? Commented Dec 8, 2014 at 21:03
  • here is an example fix: printf("%-15s %s \n", "Student ID:", studentInfo.studentID); should be: printf("%-15s %6s \n", "Student ID:", studentInfo.studentID); where the '6' is the number of characters to print. Commented Dec 8, 2014 at 22:14

4 Answers 4

2

Change your struct definition with sizes sufficient to accommodate the C string termination character: \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, i.e. "999999", but not the all important string termination character: \0. C does not actually have a _string typeP. Instead, in C, a string is defined as a character array terminated by a '\0'

So, studentID[7] would look like this:

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

An important point, when you create a string variable (or a char array) such as:

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:

|'n'|'i'|'n'|'e'|' '|'c'|'h'|'a'|'r'|0| //9 characters AND a NULL terminator
Sign up to request clarification or add additional context in comments.

4 Comments

Suggest reserving "NULL" for the null pointer NULL. Use '\0' or "null character" here.
Thanks for the reply but actually user i486 actually gave me what I needed. I said in the post that I know you can put /0 but I can't do that for this because I need to use the memory locations in certain ways.
@KevinZaki - Your mistake is creating memory insufficient for the data you are later attempting to assign. i.e. "999999" will not fit into an array of size 6. You need 7 char spaces to define a string with 6 useable characters and a '\0'.
@ryyker thanks. I understand that but this is a school assignment and the next part of the assignment I can't have char[3] for because I need to pull 4 bytes from memory as an integer which would be char[2] char[2] for birhtMonth and birthDay. I understand this may not be proper coding but it is what I need to accomplish this assignment.
1

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. 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.

Comments

0

Maybe you want this:

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

4 Comments

struct Info studentInfo = {"99999", "firs", "las", {'0','1'}, {'0','7'}, {'1','9','9','3'} };
This is actually what I was looking for.
actually, losing the last chard of each text is NOT a good solution. Rather make the initializer similar to: struct Info studentInfo = {('9','9','9','9','9','9'), etc }; However, the printf() statements for the values will also need to number of char to print, as in: printf("%-15s %6s \n", "Student ID:", studentInfo.studentID);
I removed last char for first/last name because the other option was to change the structure. Actually, char lastName[4]; must be modified to more realistic value - e.g. 20-30 chars instead of 4.
0

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.

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:

 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; and that fills the char array with those characters. (This is not permitted in C++).

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.