0

I want to compare string user input and a string from textfile.

I am comparing the value of the uname and the current value of the storage. It goes inside the while loop but when they match, it doesn't proceed to the if block which supposed to do the test if the storage and uname have the same value.

void compare()
{
   char uname[20];
   FILE *list = fopen("list.txt","a");

   if(list == NULL)
   {
      printf("Textfile doesn't have any content\n");
   }

   printf("Enter username: ");
   scanf("%s",&uname);
   fprintf(list,"%s\n",uname);
   fclose(list);

   list = fopen("listahan.txt","r");

   char storage[50]; //storage of the string that I will get from the textfile

   if(list != NULL) //check if list have content
   {
       while((fgets(storage,sizeof(storage),list) != NULL)) //if list have content, get it line by line and compare it to the uname.
       {
          printf("storage:%s\n",storage); // for debug, checks the current value of storage
          printf("uname:%s\n",uname); //for debug, checks the value of uname

          if(storage == uname) //this if block is being ignored, even when the storage and uname match, the block does not execute.
          {
             printf("Login Success!\n");
          }
    }
}
Albert
  • 19
  • 4
  • I suspect that you might have line breaks at the end of your lines that you read from your file! – csabinho Sep 22 '19 at 03:45
  • write something like perl's chomp to strip '\n' or '\r\n' from end of line read using fgets. You an also use fgets(storage,sizeof(storage),stdin) followed by chomp(storage) and strncpy(uname,storage,sizeof(uname)-10), rather than scanf... – ChuckCottrill Sep 22 '19 at 03:50
  • `char uname[20];`, see [C11 Standard - 6.3.2.1 Other Operands - Lvalues, arrays, and function designators(p3)](http://port70.net/~nsz/c/c11/n1570.html#6.3.2.1p3), `uname` is already a pointer, so there is no `&` required in `scanf("%s",&uname);`. – David C. Rankin Sep 22 '19 at 04:56

2 Answers2

1

While inputting a character array, you need not specify &uname, Why doesn't scanf need an ampersand for strings and also works fine in printf (in C)?

Correct it to make:

scanf("%s",uname);

Remaining corrections:

if(list != NULL) //check if list have content
{
    while(fgets(storage,sizeof(storage),list) != NULL) //if list have content, get it line by line and compare it to the uname.
    {
        if (*storage == '\n') 
            continue;
        sscanf(storage, "%[^\n]", storage);
        printf("storage:%s\n",storage); // for debug, checks the current value of storage
        printf("uname:%s\n",uname); //for debug, checks the value of uname

        if(!strcmp(storage, uname)) //this if block is being ignored, even when the storage and uname match, the block does not execute.
        {
            printf("Login Success!\n");
        }
    }
}

Also, you could simply have use fscanf() instead of fgets but its a pretty bad idea, read the first answer in Trouble reading a line using fscanf()

So first you fgets() to store value in storage.

As stated in the manpage:

fgets() reads in at most one less than size characters from stream and stores them into the buffer pointed to by s. Reading stops after an EOF or a newline. If a newline is read, it is stored into the buffer. A terminating null byte (aq\0aq) is stored after the last character in the buffer.

In short reading would stop if newline is encountered but it would also be stored.

So "username" != "username\n". That's why we sscanf() the string again into same string to read till \n only.

Also to compare character arrays, you need to use strcmp(). == would work if you are comparing char *.

Mihir Luthra
  • 6,059
  • 3
  • 14
  • 39
  • You can also simply trim the `'\n'` with `storage[strcspn (storage, "\n")] = 0;`. If you are using `sscanf` (which is fine), you do need to check the return, e.g. `if (sscanf (..) != 1) { /* handle error */ }` as `fgets` will happily read an empty line storing only `'\n'` which if you don't check the `sscanf` return may surprise you. – David C. Rankin Sep 22 '19 at 04:42
  • @DavidC.Rankin, will there be a need, because if `storage` is empty, `strcmp` simply won't match and continue to next line. Is there someother reason too? Thanks. – Mihir Luthra Sep 22 '19 at 04:50
  • You are correct, there will be no error, you will just be outputting and comparing an *empty-string* which may not be desirable. You can also just check `if (*storage == '\n') continue;` immediately after your call to `fgets` before the `sscanf`. – David C. Rankin Sep 22 '19 at 04:53
  • @DavidC.Rankin, makes sense, I made the changes, thanks. – Mihir Luthra Sep 22 '19 at 05:20
0

You are comparing address of storage array with address of uname array.It is always false. You have to use strcmp(storage,uname) in condition to compare string of both arrays.