- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我开始学习 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 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);
}
在这里,我尝试通过使用变量标记并将其添加到标记来构建标记列表。问题似乎是,当 token 传递给 add_string_to_vec 时,它在堆栈上始终具有相同的地址。这似乎是正确的,因为当我打印 token 时,它只是一遍又一遍地打印最后一个 token 。所以我尝试更换
sv->data[sv->size] = 字符串;与 memcpy(sv->data + sv->size, &string, sizeof(String));
认为这会将内存从字符串复制到 sv->data ,以便在添加其他标记时它可以工作。这似乎也有同样的问题。我通常使用 C++,它具有 std::vector 和 std::string 这使得这很容易。我可能只是愚蠢,或者也许我只是理解内存是如何运作的,但我一直无法找到一种方法来让它发挥作用。
最佳答案
我按照 Bo Persson 所说的做了,并制作了这些函数。现在它工作得很好。 (我稍微改变了 tokenize 函数的工作方式。)
String next_token(char* text, size_t size, int* start) {
String token; string_init(&token, 4);
char last_char = ' ';
for (int i = *start; i < size; ++i) {
if (last_char == ' ' && text[i] == ' ') { continue; }
if (text[i] == '\t' || text[i] == '\n') { if (last_char != ' ') { add_char(&token, ' '); } continue;}
if (isToken(text[i])) {
*start = i;
if (token.size == 0) { *start += 1; add_char(&token, text[i]); }
return token;
}
add_char(&token, text[i]);
last_char = text[i];
}
return token;
}
StringVec tokenize(char* text) {
StringVec tokens; stringvec_init(&tokens, 32);
size_t textlen = strlen(text);
for (int i = 0; i < textlen;) {
String token = next_token(text, textlen, &i);
add_string_to_vec(&tokens, token);
}
return tokens;
}
我在这里免费 token 。
void free_stringvec(StringVec* sv) {
for (int i = 0; i < sv->size; ++i) {
free_string(&sv->data[i]);
}
free(sv->data); sv->data = NULL;
}
关于在 c 中创建字符串列表不起作用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47502539/
今天有小伙伴给我留言问到,try{...}catch(){...}是什么意思?它用来干什么? 简单的说 他们是用来捕获异常的 下面我们通过一个例子来详细讲解下
我正在努力提高网站的可访问性,但我不知道如何在页脚中标记社交媒体链接列表。这些链接指向我在 facecook、twitter 等上的帐户。我不想用 role="navigation" 标记这些链接,因
说现在是 6 点,我有一个 Timer 并在 10 点安排了一个 TimerTask。之后,System DateTime 被其他服务(例如 ntp)调整为 9 点钟。我仍然希望我的 TimerTas
就目前而言,这个问题不适合我们的问答形式。我们希望答案得到事实、引用资料或专业知识的支持,但这个问题可能会引发辩论、争论、投票或扩展讨论。如果您觉得这个问题可以改进并可能重新打开,visit the
我就废话不多说了,大家还是直接看代码吧~ ? 1
Maven系列1 1.什么是Maven? Maven是一个项目管理工具,它包含了一个对象模型。一组标准集合,一个依赖管理系统。和用来运行定义在生命周期阶段中插件目标和逻辑。 核心功能 Mav
我是一名优秀的程序员,十分优秀!