将字符串插入C中的另一个字符串 [英] Inserting strings into another string in C

查看:262
本文介绍了将字符串插入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(或callocrealloc)时,都应该有一个相应的free:C没有垃圾回收
  • 动态分配非常昂贵,请仅在需要时使用它.换句话说,循环内的malloc应该查看两次(特别是如果没有相应的free的话)
  • 始终测试分配函数(无关:和io),当耗尽内存时,malloc将仅返回NULL.这样,一条不错的错误消息比崩溃更容易理解
  • 学习使用调试器:如果您是在调试器下执行代码的,则错误很明显
  • refrain from typedef char* str;. The char * 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 cast malloc in C
  • each time you write a malloc (or calloc or realloc) there should be a corresponding free: 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 corresponding free)
  • 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_;
}

注意:我没有还原strsalloc,但您确实应该这样做.

Note: I have not reverted the str and salloc but you really should do.

这篇关于将字符串插入C中的另一个字符串的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆