无法处理ANSI C中的字符串副本

时间:2012-04-14 23:01:51

标签: c

我在ANSI C中编写了一个程序来删除字符串前面和末尾的双引号,因此"Hello, world"将成为Hello, world

代码:

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

char* removeQuotes(char str[]) {
    int i = 1;
    int len = strlen(str) - 2;
    char * tmp = (char*) malloc (sizeof(char) * len);
    for (;i<=len;++i ) {
        tmp[i-1] = str[i];
    }
    return tmp;
}

int main(void) {
    char str[] = "Hello, world";
    char * abc = removeQuotes(str);
    printf("Inside the quotes is: %s length: %d\n"
            "Original is: %s length: %d", abc, strlen(abc), str, strlen(str));
    return 0;
}

在IDEOne(http://ideone.com/Iybuk)中,我得到了正确答案。但GCC给了我一些奇怪的东西:

U→┬↓ length: 22es is: ello, worlESSOR_↑
Original is: Hello, world length: 12

仅当字符串包含空格时才会发生。它适用于“Helloworld”或类似的东西。 任何可靠的方法让它正常工作?

4 个答案:

答案 0 :(得分:5)

  • 您没有为空终止符分配足够的空间。

  • 您不会将null终结符添加到结果的末尾。

  • 您的源字符串实际上不包含引号。

答案 1 :(得分:1)

在C字符串中以空字符结尾,这意味着'\0'

您没有在removeQuotes()中终止字符串,这是正确的版本:

char* removeQuotes(char str[]) {
    int i = 1;
    int len = strlen(str) - 2;
    char * tmp = (char*) malloc (sizeof(char) * (len + 1));
    for (;i<=len;++i ) {
        tmp[i-1] = str[i];
    }
    tmp[len] = '\0';
    return tmp;
}

此外,您的字符串实际上不包含引号,并且您不会检查传递给removeQuotes的字符串是否包含任何引号。

答案 2 :(得分:0)

在你的removeQuotes函数中,你为结果字符串取消了内存,并在缓冲区之外写了一个额外的字符。

字符串"Hello world"实际上不包含任何引号。您必须将其声明为"\"Hello world\""以获得您想到的字符串。在任何情况下,删除引号所产生的字符串与输入字符的字符数相同。你丢失了第一个字符,因为你永远不会复制它,并且最后一个字符被写入缓冲区(它会写在那里,破坏内存,即使它是引号。

为什么你还需要这样做?您是否认为C字符串是在字符数组的第一个和最后一个位置使用引号字符创建的?

答案 3 :(得分:0)

在临时字符串中保留'\ 0'。否则它不会知道它是一个字符串。