有没有办法看到ctype.h中的类型中有哪些字符?

时间:2016-08-03 21:16:57

标签: c header-files

我正在编写一个C程序,该程序涉及浏览.txt文件并查找文件中的所有可打印字符(或可能是图形字符)。我知道头文件ctype.h定义了几个字符类(例如数字,小写字母,大写字母等),并提供了检查给定字符是否属于每个类的函数,但我不确定是否可以做反向(即检查所有类中的字符)。我需要列出或定义每种类型中所有字符的东西,理想情况下是数组或枚举类型。

4 个答案:

答案 0 :(得分:4)

Dunno如果这有用,但我写了一个程序来根据给定文件中找到的字符对字符进行分类。修复它以无条件地遍历0..255范围内的字符(字节)并不难。

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

static void classifier(FILE *fp, char *fn)
{
    int c;
    int map[UCHAR_MAX + 1];
    size_t i;

    printf("%s:\n", fn);
    for (i = 0; i < UCHAR_MAX + 1; i++)
        map[i] = 0;

    printf("Code Char Space Upper Lower Alpha AlNum Digit XDig  Graph Punct Print Cntrl\n");

    while ((c = getc(fp)) != EOF)
    {
        map[c] = 1;
    }

    for (c = 0; c < UCHAR_MAX + 1; c++)
    {
        if (map[c] == 1)
        {
            int sp = isspace(c)  ? 'X' : ' ';
            int up = isupper(c)  ? 'X' : ' ';
            int lo = islower(c)  ? 'X' : ' ';
            int al = isalpha(c)  ? 'X' : ' ';
            int an = isalnum(c)  ? 'X' : ' ';
            int dg = isdigit(c)  ? 'X' : ' ';
            int xd = isxdigit(c) ? 'X' : ' ';
            int gr = isgraph(c)  ? 'X' : ' ';
            int pu = ispunct(c)  ? 'X' : ' ';
            int pr = isprint(c)  ? 'X' : ' ';
            int ct = iscntrl(c)  ? 'X' : ' ';
            int ch = (pr == 'X') ?  c  : ' ';
            printf("0x%02X %-4c %-6c%-6c%-6c%-6c%-6c%-6c%-6c%-6c%-6c%-6c%-6c\n",
                    c, ch, sp, up, lo, al, an, dg, xd, gr, pu, pr, ct);
        }
    }
}

我的代码提取的额外技巧是使用setlocale()在当前语言环境而不是C语言环境中工作:

#include <locale.h>

int main(int argc, char **argv)
{
    setlocale(LC_ALL, "");
    filter(argc, argv, 1, classifier);
    return(0);
}

filter()函数处理来自argv[1]的参数(通常是optind而不是1,但此代码中没有条件参数处理)argv[argc-1] 1}},读取文件(如果没有命名文件,则读取标准输入)。它为它打开的每个文件调用classifier() - 并处理打开,关闭等等。

答案 1 :(得分:2)

ctype.h中没有可以帮助您的固定字符列表。实际上isprint()取决于区域设置。

假设你说的是char而不是宽字符,解决问题的一种方法是初始化一个包含256个元素的表,每个元素代表一个字符:

char mychars[256];  
memset(mychars, 0, 256);  

然后打开你的文件并阅读所有的字符,并标记出现的字符:

...
int c; 
while ( (c=fgetc(fp)) != EOF) {
    mychars[c] |= 1;  
}

然后您可以遍历可打印的那些:

for (int i=0; i<256; i++) {
    if (isprint(i) && !mychars[i]) 
         printf ("%c not found\n", (char)i);
}

答案 2 :(得分:0)

我的建议:

  1. 创建一个包含256个元素的unsigned long数组,这些元素可以在文件中出现char的次数。

  2. 逐个字符地读取文件内容并更新数组中的数据。

  3. 处理完文件的所有字符后,浏览数组的元素并打印必要的信息。

  4. int main()
    {
       unsigned long charOccurrences[256] = {0};
    
       // open the file.
       FILE* fin = fopen(....);
    
       int c;
       while ( (c = fgetc(fin)) != EOF )
       {
          // Increment the number of occurrences.
          charOccurrences[c]++;
       }
    
       // Process the data.
       for (int i = 0; i < 256; ++i )
       {
          if ( isprint(i) && charOccurrences[i] == 0 )
          {
             printf("%c was not found in the file.\n", i);
          }
       }
    
       // Close the file
       fclose(fin);
    }
    

答案 3 :(得分:0)

您可以遍历unsigned char类型的所有值,从0UCHAR_MAX,并检查<ctype.h>中的每个函数,以确定类是什么。

例如,您可以列出所有数字:

printf("digits: ");
for (int c = 0; c <= UCHAR_MAX; c++) {
    if (isdigit(c))
        putchar(c);
}
printf("\n");