You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C语言检查字符是否存在于字符串中的最优方法是什么?

原代码问题定位
  • 多余的错误转换逻辑:char charC = c + '0'; 这行完全没有存在必要,将读取到的字符ASCII码加上'0'的ASCII值(通常为48)会直接改变原字符数值,导致后续换行判断完全失效。
  • 换行判断逻辑错误:使用strncmp(&charC, "\n", 1)判断换行属于冗余且错误的写法,charC已经被加了'0',不可能等于'\n'的ASCII值,所有换行都会被识别为非法字符,直接判断原读取到的c == '\n'即可实现换行合法校验。
  • 可移植性隐患:strchr要求传入的字符参数需要是unsigned char类型提升的int值,如果读取到的字符是负数(比如char为有符号类型的场景下读入了扩展ASCII字符),会导致未定义行为。
修复后的基础实现
#include <stdio.h>
#include <string.h>
#include <stdbool.h>

bool check_bad_characters(FILE *inputFile)
{
    int c;
    // 合法字符直接包含换行符,减少后续判断分支
    const char valid_characters[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ \n";
    while ((c = fgetc(inputFile)) != EOF) {   
        if (strchr(valid_characters, (unsigned char)c) == NULL)
        {
            // 存在非法字符
            return false;
        }    
    }
    return true;
}
更高效的优化实现

如果文件体积较大,频繁调用strchr遍历合法字符数组会产生额外开销,可以用静态查找表实现O(1)复杂度的字符校验:

#include <stdio.h>
#include <stdbool.h>
#include <limits.h>

bool check_bad_characters(FILE *inputFile)
{
    int c;
    // 初始化查找表,所有字符默认标记为非法
    static bool valid_table[UCHAR_MAX + 1] = {false};
    // 仅第一次调用时初始化查找表
    if (!valid_table['A']) {
        for (char ch = 'A'; ch <= 'Z'; ch++) {
            valid_table[(unsigned char)ch] = true;
        }
        valid_table[(unsigned char)' '] = true;
        valid_table[(unsigned char)'\n'] = true;
    }

    while ((c = fgetc(inputFile)) != EOF) {   
        if (!valid_table[(unsigned char)c])
        {
            return false;
        }    
    }
    return true;
}

内容的提问来源于stack exchange,提问作者Jorge Jones

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.25 10:54:03