sourcecode

C의 char 문자열을 수정할 수 있습니까?

copyscript 2022. 8. 17. 23:53
반응형

C의 char 문자열을 수정할 수 있습니까?

여러 가지 C 튜토리얼이나 포인터 관련 서적에서 몇 시간 동안 고민하고 있습니다만, 정말 궁금한 것은 작성 후 char pointer를 변경할 수 있는지 여부입니다.

제가 시도한 것은 다음과 같습니다.

char *a = "This is a string";
char *b = "new string";

a[2] = b[1]; // Causes a segment fault

*b[2] = b[1]; // This almost seems like it would work but the compiler throws an error.

그러면 포인터 주소가 아닌 문자열 내의 값을 변경할 수 있는 방법이 있습니까?

소스 코드에 "문자열"을 쓰면 해당 값을 컴파일 시 알아야 하기 때문에 실행 파일에 직접 입력됩니다(소프트웨어를 분리하여 그 안에 있는 모든 일반 텍스트 문자열을 찾을 수 있는 도구가 있습니다). 쓸 때char *a = "This is a string" "This is string" 은 "This is string" 입니다.a인트,, 실실실실실다다실행 가능한 이미지의 데이터는 읽기 전용입니다.

(다른 답변에서 지적한 바와 같이) 읽기 전용이 아닌 장소(히프 또는 스택프레임)에 메모리를 작성해야 합니다.로컬 배열을 선언하면 해당 배열의 각 요소에 대한 공간이 스택에 생성되고 문자열 리터럴(실행 파일에 저장됨)이 스택 내의 해당 공간에 복사됩니다.

char a[] = "This is a string";

하려면 , 히프에 , 「」를 사용합니다.strcpy()이치노

char *a = malloc(256);
strcpy(a, "This is a string");

malloc() 않고 free()(영어: 英英英英英英英英英英英英英英英英英英英英).

기본적으로 데이터의 위치를 추적해야 합니다.쓸 않을 될 수 있습니다. 하지 경우 파일의 동작이 변경될 수 ).char *a = "hello"; 에 바뀌었어요.a[0]로로 합니다.'c' 다른 에 이렇게 써놨어요.printf("hello");의 첫 할 수 "hello"하시는 컴파일러는해 두어야 함 후 1회만 저장합니다.printf("hello");할 수 있습니다.cello

문자열은 읽기 전용 메모리에 저장할 수 있으므로 수정할 수 없습니다.이를 수정하려면 어레이를 대신 사용할 수 있습니다.

char a[] = "This is a string";

또는 malloc를 사용하여 메모리를 할당할 수도 있습니다.

char *a = malloc(100);
strcpy(a, "This is a string");
free(a); // deallocate memory once you've done

많은 사람들이 char*와 char[]의 차이와 C의 문자열 리터럴을 혼동하고 있습니다.글을 쓸 때:

char *foo = "hello world";

...실제로 foo를 가리키고 있습니다(실제로 컴파일러가 "hello world"에서 수행하는 작업은 구현에 의존합니다).

대신 char[]를 사용하면 컴파일러에 배열을 생성하여 "hello world"라는 내용으로 채우는 것이 좋습니다.foo는 char 배열의 첫 번째 인덱스에 대한 포인터입니다.둘 다 char 포인터이지만 char[]만 로컬로 할당되어 변경 가능한 메모리블록을 가리킵니다.

a와 b의 메모리는 사용자에 의해 할당되지 않았습니다.컴파일러는 문자를 저장할 읽기 전용 메모리 위치를 자유롭게 선택할 수 있습니다.따라서 변경하려고 하면 세그먼트 장애가 발생할 수 있습니다.그래서 캐릭터 배열을 직접 만드는 것이 좋습니다.거 있잖아요.char a[10]; strcpy(a, "Hello");

질문에 답한 것 같습니다만, 왜 char *a = "String"이 읽기 전용 메모리에 저장되어 있는지 궁금할 수 있습니다.실제로는 c99 표준에서는 정의되어 있지 않지만 대부분의 컴파일러는 다음과 같은 경우에 이 방법을 선택합니다.

printf("Hello, World\n");

c99 standard (pdf) [130페이지, 섹션 6.7.8] :

선언:

char s[] = "abc", t[3] = "abc";

는 요소가 문자열 리터럴로 초기화되는 "signed" char 배열 객체와 t를 정의합니다.이 선언은 char와 동일합니다.

s[] = { 'a', 'b', 'c', '\0' }, t[] = { 'a', 'b', 'c' };

어레이의 내용은 변경할 수 있습니다.한편, 선언문은

char *p = "abc";

는 type "filename to char"로 p를 정의하고 type "array of char"의 오브젝트를 가리키도록 초기화합니다.이 오브젝트의 길이는 4입니다.이 오브젝트의 요소는 문자열 리터럴로 초기화됩니다.p를 사용하여 배열의 내용을 수정하려고 하면 동작은 정의되지 않습니다.

,도할 수 .strdup:

   The strdup() function returns a pointer to a new string which is a duplicate of the string  s.
   Memory for the new string is obtained with malloc(3), and can be freed with free(3).

예를 들어 다음과 같습니다.

char *a = strdup("stack overflow");

모두 문자열 리터럴을 읽기 전용 메모리에 저장하기 때문에 수정할 수 없는 이유를 설명하는 좋은 답변입니다.하지만, 밀어붙이기만 하면, 이것을 할 수 있는 방법이 있다.다음의 예를 참조해 주세요.

#include <sys/mman.h>
#include <unistd.h>
#include <stddef.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>

int take_me_back_to_DOS_times(const void *ptr, size_t len);

int main()
{
    const *data = "Bender is always sober.";
    printf("Before: %s\n", data);
    if (take_me_back_to_DOS_times(data, sizeof(data)) != 0)
        perror("Time machine appears to be broken!");
    memcpy((char *)data + 17, "drunk!", 6);
    printf("After: %s\n", data);

    return 0;
}

int take_me_back_to_DOS_times(const void *ptr, size_t len)
{
    int pagesize;
    unsigned long long pg_off;
    void *page;

    pagesize = sysconf(_SC_PAGE_SIZE);
    if (pagesize < 0)
        return -1;
    pg_off = (unsigned long long)ptr % (unsigned long long)pagesize;
    page = ((char *)ptr - pg_off);
    if (mprotect(page, len + pg_off, PROT_READ | PROT_WRITE | PROT_EXEC) == -1)
        return -1;
    return 0;
}

저는 항상 정확성에 대한 저의 좀 더 깊은 생각의 일환으로 이 글을 썼는데, 여러분이 흥미를 느끼실 수도 있을 것입니다(나는 희망:).

도움이 됐으면 좋겠다.행운을 빕니다.

문자열을 읽기 전용 메모리 버퍼가 아닌 다른 메모리 버퍼에 복사하고 거기에서 변경해야 합니다.스트링을 복사하려면 strncpy()를 사용하고 스트링 길이를 검출하려면 strlen()을 사용하고 새 스트링에 버퍼를 동적으로 할당하려면 malloc()를 사용합니다.

예를 들어 (C++ 유사코드):

int stringLength = strlen( sourceString );
char* newBuffer = malloc( stringLength + 1 );

// you should check if newBuffer is 0 here to test for memory allocaton failure - omitted

strncpy( newBuffer, sourceString, stringLength );
newBuffer[stringLength] = 0;

// you can now modify the contents of newBuffer freely

free( newBuffer );
newBuffer = 0;
char *a = "stack overflow";
char *b = "new string, it's real";
int d = strlen(a);

b = malloc(d * sizeof(char));
b = strcpy(b,a);
printf("%s %s\n", a, b);

언급URL : https://stackoverflow.com/questions/1011455/is-it-possible-to-modify-a-string-of-char-in-c

반응형