1

When I try to swap between strings in the function Update_student it doesn't make it. Why?

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

#define SIZE 1

struct student {
    int id_number;
    char name[50];
    char sex[6];
    int quiz_score[2];
    int total_score;
};

void Add_Student_Records(struct student *pupil) {
    printf("ID:");
    scanf("%d", &pupil->id_number);
    printf("Name: ");
    scanf("%s", &pupil->name);
    printf("Sex :");
    scanf("%s", &pupil->sex);
    for (int i = 0; i < 2; i++) {
        printf("Quit score %d:", i + 1);
        scanf("%d", &pupil->quiz_score[i]);
    }
    pupil->total_score = pupil->quiz_score[0] + pupil->quiz_score[1];
    return; 
}

void Add_Students(struct student *students) {
   for (int i = 0; i < SIZE; i++) {
        printf("Student %d:\n", i + 1);
        Add_Student_Records(students);
    }
    return;
}

void Print_Students(struct student *students) {
    for (int i = 0; i < SIZE; i++) {
        printf("Student %d details: \n", i + 1);
        printf("ID:%d\n", students->id_number);
        printf("Name:%s\n", students->name);
        printf("Sex:%s\n", students->sex);
        for (int i = 0; i < 2; i++) {
            printf("Quit score %d:\n", students->quiz_score[i]);
        }
        printf("Total score: %d\n", students->total_score);
        students++;
    }
    return;
}

void Replace_Strings(char **old_string, char **new_string) {
        *old_string = *new_string;
        return;
}

void Update_Student(struct student *students) {
    int i = 0;
    char name[50], new_name[50], cur_name[50];
    printf("You can update name, and scores.\n");
    printf(" current Name: ");
    scanf("%s", name);
    printf("new name: ");
    scanf("%s", &new_name);
    while (i < SIZE) {
        strcpy(cur_name, students->name);
        if (strcmp(cur_name, name) == 0) {   
            char *ptr_old_stud_name = students->name;
            char *ptr_new_stud_name = new_name;
            Replace_Strings(&ptr_old_stud_name, &ptr_new_stud_name);
        }
        i++;
        students++;
    }
    return;
}

int main() {
    struct student students[SIZE];
    char ch;
    /*1.Add student, 2. Print student*/
    printf("1.Add student\n2.Print students\n3.Update student\n");
    scanf("%c", &ch);
    while (ch != 'E') {
        if (ch == '1') {
            Add_Students(&students[0]);
        }           
        else if (ch == '2') {
            Print_Students(&students[0]);
        }
        else if (ch =='3') {
            Update_Student(&students[0]);
        }
        printf("Another operation:\t");
        scanf("%c", &ch);
    }
}
4
  • 1
    You are not swapping pointers, only copying them. Commented Aug 14, 2020 at 14:10
  • 2
    Works fine. You changed the pointer in a local variable. You can't use this method on student->name because it is an array, not a pointer. Commented Aug 14, 2020 at 14:11
  • 1
    In scanf("%s", &pupil->name);, address-of operator is not needed for char array arguments. Commented Aug 14, 2020 at 14:23
  • 1
    You have two more of those that I can see. Commented Aug 14, 2020 at 14:26

2 Answers 2

3

Replace_Strings(&ptr_old_stud_name,&ptr_new_stud_name); passes the addresses of ptr_old_stud_name and ptr_new_stud_name to ReplaceStrings.

ptr_old_stud_name and ptr_new_stud_name are local variables. The first is a pointer that has been set to point to students->name. The second is a pointer that has been set to point to new_name.

Replace_Strings changes the first thing it is passed a pointer to to the second thing it is passed a pointer to. So it changes ptr_old_stud_name to have the value of ptr_new_stud_name.

The result is that the local variable ptr_old_stud_name has a new value. This does not change the thing it points to, students->name.

More specifically, ptr_old_stud_name was pointing to the first character of students->name. students->name is an array, and it cannot be altered by changing pointers to it, and its address cannot be changed. To change its contents, you must copy new values into the bytes within it, which you could do by using strcpy to copy bytes into it from new_name.

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

Comments

1

Your function Update_student is confusing, you should just iterate through the array of students and compare the student's name with cur_name and replace the name when there is a match.

You should also pass the number of students to handle as an argument.

Here is a modified version:

void Update_Student(struct student *students, int count) {
    char cur_name[50], new_name[50];
    printf("You can update name, and scores.\n");
    printf(" current Name: ");
    scanf("%49s", cur_name);
    printf("new name: ");
    scanf("%49s", new_name);
    for (int i = 0; i < count; i++) {
        if (strcmp(cur_name, students[i].name) == 0) {
            strcpy(students[i].name, new_name);
        }
    }
}

Call from main as Update_Student(students, SIZE);

Note also that you should ignore whitespace when reading the commands by adding a space before the %c:

    scanf(" %c", &ch);

Here is a modified version with for multiple students:

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

#define SIZE 10

struct student {
    int id_number;
    char name[50];
    char sex[6];
    int quiz_score[2];
    int total_score;
};

int Add_Student_Records(struct student *pupil) {
    printf("ID:");
    if (scanf("%d", &pupil->id_number) != 1)
        return 0;
    printf("Name: ");
    if (scanf("%49s", pupil->name) != 1)
        return 0;
    printf("Sex :");
    if (scanf("%1s", pupil->sex) != 1)
        return 0;
    for (int i = 0; i < 2; i++) {
        printf("Quiz score %d:", i + 1);
        if (scanf("%d", &pupil->quiz_score[i]) != 1)
            return 0;
    }
    pupil->total_score = pupil->quiz_score[0] + pupil->quiz_score[1];
    return 1;
}

int Add_Students(struct student *students, int count) {
    int i;
    for (int i = 0; i < count; i++) {
        printf("Student %d:\n", i + 1);
        if (Add_Student_Records(students + i) == 0)
            break;
    }
    return i;
}

void Print_Students(struct student *students, int count) {
    for (int i = 0; i < count; i++) {
        printf("Student %d details: \n", i + 1);
        printf("ID:%d\n", students->id_number);
        printf("Name:%s\n", students->name);
        printf("Sex:%s\n", students->sex);
        for (int i = 0; i < 2; i++) {
            printf("Quit score %d:\n", students->quiz_score[i]);
        }
        printf("Total score: %d\n", students->total_score);
        students++;
    }
}

void Update_Student(struct student *students, int count) {
    char cur_name[50], new_name[50];
    printf("You can update name, and scores.\n");
    printf(" current Name: ");
    if (scanf("%49s", cur_name) != 1)
        return;
    printf("new name: ");
    if (scanf("%49s", new_name) != 1)
        return;
    for (int i = 0; i < count; i++) {
        if (strcmp(cur_name, students[i].name) == 0) {
            strcpy(students[i].name, new_name);
        }
    }
}

int main() {
    struct student students[SIZE];
    int n = 0;
    char ch = 'E';
    /* print the menu */
    printf("1. Add student\n"
           "2. Print students\n"
           "3. Update student\n");
    scanf(" %c", &ch);
    while (ch != 'E') {
        if (ch == '1') {
            if (n == SIZE) {
                printf("student array is full\n");
            } else {
                /* add more students */
                n += Add_Students(&students[n], SIZE - n);
            }
        } else
        if (ch == '2') {
            Print_Students(students, n);
        } else
        if (ch =='3') {
            Update_Student(students, n);
        }
        scanf("%*[^\n]");   // consume the rest of the pending input line
        printf("Another operation:\t");
        if (scanf(" %c", &ch) != 1)
            break;
    }
    return 0;
}

Comments

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.