cc-stringscharacter-arrays

How can I remove 'garbage input' from a C string?


I am attempting to write a function that will remove all characters from an array, except for '+', '-', '*', '/', and numbers. This is the code I came up with:

void eliminateJunk(char string[MAX]){
    int i,j;
    char stringOut[MAX];
    int length = strlen(string) - 1;

    for(i=0; i <= length; i++){
        if(string[i] != '+'
        && string[i] != '-'
        && string[i] != '*'
        && string[i] != '/'
        && !(isdigit(string[i]))){
            for(j=i; j < length; j++){
                string[j] = string[j+1];
            }
        }
    }
}

However, the function does not always remove all garbage characters from the c string - it gets most of them, but occasionally leaves some behind.

Example input:

123 123

Example output of array, after it has been modified:

123123

However, in some inputs, it leaves spaces...

Example input:

123   123

Example output:

123 123

What can I do to fix this? I feel like the solution is right under my nose, but I can't seem to find it.


Solution

  • This is the classic problem with removing as you go: after the for loop you need to decrement i, otherwise you skip the next character.

    However, the nested for loop is unnecessary: you can do the entire thing with a single loop by maintaining separate read and write indexes. When you see a valid character, move it from the read location to the write location, and increment both indexes. When you see an invalid character, increment the read index without moving the character. At the end of the loop terminate the string - and you are done!

    int r, w; // r for "read", w for "write"
    for(r=0, w=0; r != length ; r++) {
        // Your condition is inverted
        if(string[r] == '+'
        || string[r] == '-'
        || string[r] == '*'
        || string[r] == '/'
        || (isdigit(string[r]))) {
            // No loop inside
            string[w++] = string[r];
        }
    }
    // Add null terminator at the end
    string[w] = '\0';