Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/string/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在c中创建字符串列表不起作用?_C_String_Memory - Fatal编程技术网

在c中创建字符串列表不起作用?

在c中创建字符串列表不起作用?,c,string,memory,C,String,Memory,我开始学习c编程,我试图将一个字符串拆分成一系列子字符串。我创建了一个名为String的用于创建字符串的结构 #include <stdio.h> #include <stdlib.h> #include <string.h> #include <stdbool.h> typedef struct dynamic_string { char* data; size_t capacity; size_t size; } St

我开始学习c编程,我试图将一个字符串拆分成一系列子字符串。我创建了一个名为String的用于创建字符串的结构

#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结构动态_字符串{
字符*数据;
容量大小;
大小;
}弦;
void free_string(string*s){free(s->data);s->data=NULL;}
无效打印字符串(string*s){for(inti=0;isize;++i){printf(“%c”,s->data[i])}printf(“\n”)}
无效清除字符串(字符串*s){s->size=0;s->data[0]='\0';}
int字符串初始化(字符串*s,大小初始化容量){
s->data=malloc(初始容量);
如果(!s->data){return-1;};
s->size=0;s->capacity=init_capacity;
返回0;
}
void add_char(字符串*s,char元素){
大小\u t新大小=s->size+1;
如果(新大小>容量){s->capacity=s->capacity data=realloc(s->data,s->capacity);}
s->数据[s->大小]=元素;
s->size=新尺寸;
}
void add_charp(字符串*s,字符*String){
尺寸\u t stringlen=strlen(字符串);
尺寸\u t新尺寸=s->尺寸+细线;
如果(新大小>容量){s->capacity=new大小数据=realloc(s->data,s->capacity);}
strcpy(s->data+s->size,string);
s->size=新尺寸;
}
void add_字符串(string*s,string*string){
大小\u t字符串长度=字符串->大小;
尺寸\u t新尺寸=s->尺寸+细线;
如果(新大小>容量){s->capacity=new大小数据=realloc(s->data,s->capacity);}
strcpy(s->data+s->size,string->data);
s->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;
}
typedef结构动态字符串指针{
字符串*数据;
容量大小;
大小;
}StringVec;
void free_stringvec(stringvec*sv){free(sv->data);sv->data=NULL;}
void print_stringvec(stringvec*sv){for(inti=0;isize;++i){print_string(&sv->data[i]);}
int stringvec_init(stringvec*sv,大小_t init_容量){
sv->data=malloc(初始容量*sizeof(字符串));
如果(!sv->data){return-1;}
sv->size=0;sv->capacity=init_capacity;
返回0;
}
void将字符串添加到向量(StringVec*sv,字符串){
大小\u t新大小=sv->大小+1;
如果(新建大小>sv->容量){sv->capacity=sv->capacity data=realloc(sv->data,sv->capacity*sizeof(String));}
sv->数据[sv->大小]=字符串;
sv->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);
}
void标记化(char*text){
StringVec令牌;StringVec_init(&tokens,32);
字符串标记;字符串初始化(&token,8);
bool first_char=false;
对于(int i=0;i
在这里,我试图通过使用变量token并将其添加到tokens来构建令牌列表。问题似乎在于,当传递令牌将_string_添加到_vec时,它在堆栈上始终具有相同的地址。这似乎是对的,因为当我打印代币时,它只是一遍又一遍地打印最后一个代币。所以我试着换了

sv->data[sv->size]=字符串;使用memcpy(sv->data+sv->size,&string,sizeof(string))


认为这会将内存从string复制到sv->data,以便在添加其他令牌时可以工作。这似乎也有同样的问题。我通常使用C++,它有STD::vector和STD::string,这使得这很容易。我可能很愚蠢,或者我只是理解内存是如何工作的,但是我还没有找到一种方法来让它工作。

我按照Bo Persson说的做了,并实现了这些功能。现在它工作得非常好。(我稍微改变了tokenize函数的工作方式。)

String next\u标记(char*text,size\t size,int*start){
字符串标记;字符串初始化(&token,4);
char last_char='';
对于(int i=*start;i
我这里有免费代币

void free_stringvec(StringVec* sv) { 
    for (int i = 0; i < sv->size; ++i) {
        free_string(&sv->data[i]); 
    } 
    free(sv->data); sv->data = NULL; 
}
void free_stringvec(stringvec*sv){
对于(int i=0;isize;++i){
自由字符串(&sv->data[i]);
} 
自由(sv->data);sv->data=NULL;
}

sv->data=malloc(初始容量*sizeof(字符串))奇怪。。。另外
if(!equals_charp(&token,”)
非常奇怪…顺便说一句,在
add_charp()
中,如果
new_size==s->capacity
strcpy()
将最后的
\0
写入无主内存。您只调用
string\u init
一次。分配一个缓冲区,然后在所有拷贝之间共享
void free_stringvec(StringVec* sv) { 
    for (int i = 0; i < sv->size; ++i) {
        free_string(&sv->data[i]); 
    } 
    free(sv->data); sv->data = NULL; 
}