将字符串插入C中的另一个字符串 [英] Inserting strings into another string in C
问题描述
我正在实现一个函数,给定一个字符串,一个字符和另一个字符串(因为现在我们可以将其称为子字符串");将子字符串放在字符在字符串中的任何位置. 为了更好地解释我,给定这些参数,这就是函数应该返回的内容(伪代码):
I'm implementing a function which, given a string, a character and another string (since now we can call it the "substring"); puts the substring everywhere the character is in the string. To explain me better, given these parameters this is what the function should return (pseudocode):
func ("aeiou", 'i', "hello") -> aehelloou
我正在使用string.h
lib中的一些函数.我已经对其进行了很好的测试:
I'm using some functions from string.h
lib. I have tested it with pretty good result:
char *somestring= "this$ is a tes$t wawawa$wa";
printf("%s", strcinsert(somestring, '$', "WHAT?!") );
Outputs: thisWHAT?! is a tesWHAT?!t wawawaWHAT?!wa
所以现在一切都很好.问题是,当我尝试使用以下字符串进行此操作时:
so for now everything is allright. The problem is when I try to do the same with, for example this string:
char *somestring= "this \"is a test\" wawawawa";
printf("%s", strcinsert(somestring, '"', "\\\"") );
因为我想将每个"
更改为\"
.当我这样做时,PC崩溃了.我不知道为什么,但是它停止工作,然后关闭.我已经了解了string.h
lib某些功能的不良行为,但是我找不到有关此信息,我真的很感谢任何帮助.
since I want to change every "
for a \"
. When I do this, the PC collapses. I don't know why but it stops working and then shutdown. I've head some about the bad behavior of some functions of the string.h
lib but I couldn't find any information about this, I really thank any help.
我的代码:
#define salloc(size) (str)malloc(size+1) //i'm lazy
typedef char* str;
str strcinsert (str string, char flag, str substring)
{
int nflag= 0; //this is the number of times the character appears
for (int i= 0; i<strlen(string); i++)
if (string[i]==flag)
nflag++;
str new=string;
int pos;
while (strchr(string, flag)) //since when its not found returns NULL
{
new= salloc(strlen(string)+nflag*strlen(substring)-nflag);
pos= strlen(string)-strlen(strchr(string, flag));
strncpy(new, string, pos);
strcat(new, substring);
strcat(new, string+pos+1);
string= new;
}
return new;
}
感谢您的帮助!
推荐答案
一些建议:
- 不要使用
typedef char* str;
.char *
类型在C语言中很常见,并且将其屏蔽会导致您的代码更难审核 - 出于完全相同的原因,请避免使用
#define salloc(size) (str)malloc(size+1)
.另外,请勿在C语言中投射malloc
- 每次编写
malloc
(或calloc
或realloc
)时,都应该有一个相应的free
:C没有垃圾回收 - 动态分配非常昂贵,请仅在需要时使用它.换句话说,循环内的
malloc
应该查看两次(特别是如果没有相应的free
的话) - 始终测试分配函数(无关:和io),当耗尽内存时,malloc将仅返回NULL.这样,一条不错的错误消息比崩溃更容易理解
- 学习使用调试器:如果您是在调试器下执行代码的,则错误很明显
- refrain from
typedef char* str;
. Thechar *
type is common in C and masking it will just make your code harder to be reviewed - refrain from
#define salloc(size) (str)malloc(size+1)
for the exact same reason. In addition don't castmalloc
in C - each time you write a
malloc
(orcalloc
orrealloc
) there should be a correspondingfree
: C has no garbage collection - dynamic allocation is expensive, use it only when needed. Said differently a
malloc
inside a loop should be looked at twice (especially if there is no correspondingfree
) - always test allocation function (unrelated: and io) a malloc will simply return NULL when you exhaust memory. A nice error message is then easier to understand than a crash
- learn to use a debugger: if you had executed your code under a debugger the error would have been evident
接下来的原因:如果替换字符串包含原始字符串,那么您将再次落在其上并无休止地循环运行
Next the cause: if the replacement string contains the original one, you fall again on it and run in an endless loop
一种可能的解决方法:在循环之前 分配结果字符串,并在原始循环和结果中进行排序.这样可以避免不必要的分配和取消分配,并避免替换字符串中存在原始字符.
A possible workaround: allocate the result string before the loop and advance both in the original one and the result. It will save you from unnecessary allocations and de-allocations, and will be immune to the original char being present in the replacement string.
可能的代码:
// the result is an allocated string that must be freed by caller
str strcinsert(str string, char flag, str substring)
{
int nflag = 0; //this is the number of times the character appears
for (int i = 0; i<strlen(string); i++)
if (string[i] == flag)
nflag++;
str new_ = string;
int pos;
new_ = salloc(strlen(string) + nflag*strlen(substring) - nflag);
// should test new_ != NULL
char * cur = new_;
char *old = string;
while (NULL != (string = strchr(string, flag))) //since when its not found returns NULL
{
pos = string - old;
strncpy(cur, old, pos);
cur[pos] = '\0'; // strncpy does not null terminate the dest. string
strcat(cur, substring);
strcat(cur, string + 1);
cur += strlen(substring) + pos; // advance the result
old = ++string; // and the input string
}
return new_;
}
注意:我没有还原str
和salloc
,但您确实应该这样做.
Note: I have not reverted the str
and salloc
but you really should do.
这篇关于将字符串插入C中的另一个字符串的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!