简体   繁体   中英

C code removing wrong character from string

This code is supposed to remove any leading spaces from the given string, and it was working correctly. Then, for seemingly no reason at all, it started removing characters in the middle of the word. In this example the word "CHEDDAR" is given, which has no leading spaces so it should be passed back the same as it was input, however it's returning "CHEDDR" and I have no idea why. Does anyone know how this is even possible? I assume it has to do with pointers and memory, but I am not fluent in C and I need some help. Runnning on RHEL. Thanks.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define REMOVE_LEADING_SPACES(input)                       \
           {                                            \
           stripFrontChar( input, ' ' );                         \
           }


char *stripFrontChar(char *startingString, char removeChar) {
    while (*startingString == removeChar)
        strcpy(startingString, startingString + 1);
    return (startingString);
}

void main(argc, argv)
    char **argv;int argc; {
    char *result = "CHEDDAR";
    REMOVE_LEADING_SPACES(result);
    printf("%s\n", result);
}

EDIT: It's a little late now but based on the comments I should have shown that the word (CHEDDAR I used as an example) is read from a file, not a literal as shown in my code. I was trying to simplify it for the question and I realize now it's a completely different scenario, so I shouldn't have. Thanks, looks like I need to use memmov.

EDIT2: There actually is a space like " CHEDDAR", so I really just need to change it to memmov, thanks again everyone.

You copy a string using overlapping memory area:

strcpy(startingString, startingString + 1);

From the C standard:

7.24.2.3 The strcpy function

If copying takes place between objects that overlap, the behavior is undefined.

You need to use memmov (and provide proper length) or you need to move the characters on your own. You can also improve the performance if you start with counting the characters that need to be removed and then copy all in one go.

Another issue that was pointed out by Joop Eggen in a comment:

char *result = "CHEDDAR";

You are not allowed to modify string literals. If you try to remove leading characters, you invoke undefined behaviour.

You should change this to

char result[] = "CHEDDAR";

As your sample string does not contain a leading space, this does not cause trouble yet. But you should fix it nevertheless

This code

strcpy(startingString, startingString + 1);

copies overlapping strings.

Per 7.24.2.3 The strcpy function , paragraph 2 of the C standard :

The strcpy function copies the string pointed to by s2 (including the terminating null character) into the array pointed to by s1 . If copying takes place between objects that overlap, the behavior is undefined.

You are invoking undefined behavior.

Although the answers identifying that you are copying overlapping strings identify undefined behavior, another cause is that you use a literal string, and on most platforms those are immutable and will cause the program to abort.

Instead of:

char *result = "CHEDDAR";

Use:

char result[] = "CHEDDAR";

(Note: looking at how most strcpy functions will have been implemented, namely a loop that terminates when seeing the null character of the source string, then the overlap that you use will still see the null character of the source and place it in the destination (down-copying). Copying the other way around (up-copying) would not see the null terminator anymore, as it will have been overwritten, and may continue copying beyond the destination string.)

In your case, where no modification is needed and no allocs are done, you only need to find the start without copying anything.

char *stripFrontChar(char *startingString, char removeChar) {
    for( ; *startingString == removeChar; startingString++)
        ;
    return (startingString);
}

But you have to use the return of stripFrontChar()

printf("%s\n", stripFrontChar(result));

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM