2015-11-07 222 views
-8

我想创建一个可以打开密钥的程序。但是,当我比较关键和输入,它总是说“错”:与其他字符串进行比较

#include <stdio.h> 

int main(){ 
    char key[5]="april",ckey[5]; 
    printf("Enter the key: "); 
    scanf("%s",ckey); 
    if(ckey==key){ 
     printf("Correct."); 
    } 
    else{ 
     printf("Wrong."); 
    } 
    return 0; 
} 

是否有可能解决的问题,而无需使用其他图书馆?

+1

撰写您自己的'strcmp'版本 –

+3

您的字符串溢出阵列。 –

+1

C中的字符串需要终止空值。所以如果字符串有5个字符,你需要至少6个'char'位置来保存它。 – lurker

回答

2

你必须逐字检查字符。 试试这个代码:

int main(){ 
    int i = 0 ; int j = 1; 
    char key[6]="april",ckey[6]; 
    printf("Enter the key: "); 
    scanf("%s",ckey); 
    for(i = 0; i < 6; i++){ 
     if(ckey[i] != key[i]) 
      j=0; 
    } 
    if(j == 1) 
     printf(%s,"Correct."); 
    else 
     printf(%s,"Wrong."); 
    return 0; 
} 
+0

'char key [5] =“april”'溢出'key'缓冲区。 – lurker

+0

是的,你说得对。他需要将密钥声明为6个字符的字符串。 – Farhood

+1

使阵列足够大实际上是一个好主意。尽管如此,一个有限的缓冲区本身对于无界输入来说还不够大,而且你没有纠正这个问题。 – Deduplicator

-6

if语句

if(ckey==key){ 

有比较了数组所占用的内存区的两个地址的条件。

所以你总是会因为阵列占用不同的内存区域而变得错误。

如果您不能使用其他标准功能,例如strncmpmemcmp在头<string.h>声明,那么你可以写下面的方式

#include <stdio.h> 

int main(void){ 
    char key[5]="april",ckey[6]; 
    printf("Enter the key: "); 
    scanf("%5s",ckey); 

    size_t i = 0; 

    while (i < sizeof(key) && key[i] == ckey[i]) ++i; 

    if(i == sizeof(key)){ 
     printf("Correct."); 
    } 
    else{ 
     printf("Wrong."); 
    } 
    return 0; 
} 

而不是scanf这将是更好地使用fgets。在这种情况下,必须增加数组ckey的大小。

这个声明

char key[5]="april"; 

是完全有效的用C虽然是不是在C++中有效。:)

+5

我以为''四月''是6个字节,因此将它分配给堆栈中分配的'char key [5]'会溢出,并在某处写入''\ 0',否则? – Siguza

+0

@Siguza首先,答案是完全正确的。至于你的问题,那么编译器使用字符串文字初始化数组。它将使用与数组元素对应的字符串字符的字符。字符串文字要么在静态存储期间分开存储,要么甚至不存储并仅用于初始化。我在我的文章中写道,它在C中的初始化是正确的。 –

+0

如果用户在“输入密钥:”提示中键入“aprilx”,则在回答中显示的代码显示“正确”。 – lurker

2

你有 “%S” 的scanf语句中之前,留出空间,使“ \ n字符未存储在ckey以确保比较成功。注:ckey必须具有6或更大的大小。

#include <stdio.h> 
#include <string.h> 

int main(){ 
    char key[] = "april",ckey[6]; 
    printf("Enter the key: "); 
    scanf(" %5s",ckey); 
    if(!strcmp(ckey, key)){ 
     printf("Correct."); 
    } 
    else{ 
     printf("Wrong."); 
    } 
    return 0; 
} 
+1

更改scanf以限制输入字符串的长度 –

+1

模式中的空格将是多余的。使数组足够大虽然实际上是一个好主意。尽管如此,一个有限的缓冲区本身对于无界输入来说还不够大,而且你没有纠正这个问题。 – Deduplicator

+0

回滚的问题,请看看。 – Deduplicator

1

您在为您的密钥设置阵列大小时犯了几个错误。请记住,一个C字符串总是由一个空字符终止,并且当您将数组放大到接受这样的字符串时,您必须对此进行解释。

scanf是不安全的,请不要使用它。改用fgets。一个安全的使用与fgets的是:

fgets (buffer, sizeof(buffer), stdin); 

的回答你的问题是否定的,这将是更好地使用STRCMP如果你想词法用C比较字符串,并且将涉及包括头部。但即便如此,由于fgets和strcmp在相同的标准C库中,因此不会添加任何其他“库”。

如果你不能添加任何其他的头文件(如果这是一个大型项目的一部分,这是没有意义的,但如果这是一个家庭作业问题,这是非常有意义的),那么你可以编写自己的strcmp(我们称之为比较在这里)并从main调用它。

#include <stdio.h> 

int compare (const char* src, const char* dst) 
{ 
    int ret = 0; 
    while(! (ret = *src - *dst) && *dst){ 
     ++src, ++dst; 
    } 
    if (ret < 0) 
     ret = -1 ; 
    else if (ret > 0) 
     ret = 1 ; 
    return(ret); 
} 

    int main(void){ 
    char key[6]="april",ckey[6]; 
    printf("Enter the key: "); 
    fgets(ckey, sizeof ckey, stdin); 

    if(!compare(key,ckey)) { 
     printf("Correct."); 
    } 
    else { 
     printf("Wrong."); 
    } 
    return 0; 
} 

更好地利用你的时间将是使用标准C库为您提供的功能,把它写:

#include <stdio.h> 
#include <string.h> 

int main(void){ 
    char key[6]="april",ckey[6]; 
    printf("Enter the key: "); 
    fgets(ckey, sizeof ckey, stdin); 

    if(!strcmp(key,ckey)) { 
     printf("Correct."); 
    } 
    else { 
     printf("Wrong."); 
    } 
    return 0; 
} 

但是,即使这个解决方案有一个缺陷。它将接受“aprilaaaa”或以“april”开头的任何字符串作为有效的ckey。你能解释为什么吗?你会如何解决这个问题?

相关问题