c - 使用 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
正确打印。如果我移动strCleare
到Structure *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
我也必须使用strClear
。res
将包含约 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);
}
}
这段代码将执行得很好。
解决方案
更正版本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
将成员更改a
为string*
:
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;
}
推荐阅读
- php - 将带有查询字符串的 URL 重定向到 NGINX 中的漂亮 URL
- python - 如何从 Celery 任务中的不同队列中提取
- python - 列表的 Python 问题(TypeError:'NoneType' 对象不可迭代)
- reactjs - 使用formaMessage时反应国际返回错误
- python - 在 Python 中解析嵌套的 XML?
- css - 具有三个背景图像以同一位置为中心的 Flexbox?
- reactjs - React Modal 使页面崩溃
- node.js - 用于博客的 nodejs 和 mongodb 中的 REST API
- powershell - 使用 PowerShell 写入 .js 文件
- list - Haskell wrap 函数实现