strcmp returns 错误值
strcmp returns wrong value
谁能解释一下为什么 strcmp
returns 即使密码是 correct/incorrect 也是一样的值?我在包含部分下面定义了有效密码,并在我的程序结束时用输入的密码检查它。
这是我的代码:
#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");
}
}
您忘记将 \n
替换为 NUL
...
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
将不匹配。
因此,null
如果您发现 \n
如下所示,则终止输入。
if (password[i] == '\n')
{
password[i] = '[=10=]';
break;
}
您已经声明 strcmp()
表示两个 字符串 相等,当您知道它们不相等时...
其他答案中提到的\n
的问题不成立,如果您确实看到strcmp()
return错误的指示,问题就变成了为什么?
在 C 中,string
被定义为 null
终止的字符数组。因此,例如,如果您有以下内容:
char password[MAXPASSWORD] = {0};//where MAXPASSWORD == 12
|p|a|s|s|1|2|3|[=10=]|[=10=]|[=10=]|[=10=]|[=10=]| // `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|[=11=]| // 'password' - too long by 1 character
^ // end of legal definition of `password`
如果 password
数组有太多字符,即使在这种情况下,在 beyond[=48] 的位置将最后一个 char
\n
替换为 NULL =] 字符串的合法定义,代码变为undefined behavior.
字符串函数专门用于 strings
。当出现非 nul 终止的字符数组时,函数(在本例中为 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()
会指出。
谁能解释一下为什么 strcmp
returns 即使密码是 correct/incorrect 也是一样的值?我在包含部分下面定义了有效密码,并在我的程序结束时用输入的密码检查它。
这是我的代码:
#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");
}
}
您忘记将 \n
替换为 NUL
...
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
将不匹配。
因此,null
如果您发现 \n
如下所示,则终止输入。
if (password[i] == '\n')
{
password[i] = '[=10=]';
break;
}
您已经声明 strcmp()
表示两个 字符串 相等,当您知道它们不相等时...
其他答案中提到的\n
的问题不成立,如果您确实看到strcmp()
return错误的指示,问题就变成了为什么?
在 C 中,string
被定义为 null
终止的字符数组。因此,例如,如果您有以下内容:
char password[MAXPASSWORD] = {0};//where MAXPASSWORD == 12
|p|a|s|s|1|2|3|[=10=]|[=10=]|[=10=]|[=10=]|[=10=]| // `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|[=11=]| // 'password' - too long by 1 character
^ // end of legal definition of `password`
如果 password
数组有太多字符,即使在这种情况下,在 beyond[=48] 的位置将最后一个 char
\n
替换为 NULL =] 字符串的合法定义,代码变为undefined behavior.
字符串函数专门用于 strings
。当出现非 nul 终止的字符数组时,函数(在本例中为 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()
会指出。