我正在用C编写一个程序,该程序用字符串替换char *中名为“ template”的数字,但是我不断遇到Segmentation Fault:11错误。
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
char *rep_str(const char *s, const char *old, const char *new1){
char *ret;
int i, count = 0;
int newlen = strlen(new1);
int oldlen = strlen(old);
for (i = 0; s[i] != '\0'; i++){
if (strstr(&s[i], old) == &s[i]){
count++;
i += oldlen - 1;
}
}
ret = (char*)malloc(i + count * (newlen - oldlen));
if (ret == NULL)
exit(EXIT_FAILURE);
i = 0;
while (*s){
if (strstr(s, old) == s){ //compare the substring with the newstring
strcpy(&ret[i], new1);
i += newlen; //adding newlength to the new string
s += oldlen;//adding the same old length the old string
} else {
ret[i++] = *s++;
}
}
ret[i] = '\0';
return ret;
}
char* madlib_by_numbers(char* temp, int word_count, char* words[]){
char* numbers[] = {"0", "1", "2", "3", "4", "5", "6", "7", "8", "9"};
int tempSize = strlen(temp);
for (int i = 0; i < tempSize; i++){
if (isdigit(temp[i])){
for (int j = 0; j < (sizeof(numbers) / sizeof(char*)); j++){
temp = rep_str(temp, numbers[j], words[j]); //it makes it to this line, but never gets to assert()
}
}
}
return temp;
}
int main() {
char* temp1 = "The 1 0 likes to 2 in the moonlight.";
char* words[] = {"git", "brilliant", "swim"};
char* result = "The brilliant git likes to swim in the moonlight.";
int stringLength = strlen(result);
char* test = madlib_by_numbers(temp1, 3, words);
assert(strncmp(test, result, stringLength) == 0);
free(test);
return 0;
}
当我运行调试器时,它只是说: Segmentation Fault: 11
我仅想了解的是分段错误错误的来源,我怀疑我的循环之一运行了太多次。
ret = (char*)malloc(i + count * (newlen - oldlen));
这行代码存在一些问题。
void *
您要分配给不同指针类型的变量的malloc,反之亦然)。'\0'
在哪里?您需要意识到,对于一个空old
字符串,这将是malloc(0)
并且零字节不足以存储一个空字符串。old
字符串可能是的子字符串,那么也会有一个问题new
(例如,您要替换"0"
为"hell0"
)。您需要调整算法以解决此问题。我会把它留给您尝试的挑战:)for (int i = 0; i < tempSize; i++){
if (isdigit(temp[i])){
for (int j = 0; j < (sizeof(numbers) / sizeof(char*)); j++){
temp = rep_str(temp, numbers[j], words[j]); //it makes it to this line, but never gets to assert()
}
}
}
用户先前的答案正确地突出显示了此代码,但原因不正确...因此他/她提出的解决方案是错误的。
isdigit(temp[i])
可能还会对某些输入造成段错误。isdigit((unsigned char) temp[i])
在这种情况下,我建议使用代替。
words[j]
在word_count
3j
大于或等于3的位置访问是无效的;您正在访问该数组的边界。
您还需要注意您的free
所有内存*alloc
(同时不要free
占用您没有的内存*alloc
)。忘记做前者不会导致崩溃,但是您的程序不会快乐地运行。它会使用内存堆。
考虑这样的事情,而不是:
temp = strdup(temp);
if (temp == NULL) {
exit(EXIT_FAILURE);
}
for (int i = 0; i < tempSize; i++){
if (isdigit((unsigned char) temp[i])){
for (int i = min(word_count, sizeof(numbers) / sizeof(char*)), j = 0; j < i; j++){
char *new = rep_str(temp, numbers[j], words[j]);
free(temp);
temp = new;
}
}
}
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句