Sababoni
Sababoni

Reputation: 5097

swap strings function in c with pointers

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);
    }
}

Upvotes: 1

Views: 89

Answers (2)

chqrlie
chqrlie

Reputation: 144750

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;
}

Upvotes: 1

Eric Postpischil
Eric Postpischil

Reputation: 222734

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.

Upvotes: 3

Related Questions