#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void concatena(char *, char *, char *);
void conta_consonanti(char [], int *);
void copy_string(char [], char [ ], int);
int main(void) {
char *input1, *input2, *output;
input1 = "sdaeteruiop";
input2 = "eiyearteoiana";
concatena(input1, input2, output);
printf("%s\n", output);
free(output);
return 0;
}
void concatena(char *input1, char *input2, char *output) {
int num_cons1 = 0, num_cons2 = 0, dim_input1, dim_input2;
conta_consonanti(input1, &num_cons1);
conta_consonanti(input2, &num_cons2);
if (num_cons1 < num_cons2) {
dim_input1 = strlen(input1) + strlen(input2);
output = malloc(dim_input1 * sizeof(char));
copy_string(output, input1, 0);
copy_string(output, input2, strlen(input1));
} else if (num_cons2 < num_cons1) {
dim_input2 = strlen(input2) + strlen(input1);
output = malloc(dim_input2 * sizeof(char));
copy_string(output, input2, 0);
copy_string(output, input1, strlen(input2));
}
}
void conta_consonanti(char vect[], int *num_cons) {
int dim = strlen(vect), i;
for (i = 0; i < dim; i++)
if (vect[i] != 'a' && vect[i] != 'e' && vect[i] != 'i' && vect[i] != 'o' && vect[i] != 'u')
*num_cons++;
}
void copy_string(char output[], char input [ ], int offset) {
int dim, i;
dim = strlen(input);
for (i = 0; i < dim; i++) {
output[offset] = input[i];
offset++;
}
}
为什么我的代码给我分段错误?
程序应将两个字符串连接起来并将结果字符串存储在output
中,但它给我分段错误。为什么?
辅音较少的字符串首先存储。
答案 0 :(得分:2)
在
concatena(input1, input2, output);
printf("%s\n", output);
输出的值被 concatena 保持不变,因此您打印未初始化的字符* =>崩溃或任何其他未定义的行为
您需要将输出设为输出变数,因此void concatena(char *input1, char *input2, char **output)
等如下:
int main(void){
char *input1, *input2, *output;
input1 = "sdaeteruiop";
input2 = "eiyearteoiana";
concatena(input1, input2, &output);
printf("%s\n", output);
free(output);
return 0;
}
void concatena(char *input1, char *input2, char **output){
int num_cons1 = 0, num_cons2 = 0, dim_input1, dim_input2;
conta_consonanti(input1, &num_cons1);
conta_consonanti(input2, &num_cons2);
if(num_cons1 < num_cons2){
dim_input1 = strlen(input1) + strlen(input2);
*output = malloc(dim_input1 + 1);
strcpy(*output, input1);
strcat(*output, input2);
}else {
dim_input2 = strlen(input2) + strlen(input1);
*output = malloc(dim_input2 + 1);
strcpy(*output, input2);
strcat(*output, input1);
}
}
我还修复了您的malloc,您为空终止符错过了1个字符
如果未设置num_cons2 == num_cons1
*输出并且仍打印未初始化,则发出警告,您需要将其设置为NULL并测试该大小写,然后再进行打印,或更可能用else if(num_cons2 < num_cons1)
替换else
(这是我上面所做的)
还请注意dim_input1
和dim_input2
的值相同,无法区分它们
,copy_string
的第一个调用可以用strcpy
替换,第二个调用可以用strcat
替换,除了copy_string
缺少最后一个空字符之外,< / strong>。我删除了使用copy_string
警告声明void concatena(char *, char *, char *);
必须更新为void concatena(char *, char *, char **);
执行:
eiyearteoianasdaeteruiop
在 valgrind 下:
pi@raspberrypi:~ $ valgrind ./a.out
==15629== Memcheck, a memory error detector
==15629== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==15629== Using Valgrind-3.13.0 and LibVEX; rerun with -h for copyright info
==15629== Command: ./a.out
==15629==
eiyearteoianasdaeteruiop
==15629==
==15629== HEAP SUMMARY:
==15629== in use at exit: 0 bytes in 0 blocks
==15629== total heap usage: 2 allocs, 2 frees, 1,049 bytes allocated
==15629==
==15629== All heap blocks were freed -- no leaks are possible
==15629==
==15629== For counts of detected and suppressed errors, rerun with: -v
==15629== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 6 from 3)
答案 1 :(得分:2)
您的代码中存在多个问题:
concatena
。 API不正确:您应该使concatena
返回指向新分配的数组的指针作为返回值。当前实现覆盖第三个参数output
这个分配的值永远不会返回给调用者。 C没有 output 参数的概念,您可以将指针传递给调用者的output
指针,类型为char **
,但是使用返回值要简单得多。 由concatena
执行的分配是错误的:您应为null终止符分配一个额外的字节,并且sizeof(char)
根据定义为1
:
output = malloc(dim_input1 + 1);
conta_consonanti
也不正确:必须将num_cons
或++*num_cons
写成(*num_cons)++
所指向的数字递增。 *num_cons++;
递增指针,而不是所指向的值。此外,正如汤姆·兰德尔(Tom Randall)所评论的那样,辅音的数量不一定与非元音的数量相同,因为字符串可能包含非字母。另外算上所有大写字母为辅音,这似乎不正确了。
如果两个字符串具有相同数量的辅音,则代码将具有未定义的行为,您应指定在这种情况下发生的情况(并实现)。
copy_string
未在目标缓冲区中设置空终止符。可以在此处进行设置,也可以在concatena
中手动进行设置。
这是经过更正(简化)的版本:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char *concatena(const char *s1, const char *s2);
int conta_consonanti(const char *vect);
void copy_string(char *output, const char *intput);
int main(void) {
const char *input1 = "sdaeteruiop";
const char *input2 = "eiyearteoiana";
char *output = concatena(input1, input2);
printf("%s\n", output);
free(output);
return 0;
}
char *concatena(const char *input1, const char *input2) {
int len1 = strlen(input1);
int len2 = strlen(input2);
int num_cons1 = conta_consonanti(input1);
int num_cons2 = conta_consonanti(input2);
char *output = malloc(len1 + len2 + 1);
if (output != NULL) {
if (num_cons1 <= num_cons2) {
copy_string(output, input1, 0);
copy_string(output, input2, len1);
} else {
copy_string(output, input2);
copy_string(output, input1, len1);
}
output[len1 + len2] = '\0'; // set the null terminator
}
return output;
}
int conta_consonanti(const char *vect) {
int i, num_cons = 0;
for (i = 0; vect[i] != '\0'; i++) {
/* counting ASCII consonants, upper and lowercase */
/* our French friends will miss the ç and our Spanish ones the ñ */
if (strchr("BCDFGHJKLMNPQRSTVWXYZbcdfghjklmnpqrstvwxyz", vect[i])
num_cons++;
}
return num_cons;
}
void copy_string(char *output, const char *input, int offset) {
int i;
for (i = 0; input[i] != '\0'; i++) {
output[offset] = input[i];
offset++;
}
}
答案 2 :(得分:0)
您尝试释放main中的output
,但未分配任何值。 concatena
中的分配不会返回到main。从concatena
内部返回已分配的缓冲区并将其分配给output
,然后最后对其进行清理,会更有意义。