【问题标题】:String modification through function. Unexplained behavior通过函数修改字符串。无法解释的行为
【发布时间】:2013-09-27 17:07:31
【问题描述】:

此程序应将 n't 后跟字母更改为“not”。喜欢不要->不要。 但它显示了一些非常奇怪的输出。 例如,如果我只是跳过打印字符串长度输出是垃圾。我也不能说空间如何在输出中变为 s2ace。如果我不知道更好,我会说我在代码中有一个幽灵。

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

int func(char **str, int cur_len, int max_len)
{
    if (cur_len <= 3)
        return(cur_len);
    else if(max_len < cur_len)
        return(-1);

    int i,j;
    char new[max_len];
    new[0]='\0';
    char temp[2];

    for (i = 0; i < cur_len; i++)
    {
        if(i > 0 && i < cur_len - 2 && isalpha((*str)[i-1]) && (*str)[i] == 'n' && (*str)[i+1] == '\'' && (*str)[i+2] == 't')
        {
            strcat(new," not");
            i=i+2;
        }
            else
        {
            temp[0]=(*str)[i];
            temp[1]='\0';
            strcat(new, temp);
        }
    }
    j = strlen(new);
    if (j > max_len)
        return(-1);

    *str = new;
    return(j);

}


int main()
{
    char *x = "Please don't do anything stupid. all the n't followed by an alphabate should be changed to not followed by a space. e.g. doesn't.";
    int len, max, result;
    len = strlen(x);
    printf("String size = %d\n",len);//**if i comment this line all output goes down the drain.**
    max = 200;

    result = func (&x, len, max);
    if(result == -1)
    {
        printf("No change possible\n");
        return(-1);
    }
    printf("No of changes = %d\n",strlen(x)-len);
    printf("New String is :: %s\n",x);//**how does space change into s2ace??**
    return(0);
}

输出是

129更改次数 = 2 新字符串是 :: 请不要做任何愚蠢的事情。所有不跟随字母的 n 都应更改为不跟随 s2ace。例如没有。

【问题讨论】:

  • 您正在从您的函数func 返回一个指向本地对象的指针。这没有明确的行为,任何事情都可能发生,所以没有什么好解释的。
  • 是的,你要么需要malloc()func() 中的缓冲区,要么在main() 中创建一个数组并将其传递给你的函数。
  • 行不通。你不能像那样展开所有的收缩。

标签: c string function


【解决方案1】:

通过将char new[max_len]; 替换为

,以最少的代码更改解决问题
char *new = *str = (char*)malloc(max_len+1);

您还需要在顶部添加#include &lt;stdlib.h&gt;

如 cmets 中所述,指向本地对象(具有自动存储类)的指针在函数返回后立即变为无效。

静态对象不会消失,但我不相信可变长度数组可以是静态的。所以,你被 malloc/calloc 困住了。

请务必记录此行为,以便调用函数的作者知道在不再需要内存时释放指针。 (如果您要狡辩说您是作者并且已经知道它,我会指出它可以帮助您的代码的读者了解发生了什么。)

【讨论】:

  • 可能不希望有= *str,函数需要访问参数的原始值。关于从malloc() 申请返回的普通 cmets。
  • @PaulGriffiths 这不是我阅读原始程序的方式。 str 参数作为 char** 传递,因此将返回分配的字符串指针。名称“new”指的是当它被错误地分配为 C99 可变长度数组时的数组,并且被声明和分配为别名,主要是为了保留旧代码。无论如何,我会为指针本身声明一个名称,并使用它来代替 *str。甚至“新”这个名字也具有描述性。正如我所说,最小的变化,达到预期的行为。
  • 我的意思是这样的:temp[0]=(*str)[i];isalpha((*str)[i-1]) &amp;&amp; (*str)[i] == 'n' 取消引用传入的原始双指针。如果在到达那里之前用 *str = anything 覆盖原始值,那么该代码将会中断.显然,这段代码还有很多其他严重的问题,所以谁知道这是否是 OP 实际打算做的,但该函数似乎肯定是为了读取传入的原始字符串,然后才修改原始指针指向的内容。
猜你喜欢
  • 1970-01-01
  • 2023-04-08
  • 2020-12-15
  • 2013-12-27
  • 1970-01-01
  • 1970-01-01
  • 2023-03-09
  • 2022-10-04
  • 2018-04-01
相关资源
最近更新 更多