[英]concatenate two strings without strcat
我想在不使用strcat()函数的情况下连接两个字符串。但是我没有得到所需的结果。 请指出我的错误。
void main() {
char s1[100], s2[100];
int i;
puts("First string?");
gets(s1);
puts("Second string?");
gets(s2);
for (i = strlen(s1); i <= (strlen(s1) + strlen(s2)); i++) {
s1[i] = s2[i - strlen(s1)];
}
puts(s1);
}
我对您的程序没有真正的改变,但是这就是我(从您的程序修改而来的)并且可以正常工作。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(void)
{
char s1[100], s2[100];
size_t i, s1l, s2l, total;
puts("First string?");
fgets(s1, sizeof(s1), stdin);
s1[strlen(s1) - 1] = 0x00;
puts("Second string?");
fgets(s2, sizeof(s2), stdin);
s2[strlen(s2) - 1] = 0x00;
s1l = strlen(s1);
s2l = strlen(s2);
total = s1l + s2l;
for(i = s1l; i <= total; i++)
{
s1[i] = s2[i - s1l];
}
puts(s1);
return(0);
}
使用您的程序逐字记录,问题在于,由于s1的长度在循环的每次迭代中都在变化,因此支票中的strlen(s1)的值一直在增加,因此您基本上将最终遇到一个无限循环...至少直到遇到随机的空字节为止。 但是,当事先计算字符串的长度时,循环终点计数不会改变,从而可以产生正确的输出。 我的代码将使用clang编译器在FreeBSD 10.2系统上编译并正确运行。
附带说明, 请勿在main上返回void。 始终返回int。 还指定您计划使用的库头。
编辑:我修改了代码以使用fgets而不是gets,因为gets完全不安全。 它不检查缓冲区大小,因此您很容易发生缓冲区溢出。
使用sprintf的变体:
简单
char buf[200];
sprintf(buf, "%s%s" s1, s2);
更简单,更安全
char buf[200]
snprintf(buf, sizeof(buf), "%s%s", s1, s2);//prevents buffer overflow
或者,修改循环(有关原因,请参见行注释):
int main(void)//note changed main prototype
{
char s1[100], s2[100];//caution here: s1 must be big enough
//to contain its string as well as
//the string stored in s2, plus 1 for NULL
int i;
int len1, len2;//create variables to store string lengths
puts("First string?");
gets(s1);//note, gets is no longer recommended
puts("Second string?");
gets(s2);
len1 = strlen(s1);//store string lengths only once
len2 = strlen(s2);//to avoid calling them repeatedly in loop
for(i = 0; i < len2; i++)//index i in one place only
{
s1[len1+i] = s2[i];
}
s1[len1 + i]=0;//null terminate string when done.
puts(s1);
getchar();//added to pause execution in my environment.
return 0;
}
s1的长度在运行时更改,这使索引i不正确。 尝试以下类似的方法:-
l = strlen(s1);
for(i = 0; i < strlen(s2); i++)
{
s1[l++] = s2[i];
}
s1[l] = '\0';
假设s1 =“ hello”且s2 =“ world”,则在第一次迭代中s1 = 5,索引s2 = 0(i- length(s1)); 效果很好。 但是在第二次迭代中,长度(s1)= 6,索引s2 = 0(i-length(s1))。 因此从s2提取字符的索引不变。 这是关于实现中的问题,尽管您应该通过使用sprintf来获得有效的方式。
sprintf(s1, "%s%s", s1, s2);
您的解决方案不起作用,因为您在每次迭代时都要重新计算strlen(s1)
以测试是否完成并计算s2
的偏移量以从中复制字符,但是您在循环中修改了s1
,因此长度改变了,甚至更糟了s1
暂时不再以'\\0'
终止:测试表达式i <= strlen(s1) + strlen(s2)
调用未定义的行为,当您第二遍复制s2[i - strlen(s1)]
, s2[i - strlen(s1)]
发生同样的情况环。
使用以下思路更正您的代码:
不要使用gets
读取输入,请使用fgets()
并删除最后的'\\n'
。
仅计算一次s1
和s2
的长度,并将它们存储在局部变量中。
验证串联的大小不会超过s1
的大小。
使用这些局部变量重写循环,或使用strcpy
或memcpy
。
这是一个例子:
#include <stdio.h>
#include <string.h>
int main(void) {
char s1[100], s2[100];
size_t i, len1, len2;
puts("First string?");
if (!fgets(s1, sizeof s1, stdin))
return 1;
len1 = strlen(s1);
if (len1 > 0 && s1[len1 - 1] == '\n')
s1[--len1] = '\0';
puts("Second string?");
if (!fgets(s2, sizeof s2, stdin))
return 1;
len2 = strlen(s2);
if (len2 > 0 && s2[len2 - 1] == '\n')
s1[--len2] = '\0';
if (len1 + len2 >= sizeof s1)
return 2;
/* copy the characters from s2 including the final '\0' */
for (i = 0; i <= len2; i++) {
s1[len1 + i] = s2[i];
}
puts(s1);
return 0;
}
// A simple strcat function
int main(void)
{
char str1[100] ="Avis";
stringcat(str1,"karthik");
printf("\n%s",str1);
return 0;
}
void stringcat(char *str1, char *str2)
{
while(*str1)
str1++;
while(*str2)
*str1++ = *str2++;
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.