【问题标题】:C: Program to delete characters other than alphabeticalC:删除字母以外字符的程序
【发布时间】:2015-11-09 10:12:36
【问题描述】:

所以我正在尝试创建一个程序,该程序查看 main 中定义的字符串,并删除所有非字母字符(不包括 \0)。到目前为止,这是我的代码:

/* Write code to which considers the string currently saved
 * in the 'name' array, removes all spaces and non-alphabetical
 * chars from the string, and makes all alphabetical characters
 * lower case. */

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

#define NAMELEN 30

int main (void) {
  char name[NAMELEN];
  strcpy(name, " William B. Gates");
    int i, length, check;

    length = strlen(name);
    for ( i = 0; i < length; i++ ) {
        check = isalpha(name[i]);
        if ( check == 0 ) {
            for ( ; i < length; i++ ) {
                name[i] = name[i+1];
            }
        }
    }
    printf("The length is %lu.\n", strlen(name));

  printf("Name after compression: %s\n", name);
  return EXIT_SUCCESS;
}

所以对于测试数据“William B. Gates”,输出应该是“WilliamBGates”,不幸的是我得到的输出是:

The length is 16.
Name after compression: William B. Gates

我认为威廉前面的空格已被删除,但我无法确定。 感谢您的帮助!

【问题讨论】:

  • @user3121023 改成length = strlen(name); for ( i = 0; i &lt; length; i++ ) { check = isalpha(name[i]); if ( check == 0 ) { for ( j = i ; j &lt; length; j++ ) { name[j] = name[j+1]; } } } 得到输出WilliamB Gates 为什么不删除第二个空格?
  • 你根本不需要双循环。您需要一个源和目标指针,以及对字符串的一次遍历。
  • @WhozCraig 我该怎么做呢。我是一个非常基础的程序员,我只是为了考试练习而做这些问题,而不是出于需要或乐趣......有什么建议吗?
  • @user3121023 你认为我应该使用isspace() 添加一个单独的for循环来检查新字符串中的空格吗?
  • 如果您更喜欢使用索引下标而不是指针,那么对于 Vlad 的回答也是如此。

标签: c arrays string ctype


【解决方案1】:

对于这个你根本不需要复杂的双循环。练习的目的是保持独立的源读取器和目标写入器,仅在前者符合您的标准时才复制和推进后者(即它对 isalpha 的回答为真)。

换句话说:

#include <stdio.h>
#include <ctype.h>

int main (void)
{
    char name[] = " William B. Gates";
    char *dst = name, *src;

    for (src = name; *src; ++src)
    {
        if (isalpha((unsigned char)*src))
            *dst++ = *src;
    }
    *dst = 0; // terminate the string

    printf("result: %s\n", name);
}

输出

result: WilliamBGates

我将在复制步骤中将翻译为小写作为练习留给您。 (来自您的代码内注释:“使所有字母字符小写”)。

【讨论】:

    【解决方案2】:

    这个内循环是错误的

        if ( check == 0 ) {
            for ( ; i < length; i++ ) {
                name[i] = name[i+1];
            }
    

    它复制字符串本身,不包括第一个字符,然后你的程序什么都不做,因为 i 已经等于长度。

    所以程序只从字符串中删除一个非字母字符。

    当你要连续遍历一个字符串时,不需要计算它的长度。该程序可以编写得更简单,或者至少您可以使用下面演示的方法。例如

    #include <stdio.h>
    #include <ctype.h>
    
    int main( void )
    {
        char name[] = " William B. Gates";
    
        printf( "\"%s\"\n", name );
    
        size_t j = 0;
        for ( size_t i = 0; name[i] != '\0'; i++ )
        {
            if ( isalpha( ( unsigned char )name[i] ) )
            {
                if ( j != i ) name[j] = name[i];
                ++j;
            }
        }
        name[j] = '\0';
    
        printf( "\"%s\"\n", name );
    
    }   
    

    程序输出是

    " William B. Gates"
    "WilliamBGates"
    

    【讨论】:

      【解决方案3】:

      贴出的代码很努力。

      以下代码

      • 编译干净
      • 包含有用的 cmets 以阐明正在做什么
      • 正确执行
      • 使用有意义的变量名

      请注意代码的简单性,所有代码都只通过 name[] 数组执行。

      #include <stdio.h>
      #include <ctype.h>
      
      int main( void )
      {
          char name[] = " William B. Gates";
      
          printf( "\"%s\"\n", name );
      
          size_t src  = 0;
          size_t dest = 0;
          for( ; name[src]; src++)  // will exit loop when string terminator '\0' encountered
          {
              if( isalpha(name[src]) )
              { // then current char is: a...zA...Z
                  name[dest] = tolower(name[src]); // force lower case
                  dest++; // update where to save next character
              }
          }
      
          name[dest] = '\0'; // terminate the modified string
      
          printf( "\"%s\"\n", name );
      
          return 0;
      } // end function: main
      

      【讨论】:

      • 对不起,我是一个非常基础的 C 程序员,你能解释一下 size_t 吗?
      • 在程序中的什么地方,不是字母的字符会被删除?我只是看不到它。
      猜你喜欢
      • 2017-09-01
      • 2017-10-16
      • 1970-01-01
      • 2011-10-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-09-27
      • 1970-01-01
      相关资源
      最近更新 更多