【问题标题】:C program that returns the initials of a name (CS50)返回姓名首字母的 C 程序 (CS50)
【发布时间】:2016-04-02 12:03:23
【问题描述】:

这是我的main

char* name = GetString();
if(name != NULL)
{
    for(int i = 0, j = strlen(name); i < j; i++)
    {
        if(!isalpha(name[i-1]) && isalpha(name[i]))
            printf("%c", toupper(name[i]));
    }
    printf("\n");
}

该程序运行良好;它通过了所有 (check50) 测试。

但我担心一个可能的错误,那就是i = 0,存储在name[-1] 中的值可以是字母字符吗?

注意:GetString() 函数返回用户输入的字符串。

【问题讨论】:

  • name[i-1] - 当 i 为零时这是可疑的
  • 请参阅stackoverflow.com/questions/15646973/…,详细解释为什么访问不属于您的内存是错误的。
  • GetString 函数是否保证第一个字符之前的字符是可访问的而不是字母数字的?如果是这样,这段代码很好。如果不是,则此代码已损坏。
  • @David Schwartz Nop,它没有。
  • 您可以使用if ((i == 0 || !isalpha(name[i-1])) &amp;&amp; isalpha(name[i])) 作为循环中的条件。

标签: c string memory char cs50


【解决方案1】:

对于i = 0name[i-1] 正在访问未分配的内存,这将导致未定义的行为。将循环计数器更改为 i = 1 而不是 i = 0

如 cmets 中所述,您需要在循环外检查 i =0 的条件。

【讨论】:

  • 并在循环前分别检查i = 0的条件。
  • 如果他想检查name[0]是否是alpha。更改您的建议将跳过该检查
  • @hacks Haris 说的是对的。你跳过了名字[0]
  • @Haris - 哈克斯说得对。对于i == 0name[i-1] (name[0-1]) 产生一个负数组索引。
  • @ryyker,OP 的算法对于正常的i 来说是这样的,比如i=0.
【解决方案2】:

假设name指向的字符串分配的内存从name[0]开始,那么name[i-1]i=0时会导致数组越界访问,这在C语言中是未定义的行为,并且可能在您的程序中导致各种奇怪的症状(包括它正常工作:-)。这是一个不幸的案例,它通过了所有的测试,因为它误导了你。

【讨论】:

    【解决方案3】:

    实际上在 C 中,[] 运算符可以替换为 *()

    • a[n] 等于 *(a+n);

    因此,在您的情况下,当i = 0 时,您访问的是*(a - 1) 位置,而您的字符串从a 开始到a + length。因此,这将导致未知行为。

    +----+----+----+----+
    | f  |  o | o  | \0 |
    +----+----+----+----+
      ^              ^
      |              |
      a            a + 3
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-12-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-03-26
      • 1970-01-01
      • 2020-06-08
      • 1970-01-01
      相关资源
      最近更新 更多