我正在尝试构建一个函数,无论大小如何都将两个字符串交错在一起(虽然可以假设它不到100个字符)并输出指向新字符串的指针。
char* interleaved(const char* s1, const char* s2){
char *word = malloc (sizeof (char) * 100);
const char *p = s1;
const char *p2 = s2;
int i = 0;
while(*p != '\0' || *p2 != '\0'){
if(i%2 == 0){
word[i] = *p;
p++;
}
if(i%2 == 1){
word[i] = *p2;
p2++;
}
i++;
}
if(*p == '\0'){
while(*p2 != '\0'){
word[i] = *p2;
p2++;
i++;
}
}
if(*p2 == '\0'){
while(*p != '\0'){
word[i] = *p;
p++;
i++;
}
}
word[i] = '\0';
return word;
}
目前,如果两个字符串长度相同,它将起作用,例如'dog'和'cat'将产生'dcoagt',但如果字符串不均匀,例如'dogbird'和'cat',我会得到'dcoagtb',并且如果第二个字符串更长,我就得到'dcoagt'。在原来的while循环之后我的两个if语句中出现了一些错误,但是我不确定它是什么,有人可以看看并帮助我吗?
干杯
答案 0 :(得分:3)
第一个循环应该使用&&
而不是||
。
while(*p != '\0' && *p2 != '\0')
使用&&
会在字符串耗尽时立即停止。使用||
会继续,直到两个字符串都用完为止。这很糟糕,因为较短的弦乐指针会从最后一直延伸到无人区域。
答案 1 :(得分:0)
John Kugelman中answer已解决了主要问题,但代码相当冗长。你可以写:
char *interleaved(const char *s1, const char *s2)
{
char *word = malloc(strlen(s1) + strlen(s2) + 1);
if (word == 0)
return 0;
int i = 0;
const char *p1 = s1;
const char *p2 = s2;
while (*p1 != '\0' && *p2 != '\0')
{
word[i++] = *p1++;
word[i++] = *p2++;
}
while (*p1 != '\0')
word[i++] = *p1++;
while (*p2 != '\0')
word[i++] = *p2++;
word[i] = '\0';
return word;
}
请注意,这会检查内存分配是否成功。代码分配了必要的空间量;它既不会在传递短字符串时浪费空间,也不会在传递长字符串时失败。
循环更紧凑,充分利用++
运算符。 if
测试是多余的。在主循环结束时,将执行以下两个循环中的至多一个循环的主体(一个用于较长的字符串,或者如果输入字符串的长度相同,则不执行)。
我保留p1
(好吧,将p
重命名为p1
)和p2
,但代码同样可以使用s1
和{{1相反。我还保留了下标s2
并使用了i
符号;在word[i++]
代替char *dst = word;
代替*dst++
当然可以使用word[i++]
然后*dst
代替word[i]
。这甚至可能在显微镜下更有效 - 但这不是使用符号的理由;另一方面,对称性是使用符号的原因。
这些变化导致:
char *interleaved(const char *s1, const char *s2)
{
char *word = malloc(strlen(s1) + strlen(s2) + 1);
if (word == 0)
return 0;
char *dst = word;
while (*s1 != '\0' && *s2 != '\0')
{
*dst++ = *s1++;
*dst++ = *s2++;
}
while (*s1 != '\0')
*dst++ = *s1++;
while (*s2 != '\0')
*dst++ = *s2++;
*dst = '\0';
return word;
}