【问题标题】:Behavior not understood in C program that prints out initials在打印出首字母的 C 程序中无法理解的行为
【发布时间】:2015-04-15 08:50:33
【问题描述】:

我有一个简单的 C 程序,它应该接受用户给出的名称,然后在标准输出中打印出名称的首字母。我的实现如下:

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

int main(int argc, string argv[])
{
    string name = GetString();
    printf("%c\n", name[0]);  // print out the very first initial of the complete name

    for(int i = 1; i< strlen(name); i++)
    {
        string blank_space = " ";
        printf("name[i] = %c \n", name[i]);
        printf("i = %d, blank_space = %s,strcmp = %d\n", i, blank_space, strcmp(&name[i - 1], blank_space));
        if (strcmp(&name[i - 1], blank_space) == 0)
        {
            printf("%c\n", name[i]);
        }
        else
        {
            continue;
        }
    }

    return 0;
} 

如果我给程序类似Aug Koh 作为输入,那么它应该给我AK 作为输出。但是,当我尝试调试我的程序时,我似乎无法弄清楚它有什么问题。这是我的程序的标准输出:

jharvard@ubuntu (~/pset2): ./initials 
Aug Koh
A
name[i] = u 
i = 1, blank_space =  ,strcmp = 1
name[i] = g 
i = 2, blank_space =  ,strcmp = 1
name[i] =   
i = 3, blank_space =  ,strcmp = 1
name[i] = K 
i = 4, blank_space =  ,strcmp = 1
name[i] = o 
i = 5, blank_space =  ,strcmp = 1
name[i] = h 
i = 6, blank_space =  ,strcmp = 1

它所做的只是打印出A。真正让我感到困惑的是为什么strcmp(&amp;name[i - 1], blank_space) 会返回1 的值,即使name[i - 1] 是一个空格,在执行strcmp 时,它的计算结果应该与blank_space 变量相同。当我用printf 打印出它们时,它们看起来都一样!

对我的问题的任何帮助将不胜感激,我非常重视任何改进建议。

仅供参考:这实际上来自 Edx 课程 CS50 的问题集 2。所以cs50.h是课程中提供的一个头文件,它为我们提供了string等特殊类型和GetString()等独特功能。

【问题讨论】:

  • 你确定这是 C 代码吗?
  • 我猜cs50.h 中有一些讨厌的东西,比如typedef char * string;,还有一个函数GetString()
  • strcmp 不是正确的函数。您正在将“Foo”与“”进行比较。这些字符串不相等。请查看 ctype.h 标头来对 ascii 字符进行分类。 (但是那个 cs50 头是邪恶的。那个字符串类型很讨厌。)
  • 另外,可能不需要在循环中每次都定义空格。
  • @Jiminion 好问题,但至少就 PSet2 而言,我们得到了一些假设,其中包括名称之间最多有一个空格。我们也可以假设不会使用像 O'Brien 之类的名字。

标签: c for-loop conditional cs50


【解决方案1】:

发生这种情况是因为您检查空间不正确。应该这样做:

if (name[i - 1] == ' ')

只有当name 的整个后缀从i-1 开始匹配blank_space(其中包含一个空格字符的字符串)时,比较strcmp(&amp;name[i - 1], blank_space) 才有效。这仅在以空格字符结尾的字符串末尾才有可能,因此它不适用于您的输入。

【讨论】:

    【解决方案2】:

    对程序的侵入性较小的更改(还有很多要讨论的要点)是将 strcmp 更改为 strncmp 。因为strcmp 将相等长度的字符串比较为相等。使用strcmp,这永远不会发生,因为第一个参数字符串总是比第二个(空格)长。由于您的循环将永远找不到空间,因此只会打印第一个字母。

    变化:

       if (strcmp(&name[i - 1], blank_space) == 0)
    

       if (strncmp(&name[i - 1], blank_space,1) == 0)
    

    如果要比较子串或

       if( name[i-1]==blank_space )
    

    如果你想比较单个字母。

    【讨论】:

      【解决方案3】:

      您可能正在寻找:

      int seen_space = 1; // The first character is assumed to be initial
      for (int i = 0; name[i]; ++i)
      {
          if (isspace((unsigned char)name[i]))
          {
             seen_space = 1;
          }
          else if (seen_space)
          {
              printf("%c", name[i]);
              seen_space = 0;
          }
      }
      printf("\n");
      

      【讨论】:

      • 你需要重置 seen_space。
      【解决方案4】:

      strcmp 比较两个字符串,直到找到两个字符串的 null(\0) 并返回零。

      您正在做的是将Koh 进行比较,这显然不相等。

      你应该搜索空格

      if(name[i - 1] == ' ')
      {
         \\space found
      }
      

      【讨论】:

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