附加两个字符串

时间:2018-02-20 00:56:17

标签: c

我试图编写代码来附加两个没有函数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;
}

我该如何解决?

2 个答案:

答案 0 :(得分:2)

您的代码中存在一些错误:

  1. 请勿使用gets 。这个功能是危险的,因为它没有采取 考虑缓冲区的大小。请改用fgets

  2. 您的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;
    }
    
  3. str1可能会因为持有两个字符串而缩短。如果str2包含"Hello" 并且str2包含"World!",您将溢出缓冲区。制作 缓冲区更大。

  4. 如果您自己编写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;
}