c - 在 C 中用等效的 HTML 实体替换字符/符号

标签 c string

我正在尝试在c中创建一个函数,它接受一个字符串作为输入并返回相同的字符串,但将“&”、“>”、“<”替换为“&”、“&” LT;”和“>” (不包括空格)。

我正在努力理解如何才能做到这一点。

我尝试通过循环运行字符串,然后使用 strcmp 将字符串中的每个字符与符号进行比较。如果字符相同,则尝试将字符替换为对应的实体。

一些代码来展示我一直在尝试的内容:

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

char *replace_character(char *str) {
  for(size_t i = 0; i <= strlen(str); i++) {
    if(strcmp(str[i], '&') {
      str[i] = "&amp;";
    }
    ... (same procedure for the rest of the characters)
  }
  return str;
}


int main() {
 char with_symbol[] = "this & that";

 printf(replace_character(with_symbol));
}

预期结果:“This & that”

最佳答案

C 中字符串的概念是一个低级概念:字符数组。正如您无法获取一个整数数组并直接将其中一个整数替换为整个其他数组一样,您也无法直接将一个字符串中的一个字符替换为另一个字符串。您必须首先为要塞入原始字符串的额外字符分配必要的内存。

下面我提供了一个可以做到这一点的代码。它不是最有效的,但可以让您了解它应该如何工作。它效率低下,因为它首先遍历整个字符串,计算要替换的特殊符号并计算出需要多少额外空间,然后在复制字符时再次遍历它。

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

char *replace(const char *s)
{
    size_t i, j;
    size_t len, extra;
    char *r = NULL;

    len = strlen(s);
    extra = 0;

    /* First we count how much extra space we need */
    for (i = 0; i < len; ++i) {
        if (s[i] == '&')
            extra += strlen("&amp;") - 1;
        else if (s[i] == '<')
            extra += strlen("&lt;") - 1;
        else if (s[i] == '>')
            extra += strlen("&gt;") - 1;
    }

    /* Allocate a new string with the extra space */
    r = malloc(len + extra + 1);
    assert(r != NULL);

    /* Put in the extra characters */
    j = 0;
    for (i = 0; i < len; ++i) {
        if (s[i] == '&') {
            r[j++] = '&';
            r[j++] = 'a';
            r[j++] = 'm';
            r[j++] = 'p';
            r[j++] = ';';
        } else if (s[i] == '<') {
            r[j++] = '&';
            r[j++] = 'l';
            r[j++] = 't';
            r[j++] = ';';
        } else if (s[i] == '>') {
            r[j++] = '&';
            r[j++] = 'g';
            r[j++] = 't';
            r[j++] = ';';
        } else {
            r[j++] = s[i];
        }
    }

    /* Mark the end of the new string */
    r[j] = '\0';

    /* Just to make sure nothing fishy happened */
    assert(strlen(r) == len + extra);

    return r;
}

int main(void)
{
    const char *sorig = "this &, this >, and this < are special characters";
    char *snew;

    snew = replace(sorig);

    printf("original  :  %s\n", sorig);
    printf("     new  :  %s\n", snew);

    free(snew);

    return 0;
}

更好的策略是定义一个查找表或映射,以便您只需更改表即可包含或排除新的符号对及其替换项。您还可以使用 strncpy 来实现此目的,避免逐字符处理。上面的示例只是为了说明幕后发生的事情。

关于c - 在 C 中用等效的 HTML 实体替换字符/符号,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57905107/

相关文章:

c# - 分割字符串时索引超出范围异常

python - 带字符串输出的递归计数

c - 在 C 编程中使用字符串和子字符串的基础知识

c - 通过空结构指针取消引用变量地址,无段错误

c++ - size_t 和 ptrdiff_t 类型的变量

c - 为什么 inode 编号从 1 而不是 0 开始?

c - 过滤一个缓冲区并将其复制到另一个 C

c - 指针运算

c - 终端中的 printf c 问题

c# - 如何在 C# 或 VB.NET 中格式化变量?