[英]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
存入您的輸入緩沖區,這樣pass123
和pass123\\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.