почему я не могу сравнить эти массивы в файлах и что я читаю, чтобы создать систему входа в систему? - PullRequest
0 голосов
/ 03 апреля 2019

Функция strcmp() не работает. Имя пользователя, которое я читаю из консоли, не совпадает с тем, которое у меня есть в файле. Таким образом, вывод неправильный идентификатор. Какое решение?

  #include<stdio.h>       
  #include<stdlib.h>        
  #include<string.h>       
  int main()         
  {    
   FILE *pass;     
   char str[100],str2[100];     
   char id[100],pw[100];        
   pass=fopen("password.txt","r");         
   printf("ENTER USER NAME AND PASSWORD:\n");        
   printf("USERNAME: ");       
   gets(id);            
   printf("\nPASSWORD: ");         
   gets(pw);       
   while(fgets(str,100,pass)!=NULL);            
   {        
    fgets(str2,100,pass);      
    if(strcmp(id,str)==0)       
    {       
      if(strcmp(pw,str2)==0)         
      {       
        printf("ACCEPTED\n");            
      }       
      else       
      {        
        printf("wrong password");          
       }        
   }        
   else         
    {          
      printf("wrong id");           
    }           
    }    
    fclose(pass);    
   }          

Ответы [ 2 ]

2 голосов
/ 03 апреля 2019

Прежде всего, никогда не используйте gets(), используйте fgets() всегда.

При этом fgets() читает и сохраняет завершающий символ новой строки в целевом буфере.

С C11, глава 7.21.7.2

Функция fgets считывает самое большее на единицу меньше, чем количество символов, указанное в n, из потока, на который указывает поток, в массив, на который указывает s. Никакие дополнительные символы не читаются после символа новой строки (который сохраняется) или после конца файла. Нулевой символ записывается сразу после последнего прочитанного в массив символа.

Вам следует избавиться от этой новой строки перед использованием отсканированного значения. Вот один из способов сделать это .

0 голосов
/ 03 апреля 2019

Вы должны проверить, был ли fopen() успешным, прежде чем получить доступ к файлу, который программа пыталась открыть.

fopen() возвращает NULL в случае ошибки.Так что делайте что-то вроде

pass=fopen("password.txt","r");         
if( pass==NULL )
{
    perror("Unable to open input file.");       
}
else
{
    // Use the file 
}

И gets() известно о серьезных проблемах безопасности.Смотрите это .

Желательно использовать fgets() вместо stdin в качестве аргумента.Поэтому вместо

gets(id);            

try

if( fgets(id, sizeof(id), stdin)!=NULL )
{
    id[ strlen(id)-1 ] = '\0';
    // Use `id` 
}   

Значение, возвращаемое fgets(), также проверяется, чтобы убедиться, что fgets() прошло успешно.Он возвращает NULL при ошибке.

Следует отметить, что fgets() будет также читать в конце \n из стандартного ввода.

Вы можете удалить это дополнительное \n с помощьюпомощь такой функции, как strlen().Смотрите обсуждение удаления лишней новой строки здесь .

Используйте то же самое при чтении в pw.

Предполагая, что ваш входной файл имеет идентификатор в одномстрока и соответствующий пароль в строке после этого, вы можете сделать что-то вроде

char flag=0;
while(fgets(str, sizeof str, pass)!=NULL && fgets(str2, sizeof str2, pass)!=NULL)
{
    str[ strlen(str)-1 ] = '\0';
    str2[ strlen(str2)-1 ] = '\0';
    if( strcmp(str, id)==0 )
    {
        flag=1;
        if( strcmp(str2, pw)==0 )
        {
            printf("ACCEPTED\n");            
        }
        else 
        {
            printf("wrong password.");
        }
        break;
    }
}
if(flag==0) 
{
    printf("Wrong id.");    
}

Читать две строки одновременно и проверить, успешны ли обе перед каждой итерацией цикла, чтобы убедиться, что правильные значения были прочитаны.

Возможно, вы захотите выйти из цикла, как только обнаружите, что пароль неверен.

Вы также можете использовать переменную flag, чтобы проверить, был ли введенный идентификатор, действительным, и напечататьсоответствующее сообщение в конце.

...