1

This is the program i have written can anyone tell what is wrong with it, because whatever input i give, it shows valid user.

#include<stdio.h>
#include<string.h>
#define max_size 20
void main()
{
 File *Fptr;
 char username[max_size];
 char line[20];
 if((fptr=fopen("/etc/passwd","r"))==NULL)
 { 
   printf("cannot open file");
 }
 else
  {
      fptr=fopen("/etc/passwd","r");
      fputs("enter the username",stdout);
      fflush(stdout);
      fgets(username,sizeof username,stdin);
      while((fgets(line,sizeof(line),fptr))!=NULL)
      { 
          if(strcmp(line,username))
          {
             printf("%s valid user",username);
             break; 
          }
          else
            {
              printf("%s not valid user",username);
            }    
      } 
   fclose(fptr);
  }
}
Tyler McHenry
  • 74,820
  • 18
  • 121
  • 166
suhel
  • 733
  • 1
  • 6
  • 5

6 Answers6

6

Could you use getpwent for this task?

see: getpwent(3) and opengroup's getpwent

and

Regards

rbo

Community
  • 1
  • 1
rubber boots
  • 14,924
  • 5
  • 33
  • 44
3

strcmp is a three-way comparator. It tells you if the strings are equal or if the first string is lexicographically less or greater than second.

Because of this, its results are a bit unintuitive when used as booelan values. It returns 0 when the strings match, which evaluates to false in an if statement. It returns nonzero values, usually -1 or 1, (all of which evaluate to true) when the strings are different.

If you want to test if two strings are the same, you should change

if(strcmp(line,username))

to

if(strcmp(line,username) == 0)

Also take note of Starkey's answer about the extra contents of lines in /etc/passwd. If you make only the change above, your program will always return "not a valid user".

Tyler McHenry
  • 74,820
  • 18
  • 121
  • 166
  • if i put the condition as you said it shows me the "else" part i.e. not valid what should i do – suhel Aug 25 '10 at 16:03
  • Like I said, that change is necessary but not sufficient to make your program work. You have to separate the username from the other information on the line that you read from /etc/passwd. If you're trying to learn how to parse text, look into `strtok`, but if you're just trying to get something done, you should instead use the POSIX APIs for getting information out of /etc/passwd, which rubber boots linked to. – Tyler McHenry Aug 25 '10 at 16:14
3

Instead of trying to parse /etc/passwd manually, you might want to use getpwnam instead.

Hasturkun
  • 35,395
  • 6
  • 71
  • 104
2

strcmp returns 0 (which is false) if the two strings are exactly equivalent, or a non-zero number (which is true) if the strings differ at all.

So firstly, you appear to have your if-test the wrong way around. Secondly, you need to test just the leading n characters, where n is the length of the username. Off the top of my head, I suggest you try replacing your if-test with:

if (!strncmp(line, username, strlen(username))
Chowlett
  • 45,935
  • 20
  • 116
  • 150
1

strcmp compares the whole line in the passwd file with what you have entered. The passwd file contains more than just the user name on each line (look at a passwd file to see what I'm talking about).

Starkey
  • 9,673
  • 6
  • 31
  • 51
0

Aside from the fact that your strcmp test condition is wrong as others have already pointed out, lines in the passwd file contain more than just the username. You could use strstr to see if the name is present in a particular line.

if(strstr(line, username) == line)
{
    /* valid user */
}
bstpierre
  • 30,042
  • 15
  • 70
  • 103