繁体   English   中英

C 代码从字符串中删除错误的字符

[英]C code removing wrong character from string

此代码应该从给定的字符串中删除任何前导空格,并且它工作正常。 然后,似乎没有任何理由,它开始删除单词中间的字符。 在这个例子中,给出了“CHEDDAR”这个词,它没有前导空格,所以它应该像输入一样返回,但是它返回“CHEDDR”,我不知道为什么。 有谁知道这怎么可能? 我认为它与指针和内存有关,但我不精通 C,我需要一些帮助。 在 RHEL 上运行。 谢谢。

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

编辑:现在有点晚了,但根据我的评论,我应该表明这个词(我以 CHEDDAR 为例)是从文件中读取的,而不是我的代码中显示的文字。 我试图为这个问题简化它,现在我意识到这是一个完全不同的场景,所以我不应该这样做。 谢谢,看来我需要使用 memmov。

EDIT2:实际上有一个像“CHEDDAR”这样的空间,所以我真的只需要把它改成memmov,再次感谢大家。

您使用重叠内存区域复制字符串:

strcpy(startingString, startingString + 1);

从 C 标准:

7.24.2.3 strcpy 函数

如果复制发生在重叠的对象之间,则行为未定义。

您需要使用memmov (并提供适当的长度)或者您需要自己移动字符。 如果您首先计算需要删除的字符,然后一次性复制所有字符,也可以提高性能。

Joop Eggen 在评论中指出的另一个问题:

char *result = "CHEDDAR";

不允许修改字符串文字。 如果您尝试删除前导字符,则会调用未定义的行为。

你应该把它改成

char result[] = "CHEDDAR";

由于您的示例字符串不包含前导空格,因此这不会造成麻烦。 但是你应该修复它

这段代码

strcpy(startingString, startingString + 1);

复制重叠的字符串。

根据7.24.2.3 的 strcpy 函数,C 标准的第 2 段

strcpy函数将s2指向的字符串(包括终止空字符)复制到s1指向的数组中。 如果复制发生在重叠的对象之间,则行为未定义。

您正在调用未定义的行为。

尽管确定您正在复制重叠字符串的答案确定了未定义的行为,但另一个原因是您使用了文字字符串,而在大多数平台上,这些字符串是不可变的,会导致程序中止。

代替:

char *result = "CHEDDAR";

用:

char result[] = "CHEDDAR";

(注意:看看大多数strcpy函数是如何实现的,即在看到源字符串的空字符时终止的循环,那么您使用的重叠仍然会看到源的空字符并将其放入目标(向下复制)。以相反的方式复制(向上复制)将不再看到空终止符,因为它将被覆盖,并且可能会继续复制超出目标字符串。)

在您的情况下,不需要修改并且没有完成分配,您只需要找到开始而不复制任何内容。

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

但是你必须使用stripFrontChar()的返回

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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