作为我学习 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 论坛上的第一篇文章。你好。
最佳答案
Question 1: When this line is executed in main() it causes a segfault. However, when executed within the function everything seems to work fine. Why?
不,printf("input: %d\t%s\n", len, buffer); // <- Question 1
不是您的段错误的原因。
printf("output: %ld\t%s\n", strlen(output), output);
这部分是,strlen
不返回 int
但它返回 size_t
.如评论中所述,使用 %zu
打印出来。
此外,while(input[a])
将在 NULL 终止符处停止,这意味着您的 output
永远不会持有终止符,因此 printf
将继续阅读,您应该在最后添加它:
output[c] = '\0';
另外,正如@LPs 在评论中指出的那样,您应该对您使用的变量进行零初始化:
int a = 0, b = 0, c = 0;
Question 2: I have realized that I need a pretty large piece of memory allocated for the output to look as expected. strlen(input)*5 is an arbitrary number which seems to work, but why do I get seemingly 'random' errors when lowering the number?
可能是因为你没有分配足够的内存。由于字符串长度取决于运行时因素,因此无法知道所需的确切内存,因此您应该分配所需的最大内存量:
char *output = malloc(strlen(input) * strlen(new) + 1);
关于C - 替换字符串中的子字符串,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39953972/