- c -" 如何使程序从文件中读取可见字符和空格

79 3

我想"修复"别人给我的代码,使它在文件中显示正确数量的可见字符(空格也需要)。正确的数字应该是977 ,我以前从未处理过文件,我也不明白需要做什么才能显示正确的数字。


 {


 if (isprint(ch) != 'n' || 't' || '') {


 count++; 


 }


 else if (isspace(ch) == NULL){


 count++;


 }


 putc(ch,stdout); // same as putchar(ch);


 count++;


 }


 fclose(fp);


 printf("nFile %s has %lu charactersn", file, count);



我期望使用isprint和isspace组合得到正确的可见字符数,但是,我通常会得到2086.

时间: 原作者:

81 0

isprint() :

可打印字符是占据显示器上打印位置的字符(这与控制字符相反,使用iscntrl检查)。

如果确实c是可打印字符,则值不等于零(即,true)。否则为零(即false)。

这个函数应该足够了,请注意,你必须确保从<ctype.h>未签名值中提供所有这些is...()函数,因此,如果你使用的值不确定,那么最好将它转换为char unsigned 。


#include <stdlib.h>


#include <stdio.h>


#include <ctype.h>



int main(void)


{


 char const *filename = "test.txt";


 FILE *input = fopen(filename, "r");


 if (!input) {


 fprintf(stderr, "Couldn't open "%s" for reading. :(nn", filename);


 return EXIT_FAILURE;


 }



 long long unsigned count = 0; 


 for (int ch; (ch = fgetc(input)) != EOF;) {


 if (isprint(ch))


 ++count;


 }



 fclose(input);


 printf("Count: %llunn", count);


}



如果我没有幸运地猜到你想要计算哪些字符,看一下ctype.h,有一张表。

原作者:
121 4

isprint()返回一个布尔结果 - 如果字符不是"可打印",就为零,如果不是,就为非零。因为这种isprint(ch)!='n'没有意义,你在问题中的完整表达甚至没有意义,但是,我最后会谈到这一点。

isprint()自己返回true (non-zero )用于所有可打印字符,所以,你不需要其他测试,而且你无条件地在每个条件块中count ,所以,你要计算每个字符和一些两次。

你只需要:


if( isprint(ch) )


{ 


 count++; 


}


putc( ch, stdout ) ;



虽然你的代码显然是一个不完整的片段,但是,不清楚你在哪里或如何读取ch。你需要在某处中使用getc()或等价。


while( (ch = getc(fp)) != EOF ) 


{


 if( isprint(ch) )


 { 


 count++; 


 }


 putc( ch, stdout ) ;


}



不清楚你是否需要计算所有的空白(包括空格,制表符和换行符)或者是你所说的"空格",如果清楚,isprint()将匹配空格,但是,不控制字符换行或制表符,isspace()匹配所有这些,但是,不应该分别计算为isprint(),因为"空格"和可打印的集合都是,


while( (ch = getc(fp)) != EOF ) 


{


 if( isprint(ch) || isspace(ch) )


 { 


 count++; 


 }



 putc( ch, stdout ) ;


}



你似乎误解的C的另一个方面, 就是布尔表达式是如何工作的。要为多个值测试单个变量,必须编写:


if( var == x || var == y || var == z )



你写成了 :


if( var == x || y || z )



当你大声读出英语时,这可能会对英语有意义,但是,在C中,它意味着:


if( var == (x || y || z ) )



评估(x || y || z ) 作为truefalse,并将它与var进行比较。

可能值得考虑现有解决方案的语义,以显示它实际编译的原因,但是,会产生错误的结果。

首先


 isprint(ch) != 'n' || 't' || '' 



由于前面描述的原因,等效于isprint(ch)!= true ,所以,你增加了所有不可打印字符的计数器。

那这里:


 isspace(ch) == NULL



NULL是表示无效指针的宏,而且isspace()不返回指针,然而NULL将隐式转换为零(或false ),因此,在这里增加所有可打印字符的计数器,而不是空格。

最后,你无条件地计算每个字符:


 putc(ch,stdout); // same as putchar(ch);


 count++;



所以你的结果是:


number-of-non-printing-characters + 


number-of-printing-characters - number-of-spaces +


total-number-of-characters



我觉得 (2 x file-length) - number-of-spaces

最后请注意,如果在"binary "模式下打开具有CR LF行结尾的文本文件(Windows上的文本文件的常规文件),则isspace()将为每个换行计算两个字符。确保打开"文本"模式(不用考虑平台)。

原作者:
137 3

if ((ch == 't') || isprint(ch))


 count++;



如果要以不同的方式处理tab,(也许来计算他们用了多少空格):


if (ch == 't') {


 /* Do smth */


} else if (isprint(ch)) {


 count++;


}



应该足够了。

原作者:
119 2

尝试这个:


if (ch!= 'n' && ch != 't' && ch!= '')



替代:


if (isprint(ch) != 'n' || 't' || '')



原作者:
...