为什么这会打印字符串的错误部分?

时间:2019-12-11 02:54:09

标签: c c-strings

void buggy_substring(char *input, size_t pos, size_t len)
{
 input += pos;
 input[len] = '\0';
} 

int main(int argc, char *argv[])
{
 char name[16];
 strcpy(name, "Tessier-Lavigne");
 buggy_substring(name, 3, 2);
 printf("%s\n", name);
 return 0;
} 

为什么这样打印“ Tessi”而不是“ si”? 这是将size_t与char混合的问题吗?

4 个答案:

答案 0 :(得分:2)

仅在功能中更改开始位置。但是,在打印时,您仍然会将字符串的原始开头传递给printf。

尝试将name + 3传递给printf。


    int main(int argc, char *argv[])
    {
     char name[16];
    // allocated a buffer of 16 bytes on the stack (called name)
    // note that an array of chars and a pointer to a char is NOT the same thing
     strcpy(name, "Tessier-Lavigne");
    // copies from a const null-terminated string 
    // now char* name contains
    // ['T','e','s','s','i','e','r','-','L','a','v','i','g','n','e','\0']
     buggy_substring(name, 3, 2);
    // name is passed as an immutable number "by value", 
    // the value of name is not changed
    // however, the contents name points to can be
    // now name is
    // ['T','e','s','s','\0','e','r','-','L','a','v','i','g','n','e','\0']


     printf("%s\n", name);
    //output 'T','e','s','s' + new line
     return 0;
    } 



    void buggy_substring(char *input, size_t pos, size_t len)
    {
    //local pointer input
    // points to ['T','e','s','s','i','e','r','-','L','a','v','i','g','n','e','\0']
    //pos=3
    //len=2
     input += pos;
    // input points to 's' (original name still points to 'T'

     input[len] = '\0';
    //equivalent code
     char * p=input;
     p+=len;
     *p='\0';
    // input+2 points to 'i'
    // 'i' is replaced with zero
    // the original buffer looks like
    //['T','e','s','s','\0','e','r','-','L','a','v','i','g','n','e','\0']
    } 

免责声明:当然,您应该使用库字符串操作函数来编写更严肃的代码,并且不要尝试重新发明轮子。

答案 1 :(得分:1)

C是一种按值传递的语言。您的子字符串函数中的input += pos不会更改name中的main

答案 2 :(得分:1)

您需要将指针传递给指针,以便修改 pointer 而不是被引用的对象。

void substring(char **input, size_t pos, size_t len)
{
 *input += pos;
 (*input)[len] = '\0';
} 

如果您将指针传递给数组char (*pa)[]

,也可以使用

答案 3 :(得分:0)

由于C是传递值,因此将作为参数提供的值的副本绑定到函数调用中的形式参数上。这意味着在buggy_substring()中,inputnamemain()标识的指针值的副本。 (当然,namechar的数组,在函数调用中它会衰减为指向char的指针。)

由于input只是name(指针)的副本,因此对input(指针)的任何更改都不会影响name的值在main()中。但是,input仍与name指向内存中的相同位置,因此通过 input(指针)进行的更改会影响指向的相同内存区域通过name(指针)。

所有这一切的结果是,当input的值增加时,它不再指向与name(指针)相同的存储位置。递增的指针可用于通过input[len] = '\0'写入内存,但是当buggy_substring()函数返回时,input的生存期结束(input自动变量),返回main()name保持不变。因此,当调用printf()时,从头开始打印到新插入的name所指向的字符串(指针:记住,数组标识符在大多数情况下会衰减到指向其第一个元素的指针)。空终止符。