C中的字符串追加函数
string Append function in C
我想创建一个字符串附加函数,但是当我想打印该函数时它崩溃了。我调试了它,但我找不到可能是什么问题。
struct string {
size_t length;
size_t allocated;
char* data;
};
string* Init(char* str) {
string* s = malloc(sizeof(string));
size_t strLen = strlen(str);
s->data = (char*)malloc(strLen*2); //allocate 2x of the length
memcpy(s->data,str,strLen);
s->data[strLen] = '[=10=]';
s->length = strLen;
s->allocated = 2*strLen;
return s;
}
void AppendBack(string* str, string* new) {
if(str->allocated < str->length + new->length) { //allocate more
char* data = (char*)realloc(strGet(str),str->allocated*2);
str->allocated = str->allocated*2;
str->data = data;
if(str->allocated < str->length + new->length) { //need more allocation
AppendBack(str,new);
}
}
str->length = str->length + new->length;
for(int i = new->length; i >= 0; --i) {
str->data[str->length - i] = new->data[new->length - i];
}
str->data[str->length] = '[=10=]';
}
int main() {
string* a = Init("abc");
string* b = Init("1234fedfsdffghjkjhgfds3ghjk7345678juhzbfsdfsd");
AppendBack(a,b);
strPrint(a);
return 0;
}
编辑代码:
char* strGet(string* str) {
return str->data;
}
void strPrint(string* str) {
printf("%s",strGet(str));
}
很抱歉,我遗漏了部分代码。
您有两个错误:
您需要为终止零分配一个额外的字节。
您需要在递归调用 AppendBack
后 return,否则您会损坏字符串。
这是工作代码:
void AppendBack(string* str, string* new) {
if(str->allocated < (str->length + new->length + 1)) { // NOTE: +1
char* data = (char*)realloc(str->data,str->allocated*2); // removed call to strGet
str->allocated = str->allocated*2;
str->data = data;
if(str->allocated < (str->length + new->length + 1)) { // NOTE: +1
AppendBack(str,new);
return; // NOTE: return here
}
}
str->length = str->length + new->length;
for(int i = new->length; i >= 0; --i) {
str->data[str->length - i] = new->data[new->length - i];
}
str->data[str->length] = '[=10=]'; // See? You need an extra byte for this
}
我删除了对 strGet
的调用,因为您没有向我们展示该代码。
我认为您没有很好地处理空终止符的分配。您的 length
字段不计算空终止符,因此您的 allocated
字段也不应该,否则您的计算有时可能会关闭。但是您的 malloc()
调用需要考虑空终止符。
此外,您在执行递归后并未退出 AppendBack()
。我建议完全摆脱递归,而是在迭代循环中计算所需的分配大小。
试试像这样的东西:
typedef struct string {
size_t length;
size_t capacity;
char* data;
} string;
string* Init(char* str) {
string* s = (string*) malloc(sizeof(string));
if (!s) return NULL;
size_t strLen = strlen(str);
s->length = strLen;
s->capacity = strLen*2;
s->data = (char*) malloc(s->capacity+1); //allocate 2x of the length, plus a null terminator
if (!s->data) {
free(s);
return NULL;
}
memcpy(s->data, str, strLen);
s->data[strLen] = '[=10=]';
return s;
}
void Cleanup(string* str) {
if (str) free(str->data);
free(str);
}
void AppendBack(string* str, string* str2) {
size_t newLen = str->length + str2->length;
if (str->capacity < newLen) { //allocate more
size_t cap = str->capacity;
do {
cap *= 2;
} while (cap <= newLen);
char* data = (char*) realloc(str->data, cap+1);
if (!data) return;
str->data = data;
str->capacity = cap;
}
memcpy(&str->data[str->length], str2->data, str2->length);
str->data[newLen] = '[=10=]';
str->length = newLen;
}
void strPrint(string *str) {
printf("%s", str->data);
}
int main() {
string* a = Init("abc");
string* b = Init("1234fedfsdffghjkjhgfds3ghjk7345678juhzbfsdfsd");
AppendBack(a,b);
strPrint(a);
Cleanup(b);
Cleanup(a);
return 0;
}
我想创建一个字符串附加函数,但是当我想打印该函数时它崩溃了。我调试了它,但我找不到可能是什么问题。
struct string {
size_t length;
size_t allocated;
char* data;
};
string* Init(char* str) {
string* s = malloc(sizeof(string));
size_t strLen = strlen(str);
s->data = (char*)malloc(strLen*2); //allocate 2x of the length
memcpy(s->data,str,strLen);
s->data[strLen] = '[=10=]';
s->length = strLen;
s->allocated = 2*strLen;
return s;
}
void AppendBack(string* str, string* new) {
if(str->allocated < str->length + new->length) { //allocate more
char* data = (char*)realloc(strGet(str),str->allocated*2);
str->allocated = str->allocated*2;
str->data = data;
if(str->allocated < str->length + new->length) { //need more allocation
AppendBack(str,new);
}
}
str->length = str->length + new->length;
for(int i = new->length; i >= 0; --i) {
str->data[str->length - i] = new->data[new->length - i];
}
str->data[str->length] = '[=10=]';
}
int main() {
string* a = Init("abc");
string* b = Init("1234fedfsdffghjkjhgfds3ghjk7345678juhzbfsdfsd");
AppendBack(a,b);
strPrint(a);
return 0;
}
编辑代码:
char* strGet(string* str) {
return str->data;
}
void strPrint(string* str) {
printf("%s",strGet(str));
}
很抱歉,我遗漏了部分代码。
您有两个错误:
您需要为终止零分配一个额外的字节。
您需要在递归调用
AppendBack
后 return,否则您会损坏字符串。
这是工作代码:
void AppendBack(string* str, string* new) {
if(str->allocated < (str->length + new->length + 1)) { // NOTE: +1
char* data = (char*)realloc(str->data,str->allocated*2); // removed call to strGet
str->allocated = str->allocated*2;
str->data = data;
if(str->allocated < (str->length + new->length + 1)) { // NOTE: +1
AppendBack(str,new);
return; // NOTE: return here
}
}
str->length = str->length + new->length;
for(int i = new->length; i >= 0; --i) {
str->data[str->length - i] = new->data[new->length - i];
}
str->data[str->length] = '[=10=]'; // See? You need an extra byte for this
}
我删除了对 strGet
的调用,因为您没有向我们展示该代码。
我认为您没有很好地处理空终止符的分配。您的 length
字段不计算空终止符,因此您的 allocated
字段也不应该,否则您的计算有时可能会关闭。但是您的 malloc()
调用需要考虑空终止符。
此外,您在执行递归后并未退出 AppendBack()
。我建议完全摆脱递归,而是在迭代循环中计算所需的分配大小。
试试像这样的东西:
typedef struct string {
size_t length;
size_t capacity;
char* data;
} string;
string* Init(char* str) {
string* s = (string*) malloc(sizeof(string));
if (!s) return NULL;
size_t strLen = strlen(str);
s->length = strLen;
s->capacity = strLen*2;
s->data = (char*) malloc(s->capacity+1); //allocate 2x of the length, plus a null terminator
if (!s->data) {
free(s);
return NULL;
}
memcpy(s->data, str, strLen);
s->data[strLen] = '[=10=]';
return s;
}
void Cleanup(string* str) {
if (str) free(str->data);
free(str);
}
void AppendBack(string* str, string* str2) {
size_t newLen = str->length + str2->length;
if (str->capacity < newLen) { //allocate more
size_t cap = str->capacity;
do {
cap *= 2;
} while (cap <= newLen);
char* data = (char*) realloc(str->data, cap+1);
if (!data) return;
str->data = data;
str->capacity = cap;
}
memcpy(&str->data[str->length], str2->data, str2->length);
str->data[newLen] = '[=10=]';
str->length = newLen;
}
void strPrint(string *str) {
printf("%s", str->data);
}
int main() {
string* a = Init("abc");
string* b = Init("1234fedfsdffghjkjhgfds3ghjk7345678juhzbfsdfsd");
AppendBack(a,b);
strPrint(a);
Cleanup(b);
Cleanup(a);
return 0;
}