Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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.

like image 310
jkm Avatar asked Apr 08 '15 10:04

jkm


People also ask

What is garbage character C?

What it refers to is any byte that resides in a variable that wasn't assigned in some well-defined way. The character A can be a garbage character if it happens to appear in (for example) a block of memory returned by malloc or an uninitialized char variable.


1 Answers

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';
like image 83
Sergey Kalinichenko Avatar answered Sep 18 '22 01:09

Sergey Kalinichenko