簡體   English   中英

strcmp返回錯誤的值

[英]strcmp returns wrong value

有人可以解釋為什么即使密碼正確/不正確, strcmp也會返回相同的值嗎? 我在下面包含部分定義有效密碼,並在程序結束時使用輸入的密碼進行檢查。

這是我的代碼:

#include <stdio.h>
#include <signal.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
#include <termios.h>

#define TIME 10
#define MAXPASSWORD 12
#define PASSWORD "pass123"

void sigalrm_handler() {
    printf("\nERR: Time is up...\n");
}

int getch() {
    struct termios oldtc, newtc;
    int ch;
    tcgetattr(STDIN_FILENO, &oldtc);
    newtc = oldtc;
    newtc.c_lflag &= ~(ICANON | ECHO);
    tcsetattr(STDIN_FILENO, TCSANOW, &newtc);
    ch=getchar();
    tcsetattr(STDIN_FILENO, TCSANOW, &oldtc);
    return ch;
}

int main(int argc, char * argv[]) {
    char password[MAXPASSWORD] = {0};
    printf("Enter correct password. You have %d seconds: ", TIME);
    signal(SIGALRM, sigalrm_handler);
    alarm(TIME);
    fflush(stdout);

    for(int i=0; i<MAXPASSWORD; i++)
    {
      password[i] = getch();
      if (password[i] == '\n')
        break;
      printf("*");
    }

    if (strcmp(password, PASSWORD) == 0) {
        printf("\nValid password\n");
    } else {
        printf("\nInvalid password\n");
    }
}

你忘了用NUL替換\\n

...
for(int i=0; i<MAXPASSWORD; i++)
{
  password[i] = getch();
  if (password[i] == '\n')
  {
    password[i] = 0;   // <<<< add this line
    break;
  }
  printf("*");
}
...

還有一個問題:考慮如果用戶在按Enter鍵之前輸入超過11個字符會發生什么。 我讓你發現自己是一個練習。

問題是你有\\n存入您的輸入緩沖區,這樣pass123pass123\\n將不匹配。

因此,如果您發現如下所示\\n ,則null終止輸入。

  if (password[i] == '\n')
  {
     password[i] = '\0';
     break;
  }

你已經聲明strcmp()表示兩個字符串是相等的,當你知道它們不是......

在其他答案中提到的\\n問題無法解決,如果你確實看到strcmp()返回錯誤的指示,問題就變成了原因?

在C中, string被定義為null終止字符數組。 因此,例如,如果您有以下內容:

char password[MAXPASSWORD] = {0};//where MAXPASSWORD == 12

|p|a|s|s|1|2|3|\0|\0|\0|\0|\0| // `PASSWORD ` - legal string
|s|o|m|e|p|a|s|s|1|2|3|4|\n|  // 'password' 

即使在替換\\n字符后,這個數組太長了一個字符:

|s|o|m|e|p|a|s|s|1|2|3|4|\0|  // 'password' - too long by 1 character
                        ^     // end of legal definition of `password`

如果password數組的字符太多,即使在這種情況下,在超出字符串的合法定義的位置替換最后一個char \\n和NULL之后,代碼也會受到未定義的行為的影響

字符串函數專門用於strings 當呈現非空終止字符數組時,函數(在本例中為strcmp() ,因為它正在尋找nul終止符以知道字符串結尾的位置,因此不能期望其具有可預測性。 (在這種情況下, nul字符的位置將是未定義行為的原因。)

為了防止這種情況發生,即使用戶能夠在password輸入太多字符,也總是以如下語句終止:

password[MAXPASSWORD-1] = 0;  //for a properly initialized array, (as your code indicates)
                              //this guarantees termination occurs 
                              //within legal memory area of defined variable. 

有了這個,就沒有未定義的行為,如果字符串不同, strcmp()將表明這一點。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM