我试图编写代码来附加两个没有函数strcat的字符串,但它不起作用。它仅在输入为单个char时有效。
以下是代码:
#include <stdio.h>
#include <string.h>
/*
Return the result of appending the characters in s2 to s1.
Assumption: enough space has been allocated for s1 to store the extra
characters.
*/
char* append (char s1[], char s2[]) {
int s1len = strlen (s1);
int s2len = strlen (s2);
int k;
for (k=0; k<s2len; k++) {
s1[k+s1len] = s2[k];
}
return s1;
}
int main ( ) {
char str1[10];
char str2[10];
while (1) {
printf ("str1 = ");
if (!gets(str1)) {
return 0;
};
printf ("str2 = ");
if (!gets(str2)) {
return 0;
};
printf ("The result of appending str2 to str1 is %s.\n",
append (str1, str2));
}
return 0;
}
我该如何解决?
答案 0 :(得分:2)
您的代码中存在一些错误:
请勿使用gets
。这个功能是危险的,因为它没有采取
考虑缓冲区的大小。请改用fgets
。
您的append
函数未写入'\0'
- 终止字节。这应该
是
char* append (char s1[], char s2[]) {
int s1len = strlen (s1);
int s2len = strlen (s2);
int k;
for (k=0; k<s2len; k++) {
s1[k+s1len] = s2[k];
}
s1[k+s1len] = 0; // writing the 0-terminating byte
return s1;
}
str1
可能会因为持有两个字符串而缩短。如果str2
包含"Hello"
并且str2
包含"World!"
,您将溢出缓冲区。制作
缓冲区更大。
如果您自己编写strcat
,我会传递目的地的大小
缓冲区也是如此,这样你就不会溢出缓冲区:
char *mystrcat(char *t1, const char *t2, size_t maxsize)
{
if(t1 == NULL || t2 == NULL)
return NULL;
size_t s1 = strlen(t1);
size_t s2 = strlen(t2);
size_t i;
for(i = 0; i < s2 && (s1 + i) < maxsize - 1 ; ++i)
t1[i + s1] = t2[i];
t1[i + s1] = 0; // terminating the
return t1;
}
int main(void)
{
char str1[30] = "Hello ";
char str2[30] = "World!";
printf("mystrcat(\"%s\", \"%s\") = %s\n", str1, str2,
mystrcat(str1, str2, sizeof str1));
char str3[100] = "This is a long sentence";
printf("mystrcat(\"%s\", \"%s\") = %s\n", str1, str3,
mystrcat(str1, str3, sizeof str1));
char line[100];
printf("Enter some text: ");
fflush(stdout);
fgets(line, sizeof line, stdin);
line[strcspn(line, "\n")] = 0; // removing possible newline
strcpy(str3, "User input was: ");
printf("mystrcat: %s\n", mystrcat(str3, line, sizeof str3));
return 0;
}
那将返回
mystrcat("Hello World!", "World!") = Hello World!
mystrcat("Hello World!This is a long se", "This is a long sentence") = Hello World!This is a long se
Enter some text: ABC DEF user input is great
mystrcat: User input was: ABC DEF user input is great
答案 1 :(得分:1)
您的结果字符串未正确终止。
C中的字符串始终以NUL(0)字符终止。
gets
不安全,请改用fgets
。
养成检查缓冲区大小的习惯。
为了给你一个想法,这里是一个使用fgets +缓冲区大小检查的简约实现:
#include <stdio.h> // fprintf, fgets
#include <string.h> // strlen
const char *concatenate(char *dst, size_t sz, const char *s1, const char *s2) {
size_t l1 = strlen(s1);
size_t l2 = strlen(s2);
// Check for overflow
if ((l1 + l2 + 1) > sz) {
return NULL;
}
// Copy first string
for (size_t i = 0; i < l1; ++i) {
dst[i] = s1[i];
}
// Copy second string
for (size_t i = 0; i < l2; ++i) {
dst[l1 + i] = s2[i];
}
// Add NUL terminator
dst[l1 + l2 + 1] = 0;
return dst;
}
int main() {
// Allocate two strings (9 chars max.)
char first_string[10];
char second_string[10];
char concatenated_string[20];
// Read first string from stdin
fprintf(stdout, "str1 = ");
// !!! fgets return value check omitted for simplicity.
fgets(first_string, sizeof(first_string), stdin);
// Read second string from stdin
fprintf(stdout, "str2 = ");
// !!! fgets return value check omitted for simplicity.
fgets(second_string, sizeof(second_string), stdin);
const char *tmp = concatenate(concatenated_string, sizeof(concatenated_string), first_string, second_string);
if (!tmp) {
fprintf(stderr, "would overflow\n");
} else {
fprintf(stdout, "concatenated: %s\n", concatenated_string);
}
return 0;
}