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
'sourcecode' 카테고리의 다른 글
GDB에서 특정 중단점이 히트했을 때 특정 액션을 수행하려면 어떻게 해야 합니까? (0) | 2022.08.17 |
---|---|
Vue - 중첩된 속성의 기본값 (0) | 2022.08.17 |
"실험 구문 'jsx'에 대한 지원이 현재 활성화되지 않았습니다." vue 및 jest를 사용합니다. (0) | 2022.08.17 |
어레이가 변경되어 v-key가 지정된 경우에도 VueJ가 목록을 다시 렌더링하지 않음 (0) | 2022.08.17 |
vuex 스토어의 악리를 통해 게시한 후 리다이렉트하는 올바른 방법 (0) | 2022.08.17 |