1

I'm practicing C using structs and pointers, I'm asking to the user to input some info using structs and then using pointers to modify it but I'm having problems when I need to get a string with spaces. I switched all the scanfs for fgets and still getting problems with the output.

#include <stdio.h>
#include <stdlib.h>

#define MAXTSTR 25

int main(int argc, char **argv) {
    
    typedef struct birthday {
        int day, year;
        char month[10];
    } BDATE;
    
    struct employee {
        char name[MAXTSTR];
        int id;
        float salary;
        BDATE bday;
    } emp;
    
    struct employee *ptrEmp = &emp;

    printf("Enter employee name:");
    fgets(emp.name, MAXTSTR, stdin );
    printf("enter id number:");
    scanf(" %d", &emp.id);
    printf("enter salary");
    scanf(" %f", &emp.salary);
    printf("enter birhday:");
    scanf(" %d", &emp.bday.day);
    printf("enter year:");
    scanf(" %d", &emp.bday.year);
    printf("enter month:");
    fgets(emp.bday.month, MAXTSTR, stdin);
    
    printf("\nName: %s \nID: %d \nSalary: %.2f\n", emp.name, emp.id, emp.salary);
    printf("%d %s %d", emp.bday.day, emp.bday.month, emp.bday.year);
    
    printf("\n------------------------------------\n");
    
    printf("Enter employee name:");
    fgets(ptrEmp->name, MAXTSTR, stdin);
    printf("enter id number:");
    scanf(" %d", &ptrEmp->id);
    printf("enter salary");
    scanf(" %f", &ptrEmp->salary);
    printf("enter birhday:");
    scanf(" %d", &ptrEmp->bday.day);
    printf("enter year:");
    scanf(" %d", &ptrEmp->bday.year);
    printf("enter month:");
    scanf(ptrEmp->bday.month, MAXTSTR, stdin);
    
    printf("\nName: %s \nID: %d \nSalary: %.2f\n",
       ptrEmp->name, ptrEmp->id, ptrEmp->salary);
    printf("%d %s %d", ptrEmp->bday.day, ptrEmp->bday.month,
       ptrEmp->bday.year);
    
    return (EXIT_SUCCESS);
}

INPUT and OUTPUT EXAMPLE

Enter employee name:Luis Oliveira
enter id number:01
enter salary1525.25
enter birhday:05
enter year:1991
enter month:
Name: Luis Oliveira
 
ID: 1 
Salary: 1525.25
5 
 1991
------------------------------------
Enter employee name:Patricia Santos
enter id number:02
enter salary16546.46
enter birhday:05
enter year:1946
enter month:Fev

Name: Patricia Santos
 
ID: 2 
Salary: 16546.46
5 
 1946

What I'm doing wrong?

Thank you in advance for your help.

Jens
  • 69,818
  • 15
  • 125
  • 179
  • *problems with the output*. What problems specifically? Just showing the input/output doesn't make it obvious what the errors or incorrect results are. You need to explicitly point that out - usually by providing the expected result. – kaylum Feb 15 '21 at 11:04
  • What are you doing with the `'\n'` left in `stdin` after your call to `scanf(" %d", &emp.bday.year);` and before your call to `fgets(emp.bday.month, MAXTSTR, stdin);`? – David C. Rankin Feb 15 '21 at 11:05
  • 1
    This might be helpful: [How to read / parse input in C? The FAQ](https://stackoverflow.com/questions/35178520/how-to-read-parse-input-in-c-the-faq). – Lundin Feb 15 '21 at 11:07
  • @David C. Rankin do I need to use a `getchar()` so that `\n` is stored there? – Luís Oliveira Feb 15 '21 at 11:18
  • @kaylum sorry for my ignorance . Let see if I can explain better. So If the input was `Luis Oliveira, 01, 05, 1991 July` the expected output would be `Name: Luis Oliveira ID: 01, 05 1991 July` but I'm not getting the month printed. I guess is something related with the scanf's that I'm using. – Luís Oliveira Feb 15 '21 at 11:25

1 Answers1

1

Mixing scanf() and fgets() can be very confusing: scanf() leaves the pending newline in the input stream and fgets() reads it and immediately returns because it has reached the end of line.

You can read the month with scanf("%9s", emp.bday.month); and the employee name with scanf(" %14[^\n]", ptrEmp->name);.

Also check for invalid input causing scanf() to return a value different from the expected 1.

Modified program:

#include <stdio.h>
#include <stdlib.h>

#define MAXTSTR 25

typedef struct birthday {
    int day, year;
    char month[10];
} BDATE;

struct employee {
    char name[MAXTSTR];
    int id;
    float salary;
    BDATE bday;
};

int main(int argc, char **argv) {
    struct employee emp;    

    for (int i = 0; i < 2; i++) {
        printf("Enter employee name: ");
        if (scanf(" %14[^\n]", emp.name) != 1)
            return EXIT_FAILURE;
        printf("enter id number: ");
        if (scanf(" %d", &emp.id) != 1)
            return EXIT_FAILURE;
        printf("enter salary: ");
        if (scanf(" %f", &emp.salary) != 1)
            return EXIT_FAILURE;
        printf("enter birthday: ");
        if (scanf(" %d", &emp.bday.day) != 1)
            return EXIT_FAILURE;
        printf("enter year: ");
        if (scanf(" %d", &emp.bday.year) != 1)
            return EXIT_FAILURE;
        printf("enter month: ");
        if (scanf("%9s", emp.bday.month) != 1)
            return EXIT_FAILURE;
        
        printf("\n\nName: %s\nID: %d\nSalary: %.2f\n", emp.name, emp.id, emp.salary);
        printf("Birthday: %d %s %d\n", emp.bday.day, emp.bday.month, emp.bday.year);
        
        printf("\n------------------------------------\n");
    }
    return EXIT_SUCCESS;
}
chqrlie
  • 131,814
  • 10
  • 121
  • 189
  • thank you for your feedback. I changed `scanf` like you said but to make it work i also add a `getchar()` after `scanf("%9s",emp.bday.month)` – Luís Oliveira Feb 15 '21 at 11:58
  • 1
    @LuísOliveira: the `getchar()` should not be necessary if you have an initial space before the `%` in the format string: `scanf(" %14[^\n]", emp.name)`. – chqrlie Feb 15 '21 at 21:05