Search code examples
cbackspace

How to do backspace processing in C


How to do a backspace processing for string in C? Here is a simple example of what I wrote

char buf[1024]="D,e,Bs,a,t,e"  \\*Bs means Backspace
char tmp[1024];
int j,n;
n=0;

sprintf(tmp,"%s",buf);
for(j=0;tmp[j] !='\0';j++)
{
    if ((tmp[j] == '\x08') || (tmp[j] == 127))
    {
      j++;
      n--;
    }
    buf[n] = tmp[j];
    n++;
}
buf[n] = '\0';
printf("%s",buf);

This will print = Date

But if the buf have more than 1 Bs, example

char buf[1024] = "D,e,e,Bs,Bs,a,t,e"

The output will be = DeBsate

The function will find only 1 backspace. Why? Because the j are increased after it process the first Bs and ignored checking the Bs after that. Of course, if check on terminal, the output are still date. But if I log the debug just to see the string inside buf. The second Bs will still be there. Which is not suppose to. How do I modify this function?


Solution

  • You can process a string to handle backspaces with the following code (the include and main() are there for debugging purposes, the processString() function is the "meat" of this solution):

    #include <stdio.h>
    
    void processString (char *str) {
        // Set up independent source and dest pointers.
    
        char *src, *dst;
    
        for (src = dst = str; *src != '\0'; src++) {
            // Backspaces handled specially.
    
            if (*src == '\b') {
                // BS will back up unless you're at string start.
    
                if (dst != str) {
                    dst--;
                }
                continue;
            }
    
            // Non-BS means simply transfer character as is.
    
            *dst++ = *src;
        }
    
        // Terminate string.
    
        *dst = '\0';
    }
    
    int main (void) {
        char xyzzy[] = "\bPaxDiablo\b\b\b\b\b\b is one mighty fine gal\b\buy.";
        processString (xyzzy);
        puts (xyzzy);
        return 0;
    }
    

    The logic is to simply run two independent pointers through the string, the one you read from and the one you write to. The former is incremented by one each time through the loop.

    The second also does this unless you strike a backspace character. If it does, it throws that character away and decrements the destination pointer (only if you're not at the beginning of the string) so as to overwrite the previous character on the next iteration (or after the loop if it's the last character).

    As expected, the output is:

    Pax is one mighty fine guy.