【问题标题】:How to insert a copy of a string into another string?如何将一个字符串的副本插入另一个字符串?
【发布时间】:2013-11-24 05:51:04
【问题描述】:

所以,函数如下:

int strinsert(char *dst, int len, const char *src, int offset)

我需要将我的src 字符串的副本从offset 的位置插入到名为dst 的字符串中。 参数len 指定为数组dst 保留的字符数。

代码的重要部分:

int strinsert(char *dst, int len, const char *src, int offset)
{
    strncpy(dst, src+offset, len);
    char buf[100];
    strcpy(buf+len, src);
    len += strlen(src) ;
    strcpy(buf+len, dst+offset); 
    strcpy(dst, buf);
    
    return 1;
}

还是感觉有点不对劲……

编辑:在有人误解之前,我只是在自学如何用 C 编程,我找到了这个练习。顺便说一句,我真的没有找到一些好的一维和二维数组的学习材料,谁能这么好心并发布一些?

【问题讨论】:

  • 这是函数的原型,不是函数定义
  • 您的问题是什么?你有没有尝试过?
  • @VusP:这是我的编辑结果 - 已修复
  • 我们是否应该从中推断出这个问题,因为我推断它说“你会这样做,所以我不必这样做吗?”展示你做了什么,它给了你什么,以及你为什么认为它可能会这样做。
  • 我不是必须这样做,我只是在自学“如何 C”

标签: c arrays string replace


【解决方案1】:

这能解决问题吗?

int strinsert(char *dst, int len, const char *src, int offset) 
{
    char temp [MAX_SIZE];

    strncpy(temp, dest+offset, strlen(dest+offset));
    strncpy(dest+offset, src, strlen(src));
    strcat (dest+offset+strlen(src), temp);
    
    return 0;
    
}

显然,上面的代码没有任何错误检查,并且可以对temp进行malloced等。

【讨论】:

  • 会覆盖dest,OP要在中间插入
  • 这不像 OP 想要的那样做 任何事情。 OP 希望将目标指定索引处的内容右移以为插入的源腾出空间。这会从源内的偏移量对目标进行爆炸。即,它不保留任何内容,并复制错误的数据。
  • 如果您将某些内容复制到缓冲区中,显然它将覆盖缓冲区中的内容。他的意思是说,覆盖源?在这种情况下,memmove() 是最好的。
  • 他的意思是我写的。为要复制到目标的特定起始索引的源字符串腾出空间,将当前目标内容进一步向下移动,从而丢失 no 数据。 dst="ABCDE"src="123"offset=2。插入后的结果是"AB123CDE"len 参数的目的是防止您在结束 dst 之后覆盖,尽管没有指定这种情况下的行为。
  • @whozcraid 和 mvp:在您的 cmets 之后编辑了我的答案。我没有正确理解这个问题。现在它看起来像一个解决方案吗?
【解决方案2】:

你可以使用strncpy(),这是string.h库的一个函数。它将source字符串的第一个num字符复制到destination字符串。

char * strncpy ( char * 目标, const char * 源, size_t num );

但在您的情况下,您需要第三个字符串,因为您无法扩展目标数组。您可以将目标数组的子字符串(从开头到偏移量)复制到第三个数组中,然后将其余部分连接起来。所以你需要做这样的事情:

char *dst = "ThisIsMyHomework";
char *src = "Not";
char finalString[50];
int offset = 6; //Assume we want to insert "Not" string between "ThisIs" and "MyHomework". So we want src array to start from 6th index of dst array.

strncpy(finalString, dst, offset); //finalString="ThisIs"
finalString[offset] = '\0'; //For finalString, you have to add "\0" manually because strcat will append other strings from 50. index of array if you don't
strcat(finalString, src); //finalString="ThisIsNot"
strcat(finalString, dst + offset); //finalString="ThisIsNotMyHomework"

【讨论】:

    【解决方案3】:

    这有点痛苦,但你真的必须构造一个新字符串,因为你不能这么容易地真正洗牌,而且我认为没有库函数可以做到这一点(有吗??) .是这样的:

    int strinsert(char *dst, int len, const char *src, int offset)
    {
        char *new_string = new char[len];
        int remaining = len;
    
        // Check offset is not to long (+1 for null)
        if (offset >= remaining)
            offset = remaining;
    
        // copy the pre-string from dest
        strncpy(new_string, dest, offset);
        // Calulate the remaining space
        remaining -= offset;
    
        // Add the insert string (with max chars remaining)
        strncat(new_string, src, remaining);
        // calc remaining space
        remaining -= strlen(src);
    
        // Add the post-string from dest (with max chars remaining)
        strncat(new_string, dest, remaining);
    
        // Finally copy the new_string into dest
        strncpy(dest, new_string, len);
    
        // free the memory
        delete [] new_string;
    }
    

    注意:您可能需要更好地计算剩余空间,以防它变为负数...

    编辑:用内存分配替换可变长度数组(非法...哎呀)

    【讨论】:

    • True...事实上,如果您小心的话,您可以使用 *dst 位置来构建字符串 :),为了清楚起见,我认为构建一个新字符串会更容易...我需要为其分配一些空间,或者使用我不想这样做的硬编码char somthing[MAX_NUM]
    • 您无需小心 :) 只需使用 memmove 即可正确处理重叠区域。查看我的版本... ;)
    【解决方案4】:
    void strinsert(char *dst, size_t len, const char *src, size_t offset) 
    {
      size_t iLenDst = strlen(dst),
             iLenSrc = strlen(src);
    
      // Some error handling
      if (iLenDst+iLenSrc+1>len)  
      {
        ASSERT(FALSE):
        return;
      }
    
      // restrict to max length
      if (offset>iLenDst)
        offset = iLenDst;
    
      // Make room incl. trailing \0
      memmove(dst+offset+iLenSrc,dst+offset,iLenDst-offset+1);
      // Insert new
      memcopy(dst+offset,src,iLenSrc);
    }
    

    【讨论】:

      猜你喜欢
      • 2012-09-25
      • 2015-02-11
      • 2012-08-14
      • 2011-05-13
      • 2016-02-07
      • 1970-01-01
      • 2013-03-04
      • 1970-01-01
      相关资源
      最近更新 更多