-2
#include <stdio.h>
#include <string.h>
#define N 5

char username[N+3][20]={"ana","sofia","maria","isabel","joao","hugo","francisco","pedro"};
char str[20];

read_username()
{
    printf("Insert your username: ");
    gets(str);
}

void searchusername(int n)
{
    int i;
    for(i=0;i<=n;i++)
    {
        if(strstr(username[i], str) != NULL)
            printf("username exists")
    }
}

int main()
{
    read_username();
    searchusername(8);
} 

I have the code to check if username exists, but i can´t seem to turn it around so i only get the printf when username doesn't exist, any other way without using NULL is also okay, ty.

hyde
  • 60,639
  • 21
  • 115
  • 176
  • 3
    `gets` doesn't remove the trailing newline character, so your string will contain it, and hence not match any of the names. Also, ***do NOT ever, EVER use `gets()` because it is unsafe!*** Use `fgets()` instead. And format your code because it looks horrible. – The Paramagnetic Croissant Nov 08 '14 at 20:00
  • Note that your loop goes from 0 to 8 here, while your array only has indexes 0...7. – hyde Nov 08 '14 at 20:02
  • @hyde you're right actually, but this is a duplicate. Not even a duplicate, rather an `N + 1`-licate. Hence it should be dupe-closed instead of being answered (which would encourage OP to keep ignoring the debugger and the documentation next time again.) – The Paramagnetic Croissant Nov 08 '14 at 20:05
  • possible duplicate of [Removing trailing newline character from fgets() input](http://stackoverflow.com/questions/2693776/removing-trailing-newline-character-from-fgets-input) – hyde Nov 08 '14 at 20:08
  • 1
    @TheParamagneticCroissant True enough... But I don't think providing an answer in comment is any better than providing an actual answer, even for duplicates. Anyway, now I searched for a question which should provide answer to the question. – hyde Nov 08 '14 at 20:09
  • @hyde Thank you. I was commenting so that even if OP doesn't make the effort to read the dupe, he would still hear me shouting "don't use gets!". Security and correctness is more precious than anything. I'd rather have someone write code that does not have a buffer overflow vulnerability *and* not learn anything than have someone write vulnerable code (and not learn anything at the same time). – The Paramagnetic Croissant Nov 08 '14 at 20:09
  • @TheParamagneticCroissant Umm, except... `gets` removes the newline, actually, doesn't it. That's one of the things to take care of when converting `gets` to `fgets`. Of course, since `gets` luckily is not used in real code any more (I hope...), it's easy to forget these details. – hyde Nov 08 '14 at 20:12
  • @hyde yep, so I was *even* wrong. It's actually good that I didn't answer then :P – The Paramagnetic Croissant Nov 08 '14 at 20:13
  • 1
    Are you sure you are learning C++ and not some other language? – n. m. could be an AI Nov 08 '14 at 20:15

2 Answers2

0

Your compare failed because of the '\n' character.

When using gets and fgets you should trim the input.

You can use function like this:

#include <ctype.h> //for isspace
char* trim(char *input_string)
{
  int i=0;
  char *retVal = input_string;
  i = strlen(input_string)-1;
  while( i>=0 && isspace(input_string[i]) ){
      input_string[i] = 0;
      i--;
  }
  i=0;
  while(*retVal && isspace(retVal[0]) ){
    retVal ++;
  }
  return retVal;
}
SHR
  • 7,940
  • 9
  • 38
  • 57
  • Still, OP really should convert their code to use `fgets`, and then this would be useful. – hyde Nov 08 '14 at 20:34
  • @hyde you should trim because you may have spaces at the beginning or at the end. – SHR Nov 08 '14 at 20:43
  • 2
    @SHR Maybe, depends on the requirements. For names, almost certainly yes. But then, for even better UX, it might be good to also reduce all internal whitespace sequences to one SPC. – hyde Nov 08 '14 at 20:45
0

One issue is that you are not avoiding a buffer overflow with gets(). I have to assume for this example that you are typing in short usernames that do not exceed 19 characters. Anything longer is going to cause problems if you don't account for it.

More importantly, you are not comparing the usernames correctly. You should not be using strstr() for that purpose. It searches for a substring inside of another string, it does not compare strings. For example, if you typed in ia, strstr() would match with both sofia and maria, both of which are wrong results for a username lookup. Use strcmp() for comparisons.

Try something more like this instead:

#include <stdio.h>
#include <string.h>
#define N 8

char* username[N] = {"ana", "sofia", "maria", "isabel", "joao", "hugo", "francisco", "pedro"};
char str[20] = {0};

void read_username()
{
    printf("Insert your username: ");
    if (fgets(str, 20, stdin))
    {
        int len = strlen(str);
        if ((len > 0) && (str[len-1] == '\n'))
            str[len-1] = '\0';
    } 
}

void searchusername()
{
    for(int i = 0; i < N ; i++)
    {
        if (strcmp(username[i], str) == 0)
        {
            printf("username exists");
            return;
        }
    }
    printf("username does not exist");
}

int main()
{
    read_username();
    searchusername();
} 
Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
  • I don't think answering with modified code without explaining any of the changes is useful... – hyde Nov 08 '14 at 20:37
  • Thank you all, its my first post here so i apologize for my code format, i understood most of Remy Lebeau's code only line i didnt get was (str[len-1] == '\n') , is this because of "trailing newline character"? – Francisco Silva Nov 08 '14 at 21:20
  • @FranciscoSilva: Yes, it is checking to see if the last character read into `str` is a newline, and if so then replaces it with a null terminator. – Remy Lebeau Nov 08 '14 at 23:17