[c] C에서 const / literal 문자열을 어떻게 연결합니까?

나는 C에서 일하고 있으며 몇 가지를 연결해야합니다.

지금 나는 이것을 가지고있다 :

message = strcat("TEXT ", var);

message2 = strcat(strcat("TEXT ", foo), strcat(" TEXT ", bar));

이제 C에 경험이 있다면 실행하려고 할 때 세분화 오류가 발생한다는 것을 알고 있습니다. 어떻게 해결할 수 있습니까?



답변

C에서 “문자열”은 단순한 char배열입니다. 따라서 다른 “문자열”과 직접 연결할 수 없습니다.

strcat가리키는 문자열 src끝에 다음을 가리키는 문자열을 추가 하는 함수 를 사용할 수 있습니다 dest.

char *strcat(char *dest, const char *src);

다음은 cplusplus.com예입니다 .

char str[80];
strcpy(str, "these ");
strcat(str, "strings ");
strcat(str, "are ");
strcat(str, "concatenated.");

첫 번째 매개 변수의 경우 대상 버퍼 자체를 제공해야합니다. 대상 버퍼는 문자 배열 버퍼 여야합니다. 예 :char buffer[1024];

첫 번째 매개 변수에 복사하려는 내용을 저장할 공간이 충분한 지 확인하십시오 . 사용 가능한 경우 다음 strcpy_s과 같은 기능을 사용하는 것이 안전 strcat_s하며 대상 버퍼의 크기를 명시 적으로 지정해야합니다.

참고 : 문자열 리터럴은 상수이므로 버퍼로 사용할 수 없습니다. 따라서 항상 버퍼에 char 배열을 할당해야합니다.

의 반환 값은 strcat무시해도되며 첫 번째 인수로 전달 된 것과 동일한 포인터 만 반환합니다. 편의를 위해 호출을 한 줄의 코드로 연결할 수 있습니다.

strcat(strcat(str, foo), bar);

따라서 다음과 같이 문제를 해결할 수 있습니다.

char *foo = "foo";
char *bar = "bar";
char str[80];
strcpy(str, "TEXT ");
strcat(str, foo);
strcat(str, bar);


답변

strcatC 코드에서는 사용하지 마십시오 . 가장 깨끗하고 가장 중요한 방법은 다음을 사용하는 것입니다 snprintf.

char buf[256];
snprintf(buf, sizeof buf, "%s%s%s%s", str1, str2, str3, str4);

일부 의견 제시 자들은 인수의 개수가 형식 문자열과 일치하지 않을 수 있으며 코드가 여전히 컴파일 될 것이라는 문제를 제기했지만 대부분의 컴파일러는 이러한 경우 경고를 표시합니다.


답변

사람들은 str n cpy (), str n cat () 또는 s n printf ()를 사용하십시오.

버퍼 공간을 초과하면 메모리에서 뒤 따르는 모든 것이 버려집니다!

(그리고 후행 null ‘\ 0’문자를위한 공간을 확보해야합니다!)


답변

컴파일 타임에 문자열을 연결할 수도 있습니다.

#define SCHEMA "test"
#define TABLE  "data"

const char *table = SCHEMA "." TABLE ; // note no + or . or anything
const char *qry =               // include comments in a string
    " SELECT * "                // get all fields
    " FROM " SCHEMA "." TABLE   /* the table */
    " WHERE x = 1 "             /* the filter */
                ;


답변

또한 몇 개의 문자열이 연결되어 있는지 미리 알지 못하는 경우 malloc 및 realloc도 유용합니다.

#include <stdio.h>
#include <string.h>

void example(const char *header, const char **words, size_t num_words)
{
    size_t message_len = strlen(header) + 1; /* + 1 for terminating NULL */
    char *message = (char*) malloc(message_len);
    strncat(message, header, message_len);

    for(int i = 0; i < num_words; ++i)
    {
       message_len += 1 + strlen(words[i]); /* 1 + for separator ';' */
       message = (char*) realloc(message, message_len);
       strncat(strncat(message, ";", message_len), words[i], message_len);
    }

    puts(message);

    free(message);
}


답변

출력 버퍼를 초기화하는 것을 잊지 마십시오. strcat에 대한 첫 번째 인수는 결과 문자열에 충분한 공간이 할당 된 널 종료 문자열이어야합니다.

char out[1024] = ""; // must be initialized
strcat( out, null_terminated_string );
// null_terminated_string has less than 1023 chars


답변

사람들이 지적했듯이 문자열 처리가 많이 향상되었습니다. 따라서 C 스타일 문자열 대신 C ++ 문자열 라이브러리를 사용하는 방법을 배우고 싶을 수도 있습니다. 그러나 여기 순수한 C의 해결책이 있습니다.

#include <string.h>
#include <stdio.h>
#include <stdlib.h>

void appendToHello(const char *s) {
    const char *const hello = "hello ";

    const size_t sLength     = strlen(s);
    const size_t helloLength = strlen(hello);
    const size_t totalLength = sLength + helloLength;

    char *const strBuf = malloc(totalLength + 1);
    if (strBuf == NULL) {
        fprintf(stderr, "malloc failed\n");
        exit(EXIT_FAILURE);
    }

    strcpy(strBuf, hello);
    strcpy(strBuf + helloLength, s);

    puts(strBuf);

    free(strBuf);

}

int main (void) {
    appendToHello("blah blah");
    return 0;
}

그것이 올바른지 안전한지 확실하지 않지만 현재 ANSI C에서 더 좋은 방법을 찾을 수 없었습니다.