这个功能有什么问题?

bra*_*boy 4 c find

我今天遇到了问题.它有一个方法,我需要在该函数中找到问题.该函数的目标是将新行附加到传递的字符串.以下是代码

char* appendNewLine(char* str){
    int len = strlen(str);
    char buffer[1024];
    strcpy(buffer, str);
    buffer[len] = '\n';
    return buffer;
}
Run Code Online (Sandbox Code Playgroud)

我已经确定了这种方法的问题.它那种直截了当.该方法可能使数组的索引超出范围.这不是我的疑问.在java中,我使用'\n'作为换行符.(我基本上是一名Java程序员,多年来我一直在C工作).但我隐约记得'\n'是表示C中字符串的终止.这也是这个程序的问题吗?

请指教.

Dan*_*erg 9

这段代码中存在很多问题.

  1. strlen而不是strlent,除非你在那里有一个奇怪的库函数.
  2. 您正在堆栈上定义静态缓冲区.这是一个潜在的错误(也是一个安全错误),因为一行后来,你将字符串复制到它而不检查长度.可能的解决方案可以是在堆上分配内存(使用strlen和malloc的组合),或者使用strncpy并接受字符串的截断.
  3. 附加'\n'确实解决了添加新行的问题,但这会产生进一步的错误,因为该字符串当前不是以null结尾.解决方案:将'\n'和'\ 0'追加为null以终止新字符串.
  4. 正如其他人所提到的,你正在返回一个指向局部变量的指针,这是一个严重的错误,并使返回值在短时间内损坏.

为了扩展您对这些问题的理解,请查看可能来自此处的 C风格字符串.另外,自学一下堆栈上分配的变量和堆上分配的变量之间的区别.

编辑:AndreyT是正确的,长度的定义是有效的

  • @Daniel Goldberg:你的第二点不正确.那里没有错.该代码完全有效C89/90.之前的"代码行"是带有初始化程序的`len`的*声明*.C89/90禁止在块内混合声明和语句("代码").但只要您只编写连续的*声明*,就可以将任何"代码"放入初始化器中. (3认同)

Jer*_*fin 7

不,'\n'是c中的新行,就像在Java中一样(Java从C中获取).你已经发现了一个问题:如果输入的字符串比你的字符串长buffer,那你就写完了buffer.更糟糕的是,您return buffer;返回函数本地的内存地址,并在函数退出时停止存在.


phi*_*ant 5

首先,这是一个功能,而不是一个程序.

此函数返回指向局部变量的指针.当函数退出时,通常在堆栈上创建的这些变量不再可用.

另一个问题是如果传递的长度超过1024个字符; 在这种情况下,strcpy()将写入缓冲区.一种解决方案是在动态内存中分配新缓冲区并返回指向该缓冲区的指针.缓冲区的大小应为len +2(所有字符+ newline+ \0字符串终止符),但有人必须释放此缓冲区(也可能是初始缓冲区).

strlent()不存在,它应该是,strlen()但我想这只是一个错字.