0

I am trying to create a simple c program having an array of structures and I am passing each element of the array into a function and then trying to display it below is my code.

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

struct students{
    char name[50];
    int marks;
}st[10];


int size;

int addStudent(struct students st,char sname[], int marks){
    static int count = 0;
    strncpy(st.name,sname,strlen(sname));
    st.marks = marks;
    count++;
    return count;
}

void showStudents(int size){
    int i;
    printf("Total number of students : %d\n",size);
    for(i=0;i<size;i++){
        printf("Student Name : %s\nMarks : %d\n",st[i].name,st[i].marks);
    }   
}

int main(){
    int n, marks, i;
    char name[50];
    printf("Enter the total number of students : ");
    scanf("%d",&n);
    getchar();
    for(i=0;i<n;i++){
        printf("Enter the name of the Student : ");
        fgets(name,50,stdin);
        printf("Enter the marks of the student : ");
        scanf("%d",&marks);
        getchar();
        size = addStudent(st[i], name, marks);
    }

    showStudents(size);

    return 0;
}

and I am getting the following output

Enter the total number of students : 2
Enter the name of the Student : shibli
Enter the marks of the student : 23
Enter the name of the Student : max
Enter the marks of the student : 45
Total number of students : 2
Student Name :
Marks : 0
Student Name :
Marks : 0

Instead of getting the names and the marks I am getting no values can anyone help me what I am doing wrong with my code.

8
  • 1
    f(x) can't change x. Commented Aug 19, 2018 at 8:22
  • 2
    Please read how to debug small programs. Consider passing the st array -as a pointer argument- to your showStudents function. In C, every argument is passed by value. Commented Aug 19, 2018 at 8:22
  • @BasileStarynkevitch I am passing the st[i] which is an address as it is an array of structures. Commented Aug 19, 2018 at 8:26
  • You are not passing st to showStudents. You are using it as a global variable, and that is bad style. Declare void showStudents(struct students*st, size_t nbst); Commented Aug 19, 2018 at 8:27
  • 1
    st[i] is a struct, not an address, as st is an array of structures. Commented Aug 19, 2018 at 8:27

1 Answer 1

3

When passing a struct to a function, the function actually copies the struct to the input struct parameter and works on it. So the function addStudent did not work on your global array item but on a local copy.

You should pass a pointer to the struct item to the function and work on that. The code then looks like this:

int addStudent(struct students *st,char sname[], int marks){
    static int count = 0;
    strncpy(st->name,sname,strlen(sname)+1);
    st->marks = marks;
    count++;
    return count;
}

and the call to the function addStudent looks like this:

    size = addStudent(&st[i], name, marks);

In general the code can have other improvements like not using global variables, and static counters, but this is outside the scope of your question.

there is another issue here, using strncpy for copying strlen of string, does not end the string with null. So you should use strlen+1 to copy also the null termination, or simply use snprintf which adds null termination at end of string

Sign up to request clarification or add additional context in comments.

5 Comments

strncpy(st->name,sname,strlen(sname)) is broken.
strncpy(st->name,sname,strlen(sname)+1); is an inefficient way of writing strcpy(st->name,sname);.
yes. I think it is much better simply using snprintf. however I wanted to reply to user question of passing struct to a function, and not fix the entire code. as I mentioned there are some other possible improvements to user's code
Isnt it strcpy() function vulnerable to buffer overflow attacks?
Yes, but if you are using strncpy, you shall pass it a parameter, the maximum source buffer size, and not the strlen of the target buffer. in addition you must make sure the source buffer is null terminated. that's why snprintf is better for that purpose, as it make sure you do not exceed source buffer size, and also put terminating null at end of string. see strncpy, snprintf man pages.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.