【问题标题】:c read string is causing a crashc读取字符串导致崩溃
【发布时间】:2016-04-21 06:57:20
【问题描述】:
 int iPassCode, iNumber = 0;

void main()
{
    iNumber = get_name();
    iPassCode = get_code();
    name_strucutre();
}

int get_name()
{
    printf("Please enter your name: ");
    cName[MAX_NAME_LEN] = getchar();
    if(strcmp(cName,"leia"||"Leia"))
    {
        iNumber = 1;
    }
    if(strcmp(cName,"darth"||"Darth"))
    {
        iNumber = 2;
    }
    if(strcmp(cName,"r2d2"||"R2D2"))
    {
        iNumber = 3;
    }
    if(strcmp(cName,"solo"||"Solo"))
    {
        iNumber = 4;
    }
    if(strcmp(cName,"jabba"||"Jabba"))
    {
        iNumber = 5;
    }
    if(strcmp(cName,"yoda"||"Yoda"))
    {
        iNumber = 6;
    }
    else
    {
        iNumber = 0;
    }
    return(iNumber);
}

int get_code()
{
    printf("Please enter your pass code: ");
    scanf("%d", iPassCode);
    return (iPassCode);
}

我在这里得到了几个函数。我认为其中之一是get name() 函数导致程序崩溃。现在我要做的就是从用户那里收集姓名和密码,然后将信息传回main()。我不想把整个名字传回去,尽管只是一个单数。

【问题讨论】:

  • MAX_NAME_LEN ???
  • "leia"||"Leia" 没有做你认为它正在做的事情。您需要两个单独的 strcmp 调用,或 stricmp 变体。 (而且你拼错了某个西斯领主的小写版本)。
  • #define MAX_NAME_LEN 42 忘了说我一开始就有这个
  • 首先,学会使用调试器!

标签: c string strcmp getchar


【解决方案1】:

问题很多,我们一一分析

  1. 首先,

    cName[MAX_NAME_LEN] = getchar();
    

    无效,因为

    • 根据最新标准,默认为int 不再是标准。您需要定义数据类型

    • getchar() 的一次调用会读取一个char。至少你需要一个循环。

    你需要改成类似的东西

    char cName[MAX_NAME_LEN] = {0};
    

    然后,循环遍历getchar() 以读取输入。

    否则,最好使用fgets() 来读取和存储输入。

  2. 也就是说,你不能像这样在一个调用中比较多个字符串

    if(strcmp(cName,"leia"||"Leia"))
    

    这本质上是

    if(strcmp(cName,1))
    

    这又是非法的。您可以使用strcasecmp() 忽略大小写。否则,要严格符合标准,您必须使用单独的 strcmp() 调用来将字符串与每个验证器进行比较。

    是的,strcmp() 在成功(匹配)时返回 0

  3. 你在写

    scanf("%d", iPassCode);
    

    应该是

    scanf("%d", &iPassCode);  //missed the address-of
    

毕竟,从编码风格的角度来看,让我补充一点,return 是一个关键字,不要让它看起来像一个函数调用。

【讨论】:

  • 这样做? cName[MAX_NAME_LEN] = fgets();
  • @JMBTaylor 不,这根本不是语法。请阅读链接的手册页。
  • 啊,明白了。该链接适用于 linux fgets,对于初学者来说有点难以理解,但我需要将其更改为 gets(cName);
  • @JMBTaylor gets()? 不,永远不会。我给了你fgets()的链接,对吧?
  • 是的,但 fgets() 据我了解它是从文件中读取的。我不想从这个函数中的文件中读取名称。
【解决方案2】:

表达式strcmp(cName,"leia"||"Leia") 等价于strcmp(cName, 1)

子表达式"leia"||"Leia"true,它在C 中等价于1

如果你想检查一个字符串是否等于一个或另一个,你需要两个strcmp调用:strcmp(cName,"leia") == 0 || strcmp(cName,"Leia") == 0

【讨论】:

  • 或者类似stricmp的东西,虽然我不记得那是不是标准的C。
  • @Bathsheba 不,这是 Windows CRT 特定的功能。 C 标准没有不区分大小写的比较。
  • @JoachimPileborg strcasecmp() 怎么样? [POSIX]
【解决方案3】:

看看这些错误:

  • 你正在使用

    scanf("%d", iPassCode);

为了阅读,但你已经声明了

int iPassCode;

scanf 需要读取指针。

替换为

scanf("%d", &iPassCode);
  • 另一个错误是您比较字符串的方式。用以下格式替换所有比较:

    if ( (strcmp(cName,"something") == 0) || (strcmp(cName,"something") == 0) )
    
  • 此外,您不能将 cName[MAX_NAME_LEN] = getchar(); 作为有效声明。

  • 最后我想你已经在某处定义了MAX_NAME_LEN,否则你应该这样做。

【讨论】:

  • 这是一个被忽略的错误,但我认为程序没有走那么远,因为它在通知我之前仍然崩溃。
  • @JMBTaylor 我更新了我的帖子,发现更多错误,看看:)
猜你喜欢
  • 2015-11-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-05-28
  • 1970-01-01
  • 2016-06-25
相关资源
最近更新 更多