从字符串中删除子字符串 - C 编程

Remove a sub-string from a string - C programming

我正在尝试删除特定字符串中的所有 '\x00' 十六进制值。

例如:如果字符串是 "Hello\x00World\x00\x00",我得到 "Hello" 作为输出,但我需要输出 "HelloWorld".

谁能帮我解决这个问题?

char *strip(char *str, const char *sub) {
    size_t lenth = strlen(sub);
    if (lenth > 0) {
        char *p = str;
        while ((p = strstr(p, sub)) != NULL) {
            memmove(p, p + lenth, strlen(p + lenth) + 1); // returns a pointer to the destination
        }
    }
    return str;
}

请将所有“\x00”转换为“\\x00”。在主字符串和子字符串中。字符 '\' 充当转义字符。因此,如果你想把它当作一个字符,你必须在它前面添加一个额外的字符,每次使用

#include "stdio.h"
#include "stdlib.h"
#include "string.h"


char *strip(char *str, const char *sub) {
    size_t lenth = strlen(sub);
    if (lenth > 0) {
        char *p = str;
        while ((p = strstr(p, sub)) != NULL) {
            memmove(p, p + lenth, strlen(p + lenth) + 1); // returns a pointer to the destination
        }
    }
    return str;
}



int main()
{       
        char str[] = "Hello\x00World\x00\x00";
        char sub[] = "\x00";
        printf("Start program\n str: %s\n sub: %s\n ", str, sub);
        printf("Result: %s\n", strip(str, sub));
        return 0;
}

不使用标准 C 字符串函数的直接方法如下面的演示程序所示,前提是字符串包含应删除的嵌入终止零字符“\0”,并且两个连续的终止零表示字符串的结尾。

#include <stdio.h>

char * strip( char *s )
{
    char *p = s;
    const char *q = s;
    
    do
    {
        if ( !*q ) ++q;
        
        if ( p != q ) *p = *q;  

        ++p;
    } while ( *q++ );
    
    return s;
}

int main(void) 
{
    char s[] = 
    { 
        'H', 'e', 'l', 'l', 'o', '\x00', 'W', 'o', 'r', 'l', 'd', '\x00', '\x00'
    };
    
    puts( strip( s ) );
    
    return 0;
}

程序输出为

HelloWorld

字符数组的等效初始化也可以看起来像

char s[] = "Hello\x00World\x00";

或者如果像这样声明源字符数组

char s[] = 
{ 
    '0', '\x00', '1', '\x00', '2', '\x00', '3', '\x00', '4', '\x00', 
    '5', '\x00', '6', '\x00', '7', '\x00', '8', '\x00', '9', '\x00', '\x00'
};

那么程序输出将是

0123456789

一个C字符串最后只有一个空终止符。在包含多个字符串和内部任意数量的空终止符的缓冲区上工作的算法将需要知道结尾在哪里,因为在这种情况下,它不能再依赖空终止符来标记结尾。不清楚您是否打算连续使用 2 个空终止符来标记结束,或者您是否根本没有考虑这个问题。

修复它的最简单方法是传递缓冲区大小。其他替代方法是使用一些特殊符号来标记结束。如果是这样,您可以这样编写函数:

char *strip(char *str, const char *sub, size_t size) 
{
  char* result = str;
  size_t length;

  for(size_t i=0; i<size; i+=length)
  {
    if(sub[i] == '[=10=]')
    {
      length=1;
    }
    else
    {
      length = strlen(&sub[i]);
      memcpy(str, &sub[i], length);
      str += length;
    }
  }
  *str = '[=10=]';
  return result;
}

if(sub[i] == '[=12=]') 也将丢弃连续的多个空终止符。示例:

#include <string.h>
#include <stdio.h>

char *strip(char *str, const char *sub, size_t size) 
{
  char* result = str;
  size_t length;
  for(size_t i=0; i<size; i+=length)
  {
    if(sub[i] == '[=11=]')
    {
      length=1;
    }
    else
    {
      length = strlen(&sub[i]);
      memcpy(str, &sub[i], length);
      str += length;
    }
  }
  *str = '[=11=]';
  return result;
}

int main (void)
{ 
  char old_str[] = "Hello[=11=][=11=][=11=]World[=11=]How[=11=][=11=]Are[=11=]You?";
  char new_str[100];
 
  puts(strip(new_str, old_str, sizeof old_str));
}

输出:HelloWorldHowAreYou?