【发布时间】:2016-10-10 08:15:39
【问题描述】:
在我学习 C 的过程中,我正在开发几个用于字符串操作的函数。其中之一具有替换字符串中的子字符串的功能,并提出了一些问题。我在 C99 工作;在 Mac OS Sierra 和 FreeBSD 上编译。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char *repstr(char input[], char rep[], char new[]) {
char *output = malloc(strlen(input)*5); // <- Question 2
int replen = strlen(rep);
int newlen = strlen(new);
int a, b, c = 0;
// printf("input: %ld\t%s\n", strlen(input), input); // <- Question 1
while(input[a]) {
if(input[(a+b)] == rep[b]) {
if(b == replen - 1) {
strcat(output, new);
a += replen;
c += newlen;
b=0;
}
else b++;
} else {
output[c] = input[a];
a++;
c++;
}
}
return output;
}
int main() {
char buffer[] = "This is the test string test string test test string!";
char rep[] = "test";
char new[] = "tested";
int len = strlen(buffer);
char output[len+5];
printf("input: %d\t%s\n", len, buffer); // <- Question 1
strcpy(output, repstr(buffer, rep, new));
printf("output: %ld\t%s\n", strlen(output), output);
return 0;
}
问题 1:在 main() 中执行此行时,会导致段错误。但是,当在函数中执行时,一切似乎都正常。为什么?
问题 2:我意识到我需要为输出分配一块相当大的内存才能达到预期效果。 strlen(input)*5 是一个似乎可以工作的任意数字,但是为什么在降低数字时会出现看似“随机”的错误?
注意!由于这是我学习 C 编码过程的一部分,我主要不是对解决问题的(更有效的)预制解决方案感兴趣(已经有了它们),而是解释列出的两个问题 - 这样我就可以解决我自己的问题。
还有;这是我在 SO 论坛上的第一篇文章。你好。
【问题讨论】:
-
strlen返回size_t,所以使用%zu表示printf格式和变量的正确类型。new是c++ 的保留名称,应避免将其用作变量名。 -
1.
%ld是错误的格式类型。 2.如果先统计子串的出现次数,就可以算出新串的长度。 -
此外:您必须检查
mallocreturn!= NULL(它可能会失败)并由于内存中包含的随机值而初始化分配的内存。否则,您对strcat的呼叫是 UB。 -
顺便说一句,您的分段错误主要是由于:
int a, b, c = 0;应该是int a=0, b=0, c = 0;在您的代码中,a和b的值未初始化为零。 -
outputinmain不足以容纳结果!