Stephen McGarry
Stephen McGarry

Reputation: 55

C: Program to delete characters other than alphabetical

so I'm trying to create a program which looks at a string defined in main, and deletes any non-alphabetical characters (excluding \0). So far this is my code:

/* 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;
}

So for the test data, " William B. Gates", the output should be "WilliamBGates", unfortunately the output I'm getting is:

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

I think the space before William has been deleted, but I'm unable to tell. Thanks for any help!

Upvotes: 2

Views: 603

Answers (3)

user3629249
user3629249

Reputation: 16540

The posted code tries to hard.

The following code

  • compiles cleanly
  • contains useful comments to clarify what is being done
  • performs correctly
  • uses meaningful variable names

notice the simplicity of the code, and all performed in only one pass through the name[] array.

#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

Upvotes: 1

WhozCraig
WhozCraig

Reputation: 66244

You don't need a complicated double-loop for this at all. The purpose of the exercise is to maintain independent source-reader and destination-writer, only copying and advancing the latter when the former is qualified by your criteria (i.e. it answers true to isalpha).

in other words:

#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);
}

Output

result: WilliamBGates

I leave translating to lower case during the copy-step as an exercise for you. (from your in-code comment: "makes all alphabetical characters lower case").

Upvotes: 7

Vlad from Moscow
Vlad from Moscow

Reputation: 311088

This inner loop is wrong

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

It copies the string in itself excluding the first character and after that your program does nothing because i is already equal to length.

So the program only removes one non-alpha character from the string.

When you are going to traverse a string sequantially then there is no need to calculate its length. The program can be written simpler or at least you may use the approach that is demonstrated below. For example

#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 );

}   

The program output is

" William B. Gates"
"WilliamBGates"

Upvotes: 6

Related Questions