C:删除字母以外的字符的程序

时间:2015-08-16 19:36:44

标签: c arrays string ctype

所以我正在尝试创建一个查看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

我认为威廉之前的空间已被删除,但我无法分辨。 谢谢你的帮助!

3 个答案:

答案 0 :(得分:7)

这个根本不需要复杂的双循环。练习的目的是保持独立的源 - 读者和目的地 - 作者,只有当前者符合您的标准时才复制和推进后者(即它回答为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

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

答案 1 :(得分:6)

这个内循环错了

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

它会复制除了第一个字符之外的字符串,之后你的程序什么也不做,因为我已经等于长度了。

因此程序只从字符串中删除一个非alpha字符。

当您要在序列上遍历字符串时,无需计算其长度。程序可以写得更简单,或者至少可以使用下面演示的方法。例如

#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"

答案 2 :(得分:1)

发布的代码试图努力。

以下代码

  • 干净利落地编译
  • 包含有用的评论,以阐明正在做的事情
  • 正确执行
  • 使用有意义的变量名称

注意代码的简单性,并且只在一次通过名称[]数组中执行。

#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