gpt4 book ai didi

c - 如何在 C 中的 strtok 标记之间存储子字符串?

转载 作者:行者123 更新时间:2023-11-30 16:57:18 26 4
gpt4 key购买 nike

基本上,我使用 strtok() 去除多余的后续空格,然后使用 strcat() 将字符串连接回去,这样就只有一个空格根据需要在字符串中。例如:“你好呀。”字符串有 3 个空格。我的程序将成功 strtok() 字符串,然后将其放回一起,可以这么说,只有一个空格。但是,当字符串看起来像这样时:“你好,你怎么样?”我的程序将输出:“你好”,丢弃标记之间的所有内容。

这是我的代码片段:

void stringFunction(struct dh *header){
int i;
char *spaceTk, *spaceString, *holder;
struct dh *temp;

temp = header->next;
while(temp != NULL){
spaceString = malloc(strlen(temp->string) + 1);
strcpy(spaceString, temp->string);

for(i = 0; i < strlen(spaceString) + 1; i++){
if(spaceString[i] == ' '){
count++; //don't worry about this variable
if(spaceString[i] == ' ' && spaceString[i + 1] == ' '){
spaceTk = strtok(spaceString, " ");
while(spaceTk != NULL){
holder = malloc(strlen(spaceTk) + 1);
strcpy(holder, spaceTk);
spaceTk = strtok(NULL, " ");
}
strcat(spaceString, " ");
strcat(spaceString, holder);
strcpy(temp->string, spaceString);
}
}
}
}
}

......

我知道变量“holder”存储 token ,但被最后一个 token 覆盖。我只是不确定如何保存第一个和最后一个标记之间的单词。

谢谢。

最佳答案

您对strtok()的使用非常奇怪。通常会让it遍历源字符串来查找分隔符,但您似乎是手动执行此操作,然后才调用strtok()

此外,如果你有 strdup() 那么它比 strlen() + malloc() + 方便得多strcpy(),具有相同的结果(包括在不再需要时释放已分配存储空间的相同义务)。如果您没有 strdup(),并且需要动态分配字符串副本,那么您应该考虑编写它。

此外,使用 strcat() 在重叠的对象之间进行复制(正如您所做的那样)会产生未定义的行为。不惜一切代价避免这种情况。由于您已经创建了原始字符串的工作副本,因此避免在重叠对象之间进行复制的一种方法是将这些片段连接到原始字符串中,而不是将它们连接到工作空间中,然后将其复制回原始字符串字符串。

无论如何,您都需要在收到 token 时以某种方式对其进行处理。您当前的代码忽略第一个和最后一个之间的所有标记(也一直泄漏内存)。以下是您的代码的一个变体,效果会更好:

struct dh *temp;

temp = header->next;
while(temp != NULL){
char *spaceString = strdup(temp->string);
// ... need a NULL check on spaceString here, in case allocation failed
char *first_token = strtok(spaceString, " ");
char *next_token = strtok(NULL, " ");

if (next_token) { // else the original string is OK as-is
strcpy(temp->string, first_token);
do {
strcat(temp->string, " ");
strcat(temp->string, next_token);
next_token = strtok(NULL, " ");
} while (next_token);
}

// It is obligatory to free the working string now that we're done with it
free(spaceString);
}

但这仍然相当低效(尽管比你的更好),因为 strcat() 调用都必须通过从头开始扫描来找到字符串的结尾,更不用说因为动态内存分配(这也是一个潜在的故障点)和函数调用开销。编写不存在任何这些问题的就地空白压缩代码并不太难。这可能看起来像这样:

char *start_at = strstr(header->next, "  ");

if (start_at) { // else nothing to do
char *lag = start_at + 1; // after the first space
char *lead = lag + 1; // after the second space
int space_count = 2;

do {
if (*lead != ' ') {
// not part of a run of spaces
space_count = 0;
} else if (space_count++) {
// the second or subsequent space in a run of spaces
continue;
}

*lag++ = *lead;
} while (*lead++);
}

关于c - 如何在 C 中的 strtok 标记之间存储子字符串?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39597497/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com