将字符串中的字符与数据库中的另一个字符转换

问题描述 投票:0回答:1

我正在用 C 语言制作一个字符转换器。

逻辑上非常简单:您键入一个字符,程序会检测到该字符并将其替换为新字符串中与其关联的其他字符。

在项目过程中,我现在遇到了两个问题:

void ReadString()
{
    scanf("%s", inpString);
    
    for(int i = 0; i <= strlen(inpString);  i++)
    {
        ConvertChars(inpString);
    }
    
    PrintString();
}
    
void ConvertChars(char *convertedChars[])
{
    if(strpbrk(convertedChars, "ཀ"))
    {
        strcpy(outString, "!");
    }
    
    if(strpbrk(convertedChars, "ཁ"))
    {
        strcpy(outString, "\"");
    }
    
}
  1. 每当我输入

    "ཀ"
    "ཁ"
    时,输出始终相同(
    "
    代表
    "ཁ"
    )。

  2. 由于某种原因,

    for
    循环似乎不起作用,因为它从不输出两个或多个转换后的字符,只输出一个(尽管在
    inpString
    中输入了两个或多个字符)。

什么可能导致这些问题?

arrays c char
1个回答
0
投票

这个问题没有指定

的编码,因此计算机的含义是开放式的。但是,它可能是 UTF-8,用
U+0F40
表示 unicode 代码点
e0 bd 80
,用
U+0F41
表示
e0 bd 81
。即使您修复了逻辑错误,
strpbrk
也会逐字节拆分,因此不适合多字节序列。

如果您需要从 UTF-8 转换某些字符,一种方法是使用状态机。

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

int main(void) {
    unsigned char buf[1024], out[sizeof buf];
    size_t n;
    enum { UTF_ONE_BYTE, UTF_TWO_BYTES, UTF_THREE_BYTES } state = UTF_ONE_BYTE;
    do {
        n = fread(buf, 1, sizeof buf, stdin);
        size_t o = 0;
        for(size_t i = 0; i < n; i++) {
            const unsigned char cursor = buf[i];
            switch(state) {
            case UTF_ONE_BYTE:
                switch(cursor) {
                case 0xe0: state = UTF_TWO_BYTES; break; /* May be translated? */
                default: out[o++] = cursor; break;
                }
                break;
            case UTF_TWO_BYTES:
                switch(cursor) {
                case 0xbd: state = UTF_THREE_BYTES; break;
                default: /* Nope, catch up. */
                    out[o++] = 0xe0; out[o++] = cursor; state = UTF_ONE_BYTE; break;
                }
                break;
            case UTF_THREE_BYTES:
                switch(cursor) {
                case 0x80: out[o++] = '!'; break;
                case 0x81: out[o++] = '\"'; break;
                default: /* Not a translated character. */
                    out[o++] = 0xe0; out[o++] = 0xbd; out[o++] = cursor; break;
                }
                state = UTF_ONE_BYTE; break;
            }
        }
        fwrite(out, 1, o, stdout);
    } while(n == sizeof buf);
    return ferror(stdin) ? (perror("stdin"), EXIT_FAILURE) : EXIT_SUCCESS;
}
© www.soinside.com 2019 - 2024. All rights reserved.