首页 > 解决方案 > 使用 C 动态清除字符串

问题描述

Structure {
   char* a;
   char* b;
   char* c;
   Tpye t; //Enum
}
void print() {
   list* res = CreateList(sizeof(Structure))
   string* buffer = CreateEmptyString();
   for(size_t i = 0; i < 3; ++i) {
        strPushBack(buffer,'1');
        if(i==1) strPushBack(buffer,'2');
        else if(i==2) strPushBack(buffer,'3');
        Structure temp = (Structure){buffer->data,"0","0",num};
        printf("%s\n",buffer->data); //print correctly
        listPushBack(res,&temp);
        Structure *j = listAt(res,i);
        printf("%s\n",j->a); //print correctly
        strClear(buffer);
   }
   for(size_t i = 0; i < 3; ++i) {
       Structure *k = listAt(res,i);
       printf("%s\n",k->a); //just print an empty string
       printf("%s\n",k->b); //print correctly
       printf("%s\n",k->c); //print correctly
       printf("....\n");
   }
}
int main() {
   print();
   return 0;
}

list是一个通用链表void*

listAt返回void*

k->a未正确打印的第二个 for 循环中,只需打印一个空字符串,k->b然后k->c正确打印。如果我移动strCleareStructure *j...第二个 print 将不会很好地执行,只需打印一个空字符串。我认为该strClear功能无法正常工作,因为我清除了它。

string* CreateEmptyString() {
    string* s = malloc(sizeof(string));
    s->length = 0;
    s->allocated = 2;
    s->data = (char*)malloc(s->allocated+1);
    s->data[0] = '\0';
    return s;
}
void strClear(string* str) {
    str->data[0] = '\0';
    str->length = 0;
}
void strPushBack(string* str, char c) {
    if(str->allocated < str->length + 2) { // +1 c, +1 \0
        char* data = (char*)realloc(strGet(str),str->allocated*2);
        str->allocated = str->allocated*2;
        str->data = data;
    }
    str->length = str->length + 1;
    str->data[str->length-1] = c;
    str->data[str->length] = '\0';
}

我想正确打印所有内容,我也想使用strClear函数。

我知道这段代码没有任何意义,这是我的代码的混合部分,无法正常工作。

在我的真实项目中,我想返回返回,res我也必须使用strClearres将包含约 20Structure

编辑:

如果我使用不使用string*,我只会使用char*一切正常,因此我认为strClear无法正常工作。

列表:列表我不认为这里有问题。

另一件事是:

如果我不使用Structure

void print() 
    list* res = CreateList(sizeof(char*));
    string* buffer = CreateEmptyString();
    for(size_t i = 0; i < 3; ++i) {
        strPushBack(buffer,'1');
        if(i==1) strPushBack(buffer,'2');
        else if(i==2) strPushBack(buffer,'3');
        listPushBack(res,buffer->data);
        printf("%s\n",buffer->data);
        strClear(buffer);
    }
    printf("\n");
    for(size_t i = 0; i < 3; ++i) {
        char* t = listAt(res,i);
        printf("%s\n",t);
    }
}

这段代码将执行得很好。

标签: cstring

解决方案


更正版本listAt

void* listAt(list* list, size_t index) {
    node* ptr = list->head;
    size_t i = 0;
    while(ptr != NULL) {
        if(i == index)
            return ptr->data;
        ++i;
        ptr = ptr->next; // this line was missing!
    }
}

Structure将成员更改astring*

typedef struct {
    string *a;
    char *b;
    char *c;
    Tpye t;
} Structure;

然后更改为每个元素print分配一个新string*的,但不要调用strClear(buffer);,因为它会清空字符串内容:

void print(void) {
    list* res = CreateList(sizeof(Structure));
    for(size_t i = 0; i < 3; ++i) {
        string* buffer = CreateEmptyString();
        strPushBack(buffer,'1');
        if(i==1) strPushBack(buffer,'2');
        else if(i==2) strPushBack(buffer,'3');
        Structure temp = (Structure){buffer,"0","0",num};
        //printf("%s\n",buffer->data); //print correctly
        listPushBack(res,&temp);
        //Structure *j = listAt(res,i);
        //printf("%s\n",j->a->data); //print correctly
    }
    for(size_t i = 0; i < 3; ++i) {
        Structure *k = listAt(res,i);
        printf("%s\n",k->a->data);
        printf("%s\n",k->b); //print correctly
        printf("%s\n",k->c); //print correctly
        printf("....\n");
    }
}

调用时会产生以下输出:

1
0
0
....
12
0
0
....
13
0
0
....

我用于上述演示的完整资源:

列表.h

#ifndef LIST_H__INCLUDED
#define LIST_H__INCLUDED

#include <stddef.h>


struct list;

typedef struct list list;

list* CreateList(size_t typeSize);
void* listAt(list* list, size_t index);
void listPushBack(list *list, void *val);

#endif

列表.c

#include <stddef.h>
#include <inttypes.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "list.h"

struct node {
    void *data;
    struct node *next;
    struct node *prev;
};

struct list {
    struct node *head;
    struct node *tail;
    size_t elementSize;
    size_t length;
};

typedef struct node node;

static node *nodeCreate(void *data, size_t typeSize) {
    node *newNode = malloc(sizeof(node));
    newNode->data = malloc(typeSize);
    memcpy(newNode->data, data, typeSize);
    newNode->prev = newNode->next = NULL;
    return newNode;
}

list* CreateList(size_t typeSize) {
    list *list = malloc(sizeof(*list));
    list->head = list->tail = NULL;
    list->elementSize = typeSize;
    list->length = 0;
    return list;
}

void* listAt(list* list, size_t index) {
    node* ptr = list->head;
    size_t i = 0;
    while(ptr != NULL) {
        if(i == index)
            return ptr->data;
        ++i;
        ptr = ptr->next;
    }
}

void listPushBack(list *list, void *val) {
    node *newNode = nodeCreate(val, list->elementSize);
    list->length++;
    if (list->head == NULL) {
        list->head = newNode;
        list->tail = newNode;
    }
    else {
        list->tail->next = newNode;
        newNode->prev = list->tail;
        list->tail = newNode;
    }
}

字符串.h

#ifndef STRING_H__INCLUDED
#define STRING_H__INCLUDED

#include <stddef.h>

typedef struct {
    char *data;
    size_t allocated;
    size_t length;
} string;

string* CreateEmptyString(void);
void strClear(string* str);
void strPushBack(string* str, char c);

#endif

字符串.c

#include <stdlib.h>
#include "string.h"

string* CreateEmptyString(void) {
    string* s = malloc(sizeof(string));
    s->length = 0;
    s->allocated = 2;
    s->data = (char*)malloc(s->allocated+1);
    s->data[0] = '\0';
    return s;
}

void strClear(string* str) {
    str->data[0] = '\0';
    str->length = 0;
}

static char *strGet(string* str)
{
        return str->data;
}

void strPushBack(string* str, char c) {
    if(str->allocated < str->length + 2) { // +1 c, +1 \0
        char* data = (char*)realloc(strGet(str),str->allocated*2);
        str->allocated = str->allocated*2;
        str->data = data;
    }
    str->length = str->length + 1;
    str->data[str->length-1] = c;
    str->data[str->length] = '\0';
}

主程序

#include <stdio.h>
#include "list.h"
#include "string.h"

typedef enum {
    num
} Tpye;

typedef struct {
    string *a;
    char *b;
    char *c;
    Tpye t;
} Structure;

void print(void) {
    list* res = CreateList(sizeof(Structure));
    for(size_t i = 0; i < 3; ++i) {
        string* buffer = CreateEmptyString();
        strPushBack(buffer,'1');
        if(i==1) strPushBack(buffer,'2');
        else if(i==2) strPushBack(buffer,'3');
        Structure temp = (Structure){buffer,"0","0",num};
        //printf("%s\n",buffer->data); //print correctly
        listPushBack(res,&temp);
        //Structure *j = listAt(res,i);
        //printf("%s\n",j->a->data); //print correctly
    }
    for(size_t i = 0; i < 3; ++i) {
        Structure *k = listAt(res,i);
        printf("%s\n",k->a->data);
        printf("%s\n",k->b); //print correctly
        printf("%s\n",k->c); //print correctly
        printf("....\n");
    }
}

int main() {
   print();
   return 0;
}

推荐阅读