我正在编写一个C程序,该程序涉及浏览.txt文件并查找文件中不的所有可打印字符(或可能是图形字符)。我知道头文件ctype.h定义了几个字符类(例如数字,小写字母,大写字母等),并提供了检查给定字符是否属于每个类的函数,但我不确定是否可以做反向(即检查所有类中的字符)。我需要列出或定义每种类型中所有字符的东西,理想情况下是数组或枚举类型。
答案 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)
我的建议:
创建一个包含256个元素的unsigned long
数组,这些元素可以在文件中出现char
的次数。
逐个字符地读取文件内容并更新数组中的数据。
处理完文件的所有字符后,浏览数组的元素并打印必要的信息。
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
类型的所有值,从0
到UCHAR_MAX
,并检查<ctype.h>
中的每个函数,以确定类是什么。
例如,您可以列出所有数字:
printf("digits: ");
for (int c = 0; c <= UCHAR_MAX; c++) {
if (isdigit(c))
putchar(c);
}
printf("\n");