Im은 C 프로그래밍을 배우기 시작하고 Im은 문자열을 부분 문자열 목록으로 분할하려고합니다. String이라는 문자열을 만드는 구조를 만들었습니다.c에서 문자열 목록 만들기가 작동하지 않습니까?
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
typedef struct dynamic_string {
char* data;
size_t capacity;
size_t size;
} String;
void free_string(String* s) { free(s->data); s->data = NULL; }
void print_string(String* s) { for (int i = 0; i < s->size; ++i) { printf("%c", s->data[i]); } printf("\n"); }
void clear_string(String* s) { s->size = 0; s->data[0] = '\0'; }
int string_init(String* s, size_t init_capacity) {
s->data = malloc(init_capacity);
if (!s->data) { return -1; };
s->size = 0; s->capacity = init_capacity;
return 0;
}
void add_char(String* s, char element) {
size_t new_size = s->size + 1;
if (new_size > s->capacity) { s->capacity = s->capacity << 1; s->data = realloc(s->data, s->capacity); }
s->data[s->size] = element;
s->size = new_size;
}
void add_charp(String* s, char* string) {
size_t stringlen = strlen(string);
size_t new_size = s->size + stringlen;
if (new_size > s->capacity) { s->capacity = new_size << 1; s->data = realloc(s->data, s->capacity); }
strcpy(s->data + s->size, string);
s->size = new_size;
}
void add_string(String* s, String* string) {
size_t stringlen = string->size;
size_t new_size = s->size + stringlen;
if (new_size > s->capacity) { s->capacity = new_size << 1; s->data = realloc(s->data, s->capacity); }
strcpy(s->data + s->size, string->data);
s->size = new_size;
}
이제는 문제가되지 않습니다. 이러한 문자열 목록을 만들려고 할 때 문제가 발생합니다. 나는 또한 이것을하기위한 구조를 만들었다.
typedef struct dynamic_string_pointer {
String* data;
size_t capacity;
size_t size;
} StringVec;
void free_stringvec(StringVec* sv) { free(sv->data); sv->data = NULL; }
void print_stringvec(StringVec* sv) { for (int i = 0; i < sv->size; ++i) { print_string(&sv->data[i]); } }
int stringvec_init(StringVec* sv, size_t init_capacity) {
sv->data = malloc(init_capacity * sizeof(String));
if (!sv->data) { return -1; }
sv->size = 0; sv->capacity = init_capacity;
return 0;
}
void add_string_to_vec(StringVec* sv, String string) {
size_t new_size = sv->size + 1;
if (new_size > sv->capacity) { sv->capacity = sv->capacity << 1; sv->data = realloc(sv->data, sv->capacity * sizeof(String)); }
sv->data[sv->size] = string;
sv->size = new_size;
}
이 구조체에는 문제가없는 것 같으며 다른 문자열을 추가하면 올바르게 작동합니다. 문제는 내가 문자열을 만들고 동일한 변수를 사용하여 목록에 추가 할 때입니다. 예를 들어
: 나는 변수 토큰을 사용하여 토큰에 추가하여 토큰의 목록을 구축을 위해 노력하고
void tokenize(char* text) {
StringVec tokens; stringvec_init(&tokens, 32);
String token; string_init(&token, 8);
bool first_char = false;
for (int i = 0; i < strlen(text); ++i) {
if (isToken(text[i])) {
if (!equals_charp(&token, "")) { add_string_to_vec(&tokens, token); }
clear_string(&token); add_char(&token, text[i]);
add_string_to_vec(&tokens, token);
clear_string(&token); first_char = false; continue;
}
if (text[i] != ' ' && text[i] != '\t' && text[i] != '\n'){ add_char(&token, text[i]); first_char = true; }
else if (first_char) { add_char(&token, text[i]); }
}
print_stringvec(&tokens);
free_string(&token);
free_stringvec(&tokens);
}
여기. 문제는 토큰이 add_string_to_vec에 전달 될 때 항상 스택에 동일한 주소를 갖고있는 것으로 보입니다. 이것은 토큰을 인쇄 할 때 단지 마지막 토큰을 반복해서 인쇄하기 때문에 옳은 것처럼 보입니다. 그래서 나는이> 데이터를 SV-하는 문자열에서 메모리를 복사 할 것이라고 생각
sv->data[sv->size] = string; with memcpy(sv->data + sv->size, &string, sizeof(String));
교체 시도 있도록 일하는 것이 추가 할 때 다른 토큰. 이것은 같은 문제가있는 것 같습니다. 나는 보통 C++에서 std :: vector와 std :: string을 사용하여 쉽게 작업 할 수있다. 나는 어리석은가 아니면 어쩌면 기억이 어떻게 잘 작동 하는지를 이해할 수도 있지만, 이것이 작동하도록하는 방법을 찾아 내지 못했습니다.
'SV-> = 데이터의 malloc (init_capacity의 *를는 sizeof (문자열)) (! equals_charp (토큰 ""))'이상한 ... 또한''경우 매우 * * 이상한 ... – wildplasser
BTW 'add_charp()'에서'new_size == s-> capacity'이라면'strcpy()'는 최종 '\ 0'을 소유하지 않은 메모리에 씁니다. –
'string_init'을 한 번만 호출하십시오. 그러면 하나의 버퍼가 할당되고,이 버퍼는'token' 문자열의 모든 복사본간에 공유됩니다. 'String'을 복사 할 때마다 새로운 버퍼를 할당하고 오래된'data' 문자를 복사해야합니다. (그러면 '자유'라고 부를 때 알아내는 데 어려움이 많을 것입니다.) –