函数中的字符串未在C中修改

时间:2014-10-27 13:54:23

标签: c string function cstring

我试图编写一个接收字符串作为参数然后完全修改它的函数:

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

void updatePEP(char **pep_, int v){
    if((v == 0)){
        //pep_[0] = '1';
        //strncpy(pep_[0],"1", 2);
        strncpy(*pep_,"10", 2);
        //*pep_ = "10";
    }
    else if((v < 0)){
        strncpy(*pep_,"01", 2);
    }
}

int main(){

    char *PEP = "00";
    int i = 0, j = -1;

    printf("%s\n",PEP);

    updatePEP(&PEP,i);
    printf("%s\n",PEP);

    updatePEP(&PEP,j);

    printf("%s\n",PEP);

    return 0;
}

我已经通过互联网搜索过了,我相信我正确地将字符串作为参考,所以我怀疑是否使用:

pep_[0] = '1';
strncpy(pep_[0],"1", 2);
strncpy(*pep_,"10", 2);
*pep_ = "10";

为什么? (但它们都不起作用,所以它们也可能是错的......)

3 个答案:

答案 0 :(得分:7)

您无法修改字符串文字,根据定义它是const(只读),因此您的程序具有未定义的行为

您可以改为使用字符数组:

char PEP[] = "00";

并将此缓冲区传递给您的函数,该函数可以接受此数组作为参数(它将衰减为指向第一个元素的指针)。

你在updatePEP中输错了,你应该检查if (v==0)

请注意,该函数需要char* (因此您可以直接使用数组调用它),而不是char**

void updatePEP(char *pep_, int v)
{
    if (v == 0){
        strncpy(pep_,"10", 2);
    }
    else if (v < 0){
        strncpy(pep_,"01", 2);
    }
}

答案 1 :(得分:1)

您的代码中有undefined behaviorPEP函数中的指针main指向字符串文字,字符串文字实际上是只读字符数组。尝试修改字符串文字会导致所述未定义的行为。

答案 2 :(得分:0)

保留原始功能签名,您可以将功能实现为:

void updatePEP(char **pep_, int v)
{
    if (v == 0)
        *pep_ = "10";
    else if (v < 0)
        *pep_ = "01";
    else               // For symmetry, though not implemented in question
        *pep_ = "00";
}

这会修改由地址传入的指针(指向指针的指针)以指向不同的字符串文字。您的代码包含使用此表示法的注释,因此您可能会使用此变体,或者您尝试过它并且无法使其正常工作。

然后你可以编写你的主程序:

int main(void)
{
    char *pep = "00";

    printf("%p: %s\n", pep, pep);
    updatePEP(&pep, +1);
    printf("%p: %s\n", pep, pep);
    updatePEP(&pep,  0);
    printf("%p: %s\n", pep, pep);
    updatePEP(&pep, -1);
    printf("%p: %s\n", pep, pep);

    return 0;
}

如果你想修改字符串而不是指针,那么你有answer来自quantdev - 有理由接受(不要改变它!) - 但它仍然掩盖了变化在函数原型中。如果您没有像上面的代码那样修改指针,那么您不需要额外的间接层,但是您需要传递数组而不是字符串文字。

void updatePEP(char *str, int v)
{
    if (v == 0)
        strcpy(str, "10");
    else if (v < 0)
        strcpy(str, "01");
    else               // For symmetry, though not implemented in question
        strcpy(str, "00");
}

int main(void)
{
    char pep[] = "00";

    printf("%p: %s\n", pep, pep);
    updatePEP(&pep, +1);
    printf("%p: %s\n", pep, pep);
    updatePEP(&pep,  0);
    printf("%p: %s\n", pep, pep);
    updatePEP(&pep, -1);
    printf("%p: %s\n", pep, pep);

    return 0;
}

除了定义pep的方式外,这与以前的main()功能相同。

请注意,修改字符串文字会导致未定义的行为。任何事都可能发生;什么都不可能。在许多系统上,尝试修改字符串文字会导致崩溃。在一些较旧的系统(主要是上一个千年的古老系统)中,您可以修改字符串文字,但修改仍然“永远”有效,而其他希望看到"00"的代码可能会看到{{ 1}}或"01",可能导致混乱。不要尝试修改字符串文字。