【问题标题】:Why isn't isalpha working?为什么 isalpha 不起作用?
【发布时间】:2015-07-25 23:06:59
【问题描述】:

我正在使用 C,我需要检查用户输入的第二个命令行参数 argv[1] 是否仅由字母字符组成,如果不是,则执行 else 循环中的操作。我使用了 is alpha 函数,但是当我编译和运行程序时,无论我的第二个命令行参数是什么(按字母顺序或其他),它总是执行“else 循环”。我该如何解决这个问题?

#include <stdio.h>
#include <cs50.h>
#include <ctype.h>
#include <string.h>
#include <stdlib.h>

int main(int argc, string argv[])
{
  int a  = argc;    

  if (a != 2)
  {
    return 1;    
  }

  string b = argv [1]; 
  int c = strlen(b);
  string m;

  for (int i = 0; i < c; i++)
  {
    if (isalpha(b[c]))
    { 
      m = GetString();    
    }
    else
    {
      printf("Please provide a valid keyword\n");
      return 1;
    }         
  }
}  

【问题讨论】:

  • C 世界中的 string 是什么 - 肯定不是 C++
  • 在 CS50 的世界中,&lt;cs50.h&gt; 标头包含 typedef char *string; — 这种设计值得商榷,但课程是这样定义的。

标签: c cs50


【解决方案1】:

尝试替换

if (isalpha(b[c]))

if (isalpha(b[i]))

目前您正在检查索引处的元素,该元素是循环的每次迭代中strlen(b) 的结果。因为数组索引在 C 中为零,所以 b[strlen(b)] 引用的是空终止符 '\0'

参考下面的 Keith Thompson 评论和this question 的答案,您实际上应该将传递给isalpha 的值转换为unsigned char,以确保不调用未定义的行为。

因此您应该将代码更改为

if (isalpha((unsigned char)b[i]))

确保没有UB

【讨论】:

  • isalpha() 不简单地采用 char 参数。它接受一个int 参数,其值是从unsigned char 转换而来的。如果普通的char 被签名(通常是这样),那么isalpha(c)c &lt; 0(和c != EOF)的情况下具有未定义的行为。将isalpha(b[i]) 更改为isalpha((unsigned char)b[i])。 (这几乎肯定不是 OP 问题的原因。)
  • 谢谢,有帮助:)
  • 不,你没有。应该是isalpha((unsigned char)b[i])
【解决方案2】:

使用isalpha(b[i]) 而不是isalpha(b[c]) 像这样:

if (isalpha(b[i]))
{ 
  m = GetString();    
}

【讨论】:

    猜你喜欢
    • 2021-09-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-03-07
    • 2019-08-06
    • 2016-07-05
    • 2011-08-06
    相关资源
    最近更新 更多