Jordan
Jordan

Reputation: 54

C Structures: Printing a string member produces weird results

I am independently learning C. I have a four member struct as follows:

#define aSize 10
struct Students {
     char lastName[aSize];
     char firstName[aSize];
     int age; 
     int grade;
 }

I have two separate functions (in the main.c file):

void pasteInfo_1(struct Students S1) {}

and

void printStudents(struct Students S1) {}

pasteInfo() uses strcpy() and assignment to assign values to the members; printStudents() then prints the values stored in the members. When I compile the file:

#in makefile
CFLAGS = -lm -o -Wall
gcc main.c $(CFLAGS) main

It compiles with no errors. However, when I call the executable it prints some very weird characters that look like binary/assembly. Any suggestions? Here are the individual functions.

void pasteInfo_1(struct Students S1) {
     strcpy(S1.lastName, "Effinger");
 }

And here is printStudents:

void printStudents(struct Students S1) {
     printf("%s\n",S1.lastName);
}

The function calls in main:

int main() {
     struct Students S1;
     pasteInfo_1(S1);
     printStudents(S1);
 }

Re: Modifications. After adding the changes suggested by user3629249, I got the following errors:

main.c:6:23: warning: ‘struct Students’ declared inside parameter list      will not be visible outside of this definition or declaration
 void pasteInfo(struct Students * pS1);
                       ^~~~~~~~
main.c:7:27: warning: ‘struct Studens’ declared inside parameter list will not be visible outside of this definition or declaration
 void printStudents(struct Studens S1);
                           ^~~~~~~
main.c: In function ‘main’:
main.c:22:14: warning: passing argument 1 of ‘pasteInfo’ from incompatible pointer type [-Wincompatible-pointer-types]
   pasteInfo( &S1);
              ^
main.c:6:6: note: expected ‘struct Students *’ but argument is of type ‘struct Students *’
 void pasteInfo(struct Students * pS1);
      ^~~~~~~~~
main.c:23:17: error: type of formal parameter 1 is incomplete
   printStudents(S1);
                 ^~
main.c: At top level:
main.c:26:6: error: conflicting types for ‘pasteInfo’
 void pasteInfo(struct Students * pS1)
      ^~~~~~~~~
main.c:6:6: note: previous declaration of ‘pasteInfo’ was here
 void pasteInfo(struct Students * pS1);
      ^~~~~~~~~
main.c:32:6: error: conflicting types for ‘printStudents’
 void printStudents(struct Students S1)
      ^~~~~~~~~~~~~
main.c:7:6: note: previous declaration of ‘printStudents’ was here
 void printStudents(struct Studens S1);
      ^~~~~~~~~~~~~

Upvotes: 0

Views: 749

Answers (3)

autistic
autistic

Reputation: 15642

It seems from your error messages as though you need to forward declare struct Students and/or pasteInfo. See your textbook for advice on how to do that, if necessary.

I am independently learning C.

What does this mean? Are you reading from a book? If so, which book?

Keep in mind that it's dangerous to learn C by misguided trial and error; what you'll most likely end up learning is something that differs from C in subtle and possibly dangerous ways, and which medications best deal with the headaches you give yourself...

That's the peril of learning by misguided trial and error; you'll run into a lot of undefined behaviour (and implementation-defined behaviour) that will differ from system to system and might not make sense at the time...

You're better off avoiding UB and IB by reading a decent book such as K&R2E, and doing the exercises as you stumble across them.

Upvotes: 2

Jordan
Jordan

Reputation: 54

Solved it! Here is the working code: (Special Thanks to user3629249 and Seb for their advice)

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

 struct Students
 {
     char lastName[8];
     char firstName[6];
     int age;
     int grade;
 };

 void pasteInfo(struct Students *S1);
 void printStudnets(struct Students S1);

 int main(void)
 {

     struct Students S1;
     pasteInfo( &S1 );
     printStudents( S1 );
 }
 void pasteInfo(struct Students *S1)
 {
     strcpy(S1->lastName, "Effinger");
 }
 void printStudent(struct Students S1)
 {
      printf("%s\n",S1.lastName);
 }      

Upvotes: -1

user3629249
user3629249

Reputation: 16540

when the called function plans to (directly) change anything in the caller function, pass the address of the item to the called function. I.E.

int main( void ) 
{
    struct Students S1;
    pasteInfo_1( &S1 );   // <-- passing pointer to struct
    printStudents( S1 );
}

Then modify the pasteInfo_1()` function to expect a pointer,

void pasteInfo_1( struct Students * pS1 ) 
{
    strcpy( pS1->lastName, "Effinger" );
}

Note the use of vertical alignment of the braces and the use of appropriate horizontal spacing.

The purpose of the vertical alignment and horizontal spacing is to make the code much more readable.

Upvotes: 0

Related Questions