【问题标题】:strcmp with pointers not working in C带有指针的 strcmp 在 C 中不起作用
【发布时间】:2012-10-26 12:41:24
【问题描述】:

为什么这段代码不起作用。只是尝试检查用户输入是否与密码相同

char *pass;

printf("Write the password: ");
scanf("%s", pass); // Because is a pointer the & is out ?


if( strcmp( pass , "acopio") == 0)

【问题讨论】:

  • 为什么是 -1 ?我在学;试图在这里找到答案;对于初学者来说,其他答案并不容易理解。

标签: c pointers strcmp


【解决方案1】:
#include<stdio.h>
main()
{
    int mystrcmp(char *,char *);

    char s1[100],s2[100];
    char *p1,*p2;
    p1=s1;
    p2=s2;
    printf("Enter the first string..?\n");
    scanf("%s",p1);
    printf("Enter the second string..?\n");
    scanf("%s",p2);
    int x=mystrcmp(p1,p2);
    if(x==0)
        printf("Strings are same\n");
    else
        printf("Strings are not same..\n");


}
int mystrcmp(char *p1,char *p2)
{
    while(*p1==*p2)
    {
        if(*p1=='\0' || *p2=='\0')
            break;
        p1++;
        p2++;
    }
    if(*p1=='\0' &&as *p2=='\0')
        return(0);
    else
        return(1);
}

适合初学者的简单代码....

【讨论】:

    【解决方案2】:

    您实际上并没有分配任何空间来放置数据。定义指针只是定义了一个可以保存数据块地址的变量,并不分配数据块。

    您有几个选择,从堆中分配动态内存以写入并让指针指向它。或者在堆栈上使用静态分配的内存并将其地址传递给您的调用。在这种情况下,动态内存几乎没有什么好处(因为它是临时使用的并且很小)。如果你使用动态内存,你会有更多的工作要做——你必须确保在分配它时得到了你所要求的,并确保在完成后将其归还并确保你不使用它在您归还它之后(在大型应用程序中很棘手,相信我!)这只是更多的工作,而且您似乎不需要额外的努力。

    下面的例子也需要大量的错误检查,但给你一个大致的想法。

    例如

    char *pass = malloc (SOMESIZE);
    
    printf("Write the password: ");
    scanf("%s", pass);
    
    
    if( strcmp( pass , "acopio") == 0)
    

    char pass[SOMESIZE];
    
    printf("Write the password: ");
    scanf("%s", pass);
    
    
    if( strcmp( pass , "acopio") == 0)
    

    【讨论】:

    • 非常清楚。您忘记了第二个选项 scanf 中的 &。不明白为什么使用动态内存(堆)比使用静态内存(堆栈)更好。哪个更小?
    • scanf 调用不需要与符号,因为引用没有任何索引的数组地址,即 pass == &pass[0]
    • @Joe 例如,不是 /grammer-nazi
    【解决方案3】:

    您尚未初始化 pass 以指向缓冲区或其他位置来存储输入。

    对于这样简单的事情,您可以将pass 声明为char 的数组而不是指针:

    char pass[N]; // where N is large enough to hold the password plus a 0 terminator
    
    scanf("%s", pass);
    if (strcmp(pass, "acopio") == 0)
    {
      ...
    }
    

    除非它是sizeof_Alignof 或一元&amp; 运算符的操作数,或者是用于在声明中初始化另一个数组的字符串文字,表达式T”类型的“N 元素数组”将被转换(“衰减”)为“指向T”的类型的表达式,表达式的值将是数组第一个元素的地址.

    当您将pass 作为参数传递给scanfstrcmp 时,表达式 pass 的类型从“char 的N 元素数组”转换为“指向char的指针”,表达式的值是pass的第一个元素的地址,或者&amp;pass[0]。这就是为什么您不需要在 scanf 调用中使用 &amp; 运算符的原因。

    同样,在strcmp 调用中,字符串文字“acopio”从“char 的7 元素数组”(C++ 中的const char)类型的表达式转换为“指向char 的指针” .

    【讨论】:

      【解决方案4】:

      是的,指针未初始化。如果你调试它,你会得到一个access violation or segmentation fault。 代码可以改成如下。

       char pass[22];//22 can be replaced with other number
      
          printf("Write the password: ");
          scanf("%s", pass); 
          if( strcmp( pass , "acopio") == 0)
          printf("fu");//just to check
      

      【讨论】:

      • @Daveshaw:我想发布相同的内容,但 stackoverflow 不允许我保存编辑
      【解决方案5】:

      您需要分配pass 以便scanf 将有一个地方来存储输入。否则你有内存损坏。

      【讨论】:

        【解决方案6】:

        pass 是一个未初始化的指针,您尝试写入它。您必须分配足够的内存来保存字符串。例如,char pass[SIZE] 会更好。

        【讨论】:

        • 确实如此。注意你也可以使用动态分配(带有指向char的指针),但是在这里没用。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-02-08
        • 2016-07-17
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多