0

I am entering valid name Steve xyz @ //1 then also it is showing invalid name @ //2. I am unable to compare the name in structure and name inputted by user.

user63555
  • 17
  • 3

4 Answers4

1

fgets() reads also the newline ('\n') character at the end of the buffer (when possible). a newline is added when you press Enter at the console and it will make the comparison fails. from man fgets:

Reading stops after an EOF or a newline. If a newline is read, it is stored into the buffer. A terminating null byte ('\0') is stored after the last character in the buffer.

so the content of empName array for input "Steve xyz" will likely to be:

['S', 't', 'e', 'v', 'e', ' ', 'x', 'y', 'z', '\n', '\0', ...garbage]

here a rewrite of the code, basically you have to remove '\n' if it's there. there was also a problem in the initialization of the struct array:

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

struct employee {
        int cardNo;
        char name[20];
        long salary;
        int age;
} emp[20] = {
        {0, "John Doe", 6500, 25},
        {1, "Steve xyz", 7000, 30},
        // initialize here other 18 structs if needed
};

int main(void)
{
        char empName[30];
        printf("Enter your name\n");

        char *ret = fgets(empName, 30, stdin);
        if (ret == NULL) {
                printf("Error while reading name\n");
                return 1;
        }

        // remove eventual trailing newline replacing it with '\0'
        empName[strcspn(empName, "\n")] = '\0';

        if (!(strcmp(empName,emp[1].name))) {      // 1
                // I don't know why you do this...
                strcpy(empName, "Steve xyz");
        } else {
                printf("Invalid name\n");          // 2
        }
}

edit: changed newline removal approach using strcspn() (thanks to @AndrewHenle in the comments) which seems to be a perfect fit for this task. from man strcspn:

size_t strcspn(const char *s, const char *reject);

calculates the length of the initial segment of s which consists entirely of bytes not in reject. returns the number of bytes in the initial segment of s which are not in the string reject.

MarcoLucidi
  • 2,007
  • 1
  • 5
  • 8
  • 1
    [`empName[strcspn(empName, "\n")] = 0;`](https://stackoverflow.com/a/28462221/4756299) – Andrew Henle Jun 21 '20 at 19:56
  • @AndrewHenle wow I didn't know about this function! this is a much cleaner solution, I think I'm going to edit the answer and use `strcspn()` – MarcoLucidi Jun 22 '20 at 17:47
0

fgets reads the characters from the input stream and also a newline character. So you need to remove the newline character from the empName and this can be done by:

empName[strlen(empName) - 1] = '\0';
Sai Sreenivas
  • 1,690
  • 1
  • 7
  • 16
  • 1
    If `empName` is `""` (zero-length string) this invokes undefined behavior. – Andrew Henle Jun 21 '20 at 19:55
  • Sorry, but I didn't find any problem when empName is an empty string. Can you please re-confirm this? – Sai Sreenivas Jun 22 '20 at 04:43
  • IF `empName[0]` is `'\0'`, (zero-length string or `""`) `strlen(empName)` is `0` and the code tries to set `empName[ -1 ] = '\0'`. That's undefined behavior. – Andrew Henle Jun 22 '20 at 13:53
  • Actually, If we input empty string then as a newline character will be added to it the last character will be '\n' so there won't be any problem right? – Sai Sreenivas Jun 22 '20 at 13:59
  • 1
    Not always. `CTRL-Z` on Windows or `CTRL-D` can be used to close the terminal and send an string with no terminating linefeed. There are probably other ways. And if the line is long enough that it fills the buffer, it won't be terminated with a linefeed either. – Andrew Henle Jun 22 '20 at 14:08
0
#include <stdio.h>
#include <string.h>

typedef struct employee
{
    int cardNo;
    char name[20];
    long salary;
    int age;
} Employee;


int main()
{
    char empName[30];
    Employee emp[20];

    emp[1].age = 30;
    emp[1].salary = 7000;
    emp[1].cardNo = 1;
    strcpy(emp[1].name, "Steve xyz");
    
    int len = strlen(emp[1].name);
    emp[1].name[len] = '\n';

    printf("Enter your name\n");
    fgets(empName, 30, stdin);


    if (!(strcmp(empName, emp[1].name))) //1
    {
        strcpy(empName, "Steve xyz");
    }
    else
    {
        printf("Invalid name\n"); //2
    }
}


bekici
  • 68
  • 10
0

Tha fact is fgets() is reading also the \n char, so you have to do this after using fgets()

   size_t len = strlen(empName);

    if (len > 0 && empName[len-1] == '\n') {
        empName[--len] = '\0';
    }

With this we delete the \n, and now the comparison will determinate that are equals

Josep
  • 162
  • 1
  • 9