【问题标题】:Remove characters from a string in C从C中的字符串中删除字符
【发布时间】:2010-12-02 18:21:37
【问题描述】:

我只能访问“C”并且需要替换字符数组中的字符。对于这个相对简单的过程,我还没有提出任何干净的解决方案。

我传入一个字符数组,例如:

char strBuffer[] = "/html/scorm12/course/course_index.jsp?user_id=100000232&course_id=100000879&course_prefix=ACQ&version=2&scorm_version=3&roster_id=100011365&course_name=Test%20Course%201.2&mode=browse&course_number=0000&mode_id=1";

我需要修改此缓冲区以将所有& 替换为&。生成的缓冲区不必覆盖 strBuffer(可以创建新缓冲区)。

有什么建议吗?

编辑:

过去我在循环中完成了 strstr 函数,但一直在寻找更简单的解决方案,也许 C 中等效于 String.Replace 方法。

编辑:

对于我的迫切需要,以下是我所需要的。

char strBuffer[] = "/html/scorm12/course/course_index.jsp?user_id=100000232&course_id=100000879&course_prefix=ACQ&version=2&scorm_version=3&roster_id=100011365&course_name=Test%20Course%201.2&mode=browse&course_number=0000&mode_id=1";
char strTemp[1024];
char *s = (char*)strBuffer;
int i=0;

while (*s)
{
    strTemp[i++] = *s;
    if (strncmp(s,"&",5) == 0)
    {
        s += 5;
    }
    else
        s++;
}
strTemp[i] = 0;

未来的修改:

  • 创建一个实用函数来存储此函数。
  • 将搜索字符串作为参数传递。
  • 确定搜索字符串的长度,以便可以删除硬编码的 5。
  • 动态分配 strTemp 变量。
  • 检查空字符串和未找到字符时出错。

编辑:

我创建了一篇博文来详细说明这些步骤并提供更灵活的解决方案:

http://www.solutionmaniacs.com/blog/2012/11/25/c-removereplace-characters-in-a-string.html

【问题讨论】:

  • 这是作业吗? (如果有也没关系,如果合适的话标记为[homework]。)
  • 高级语言中的任何String.Replace 方法实际上都会在C 级别的循环中归结为strstr()。 C 与“抽象”和“易用性”等崇高理想无关。
  • 感谢所有帮助我解决此问题的人。我在 C# 中被宠坏了,忘记了如何在 C 中进行一些相对简单的字符串操作。

标签: c arrays replace char


【解决方案1】:

C 并不以易用性着称,尤其是在字符串方面,但它有一些相当不错的标准库函数可以完成工作。如果您需要大量处理字符串,您可能需要了解指针和指针运算,但除此之外,这里有一些库函数无疑会对您有所帮助:

  • strchr() 在字符串中查找一个字符(例如,'&')。
  • strcmp()strncmp() 比较两个字符串。
  • strstr() 在字符串中查找子字符串(可能比使用strchr()/strcmp() 组合更容易和更快)。
  • malloc() 分配一个新字符串。

【讨论】:

  • 谢谢...有很多标准的 C 函数非常方便!
  • 别忘了使用 mem* 函数!
【解决方案2】:

基本上,您需要:

  • 使用strstr() 函数查找“&”
  • 将字符复制到结果缓冲区直到找到的位置
  • 跳过 4 个字符
  • 重复直到 NUL

【讨论】:

  • 您可以使用strstr(),但您也可以使用strchr() 来查找“&”,然后查看接下来的几个字符是否为“&”:char *amp = strchr(string, '&'); if(amp && !strncmp(amp, "&") { /* we found it! */ } 虽然这可能只是一个strstr() 的优化程度较低的版本(我很生气,我忘记了)。
  • 使用 strstr() 更加通用和方便。它也可能更快,具体取决于 strstr() 的实现方式。我推荐他的方法。如果速度真的很重要,那么更复杂的算法如 KMP 是首选;但我猜 Edward Leno 只是需要一些方便的东西。
  • @Chris 在这种情况下,您实际上只是在条件块内手动执行 strstr() 工作。我认为使用标准函数来减少潜在错误会更明智。
  • 其实我更喜欢 "if(amp && !strncmp(amp+1, "amp;") { /* we found it! */ }" 和 memcpy 可以更好地用于实际的压缩而不是索引迭代。
【解决方案3】:

在堆栈或堆上分配另一个缓冲区,然后一次将字符串复制到新缓冲区中 1 个字符。遇到& 字符时进行特殊处理。

【讨论】:

  • 这是一个数组字面量,可以更改,因为它存储在一个数组中。 char *c = "string"; 不可能。但是,是的,您不应该更改它以防止将来犯这种错误。
  • 实际上,在发布的示例中(除非在您回答后对其进行了编辑) strBuffer 是一个可写的缓冲区,并且通过将文字字符串复制到缓冲区中来进行初始化。
  • 对不起,它是一个数组字面量:sizeof(strBuffer) == 249
  • 我会说肯定会在堆上分配新缓冲区。这种功能绝对应该被抽象成一个单独的函数,所以你需要使用堆来传递东西(或者要求调用者传入他/她自己的缓冲区)。
  • 我更喜欢传入你自己的缓冲区而不是辅助函数的方式。
【解决方案4】:
char *s = (char*)strBuffer;
char sClean[strlen(strBuffer) + 1]; /* +1 for null-byte */
/* if above does not work in your compiler, use:
    char *sClean = (char*)malloc(sizeof(strBuffer) + 1);
*/
int i=0;
while (*s)
{
    sClean[i++]= *s;
    if ((*s == '&') && (!strncmp(s, "&", 5)) s += 5;
    else s++;
}
sClean[i] = 0;

【讨论】:

  • 可变长度数组(如上面的 char sClean[strlen(strBuffer)];)仅适用于 C99,大量编译器并不完全支持。
  • 注明。如果 Q 的编译器做不到,Q 可以使用 malloc。
  • 另请注意,您的代码不会检查"&" - 它会覆盖'&' 字符后面的任何五个字符。
  • 另一个问题是sClean的大小是strlen(strBuffer)。如果没有什么可替换的,则上面的代码有内存冲突。
猜你喜欢
  • 2022-01-09
  • 2011-12-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-01-13
相关资源
最近更新 更多