我想在不使用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);
}
答案 0 :(得分:2)
我在你的程序中没有太大的改变,但这就是我所拥有的(从你的程序中修改)并且它有效。
#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代替获取,因为获取完全不安全。它不检查缓冲区大小,因此您可以轻松地缓冲区溢出。答案 1 :(得分:1)
使用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;
}
答案 2 :(得分:1)
s1的长度在运行时会发生变化,使得索引不正确。尝试以下内容: -
l = strlen(s1);
for(i = 0; i < strlen(s2); i++)
{
s1[l++] = s2[i];
}
s1[l] = '\0';
假设s1 =&#34;你好&#34;并且s2 =&#34; world&#34 ;,然后在s1 = 5的第一次迭代长度和s2 = 0的索引(i-长度(s1));效果很好。但是在第二次迭代中,长度(s1)= 6,索引为s2 = 0(i-length(s1))。因此从s2获取角色的索引不会改变。这是关于实现中的问题,尽管使用sprintf应该是一种有效的方法。
sprintf(s1, "%s%s", s1, s2);
答案 3 :(得分:0)
您的解决方案不起作用,因为您在每次迭代时重新计算strlen(s1)
以测试完成情况,并在s2
中计算从中复制字符的偏移量,但您修改了s1
循环,所以长度发生变化,更糟糕的是,s1
暂时不再'\0'
终止:测试表达式i <= strlen(s1) + strlen(s2)
调用未定义的行为,复制{{1}时也是如此第二次循环。
使用这些想法来纠正您的代码:
请勿使用s2[i - strlen(s1)]
阅读输入,使用gets
并删除最终fgets()
。
仅计算'\n'
和s1
的长度,并将其存储在局部变量中。
验证串联不会超过s2
的大小。
使用这些局部变量重写循环,或使用s1
或strcpy
。
以下是一个例子:
memcpy
答案 4 :(得分:0)
catch