#include <stdio.h>
#include <stdlib.h>
int main()
{
FILE *fp1, *fp2; /*定义两个指向FILE类型结构体的指针变量*/
char filename1[100],filename2[100],ch; /*定义数组变量为字符型*/
long character,word,sentence,paragraph; /*定义变量为长整型*/
character=word=sentence=paragraph=0; /*长整型变量的初值均为0*/
printf("Enter file name \n");
scanf("%s", filename1); /*输入要进行统计的文件的路径及名称*/
if((fp1=fopen(filename1, "r"))==NULL) /*以只读方式打开指定文件*/
{
printf("cannot open file.\n");
exit(1);
}
printf ( "Enter file name for write data:\n");
scanf("%s",filename2); /*输入文件名即将统计结果放到那个文件中*/
if((fp2=fopen(filename2, "w"))==NULL) /*已可写方式要存放统计结果的文件*/
{
printf("cannot open file \n");
exit(1);
}
while((ch=fgetc(fp1))!=EOF) /*知道文件内容结束处停止while循环*/
{
if(ch>='A' && ch<'Z'||ch>='a' && ch<='z')
{
character++;
} /*当遇到字母时字符个数+1*/
else if(ch==' ')
{
character++;
word++;
} /*当遇到空格时字符数+1*/
else if(ch>='0' && ch<='9')
{
character++;
} /*当遇到数字时数字个数+1*/
else if(ch=='.'||ch=='!'||ch=='?')
{
sentence++;
character++;
} /*当遇到.!?时句子数+1,字符数+1*/
else if ((ch=='\r')||(ch=='\n'))
{ paragraph++;
} /*当遇到换行符时段落数+1*/
else
{
character++;
word++;
} /*遇到其他字符时字符个数+1*/
ch++;
}
fclose(fp1); /*关闭fp1指向的文件*/
fprintf(fp2,"character:%ld word:%ld sentence:%ld paragraph:%ld\n", character, word, sentence,paragraph);/*将统计结果写入fp指向的磁盘文件中*/
fclose(fp2);
}
20 个解决方案
#1
不要使用
while (条件)
更不要使用
while (组合条件)
要使用
while (1) {
if (条件1) break;
//...
if (条件2) continue;
//...
if (条件3) return;
//...
}
因为前两种写法在语言表达意思的层面上有二义性,只有第三种才忠实反映了程序流的实际情况。
典型如:
下面两段的语义都是当文件未结束时读字符
while (!feof(f)) {
a=fgetc(f);
//...
b=fgetc(f);//可能此时已经feof了!
//...
}
而这样写就没有问题:
while (1) {
a=fgetc(f);
if (feof(f)) break;
//...
b=fgetc(f);
if (feof(f)) break;
//...
}
类似的例子还可以举很多。
#2
不要使用
while (条件)
更不要使用
while (组合条件)
要使用
while (1) {
if (条件1) break;
//...
if (条件2) continue;
//...
if (条件3) return;
//...
}
因为前两种写法在语言表达意思的层面上有二义性,只有第三种才忠实反映了程序流的实际情况。
典型如:
下面两段的语义都是当文件未结束时读字符
while (!feof(f)) {
a=fgetc(f);
//...
b=fgetc(f);//可能此时已经feof了!
//...
}
而这样写就没有问题:
while (1) {
a=fgetc(f);
if (feof(f)) break;
//...
b=fgetc(f);
if (feof(f)) break;
//...
}
类似的例子还可以举很多。
那请问基于我的程序怎么改呢
#3
char ch;
应改为
int ch;
应改为
int ch;
#4
将while语句中的条件判断挪到while循环的第一句或中间某句或最后一句视具体情况而定。
#5
定义为char的目的就是为了读取文件中的字符,如果改为int类型是否也能实现同样的功能呢?
#6
char ch;//会导致无法区分到底是读到了0xFF字符还是到了文件末尾。
#7
仅供参考:
#include <stdio.h>
#include <string.h>
#define MAXLEN 1000
char ln[MAXLEN];
FILE *f;
int i,z;
int b,n,L;
int main(int argc,char **argv) {
if (argc<2) {
printf("Usage:%s fullpathfilename.ext\nget total blank/non-blank/total linenumbers.\n",argv[0]);
return 1;
}
f=fopen(argv[1],"r");
if (NULL==f) {
printf("Can not open file [%s]!\n",argv[1]);
return 2;
}
z=0;
b=0;
n=0;
L=0;
while (1) {
if (NULL==fgets(ln,MAXLEN,f)) break;
L=strlen(ln);
if ('\n'==ln[L-1]) {
if (0==z) {
for (i=0;i<L-1;i++) {
if (!(' '==ln[i] || '\t'==ln[i])) break;
}
if (i<L-1) z=1;//当前行不是空行
}
if (0==z) b++; else n++;
z=0;
} else {
if (0==z) {
for (i=0;i<L;i++) {
if (!(' '==ln[i] || '\t'==ln[i])) break;
}
if (i<L) z=1;//当前行不是空行
}
}
}
fclose(f);
if (L>0 && '\n'!=ln[L-1]) {
if (0==z) b++; else n++;//最后一行末尾无'\n'也计算
}
printf("File:[%s] total blank/non-blank/total linenumbers is %d/%d/%d\n",argv[1],b,n,b+n);
return 0;
}
#8
谢谢详解,我想再问个问题,我之前考虑的优化方案是再定义一个ch2,用来存放从文件读取的ch上一个值,大概想法是如果ch=EOF,ch2!=\n时,段落数++,请问把EOF作为从文件中读到的最后一个字符,这样的做法合理吗?可行吗?或者有什么能够定义文本文件最后一个字符的?(因为想在源程序的基础上进行较少的改动,对于之前楼层提出的建议会采纳再写一个程序)
#9
不是合不合理的问题,而是取舍的问题,
当时这么定义的读写文件的函数,自然有他的考量。
#10
谢谢详解,我想再问个问题,我之前考虑的优化方案是再定义一个ch2,用来存放从文件读取的ch上一个值,大概想法是如果ch=EOF,ch2!=\n时,段落数++,请问把EOF作为从文件中读到的最后一个字符,这样的做法合理吗?可行吗?或者有什么能够定义文本文件最后一个字符的?(因为想在源程序的基础上进行较少的改动,对于之前楼层提出的建议会采纳再写一个程序)
不是合不合理的问题,而是取舍的问题,
当时这么定义的读写文件的函数,自然有他的考量。那请问一下我可不可以做较小程度的修改来实现段落数的正确统计,因为段落数是以回车为标志的,如果最后一段没有回车就少统计一个。能不能帮忙看一下我对修改段落数统计的想法,谢谢。
#11
这个
读到文件结束,在上一个段落和文件结束前,有文字那就添加一个段落
如果,换行后(段落后)紧接着就是文件结束了,那就不用添加这个段落。
这是个+1 ,-1 的问题,处理一下就好。
读到文件结束,在上一个段落和文件结束前,有文字那就添加一个段落
如果,换行后(段落后)紧接着就是文件结束了,那就不用添加这个段落。
这是个+1 ,-1 的问题,处理一下就好。
#12
#include <stdio.h>
#include <stdlib.h>
int main()
{
FILE *fp1, *fp2; /*定义两个指向FILE类型结构体的指针变量*/
int ch;// 定义整型,用来读取字符
long paraglen =0;//定义段长
char filename1[100],filename2[100] ; /*定义数组变量为字符型*/
long character,word,sentence,paragraph; /*定义变量为长整型*/
character=word=sentence=paragraph=0; /*长整型变量的初值均为0*/
printf("Enter file name \n");
scanf("%s", filename1); /*输入要进行统计的文件的路径及名称*/
if((fp1=fopen(filename1, "r"))==NULL) /*以只读方式打开指定文件*/
{
printf("cannot open file.\n");
exit(1);
}
printf ( "Enter file name for write data:\n");
scanf("%s",filename2); /*输入文件名即将统计结果放到那个文件中*/
if((fp2=fopen(filename2, "w"))==NULL) /*已可写方式要存放统计结果的文件*/
{
printf("cannot open file \n");
exit(1);
}
while((ch=fgetc(fp1))!=EOF) /*知道文件内容结束处停止while循环*/
{
paraglen++;//每读取一个字符,段长加一
if(ch>='A' && ch<'Z'||ch>='a' && ch<='z')
{
character++;
} /*当遇到字母时字符个数+1*/
else if(ch==' ')
{
character++;
word++;
} /*当遇到空格时字符数+1*/
else if(ch>='0' && ch<='9')
{
character++;
} /*当遇到数字时数字个数+1*/
else if(ch=='.'||ch=='!'||ch=='?')
{
sentence++;
character++;
} /*当遇到.!?时句子数+1,字符数+1*/
else if ((ch=='\r')||(ch=='\n'))
{ paragraph++;
paraglen = 0;//段长,实际上是行长,每当换行就清零
} /*当遇到换行符时段落数+1*/
else
{
character++;
word++;
} /*遇到其他字符时字符个数+1*/
ch =0;
}
if(paraglen)
paragraph++; /*遇到段长非零,表示读到 文件结束,最后一个段(行),没有计算所以,段(行)数加一*/
/* (或者读出错,这里不考虑读文件出错),需要的话,使用ferror 函数,读取文件错误码 */
fclose(fp1); /*关闭fp1指向的文件*/
fprintf(fp2,"character:%ld word:%ld sentence:%ld paragraph:%ld\n", character, word, sentence,paragraph);/*将统计结果写入fp指向的磁盘文件中*/
fclose(fp2);
while(getchar()!='q');
}
这是修改后的代码
ch ++ 是不必要的,因为ch 是从文件里读出来的,需要的话,重置为 0
#13
这个
读到文件结束,在上一个段落和文件结束前,有文字那就添加一个段落
如果,换行后(段落后)紧接着就是文件结束了,那就不用添加这个段落。
这是个+1 ,-1 的问题,处理一下就好。
else
{
character++;
word++;
} /*遇到其他字符时字符个数+1*/
ch++;
ch2=ch;
}
if(ch2=='\n')
{
printf("a");
character++;
}
#14
1)ch 必须改为 int 类型,
因为 (ch=fgetc(fp1)) 同样是 ch类型的 和 EOF 比较是有问题的
2)多定义一个 字符类型,不如直接计算最后一行的长度简单明了
3) ch++; //这个++ 是不对的 ch 是从文件读到的数据 不用++,这个++ 造成 ch,ch2 通常不会 ‘\n'
ch2=ch; // 这是做什么用的?
因为 (ch=fgetc(fp1)) 同样是 ch类型的 和 EOF 比较是有问题的
2)多定义一个 字符类型,不如直接计算最后一行的长度简单明了
3) ch++; //这个++ 是不对的 ch 是从文件读到的数据 不用++,这个++ 造成 ch,ch2 通常不会 ‘\n'
ch2=ch; // 这是做什么用的?
#15
1)ch 必须改为 int 类型,
因为 (ch=fgetc(fp1)) 同样是 ch类型的 和 EOF 比较是有问题的
2)多定义一个 字符类型,不如直接计算最后一行的长度简单明了
3) ch++; //这个++ 是不对的 ch 是从文件读到的数据 不用++,这个++ 造成 ch,ch2 通常不会 ‘\n'
ch2=ch; // 这是做什么用的?
首先谢谢指正前面的错误。ch2=ch是想保存跳出while之前的最后一个字符,我觉得是ch==EOF之前的字符也就是文本中最后一个字符。如果ch2是\n,那段落数就少加一个。不谈前面的错误,这样的理解哪里有问题?为什么实现不了段落数的正确获取?
#16
这样理解是对的,你把错误的地方修改一下看看
#17
仅供参考:#include <stdio.h>
#include <string.h>
#define MAXLEN 1000
char ln[MAXLEN];
FILE *f;
int i,z;
int b,n,L;
int main(int argc,char **argv) {
if (argc<2) {
printf("Usage:%s fullpathfilename.ext\nget total blank/non-blank/total linenumbers.\n",argv[0]);
return 1;
}
f=fopen(argv[1],"r");
if (NULL==f) {
printf("Can not open file [%s]!\n",argv[1]);
return 2;
}
z=0;
b=0;
n=0;
L=0;
while (1) {
if (NULL==fgets(ln,MAXLEN,f)) break;
L=strlen(ln);
if ('\n'==ln[L-1]) {
if (0==z) {
for (i=0;i<L-1;i++) {
if (!(' '==ln[i] || '\t'==ln[i])) break;
}
if (i<L-1) z=1;//当前行不是空行
}
if (0==z) b++; else n++;
z=0;
} else {
if (0==z) {
for (i=0;i<L;i++) {
if (!(' '==ln[i] || '\t'==ln[i])) break;
}
if (i<L) z=1;//当前行不是空行
}
}
}
fclose(f);
if (L>0 && '\n'!=ln[L-1]) {
if (0==z) b++; else n++;//最后一行末尾无'\n'也计算
}
printf("File:[%s] total blank/non-blank/total linenumbers is %d/%d/%d\n",argv[1],b,n,b+n);
return 0;
}
变量z的含义是什么?
#18
仅供参考:#include <stdio.h>
#include <string.h>
#define MAXLEN 1000
char ln[MAXLEN];
FILE *f;
int i,z;
int b,n,L;
int main(int argc,char **argv) {
if (argc<2) {
printf("Usage:%s fullpathfilename.ext\nget total blank/non-blank/total linenumbers.\n",argv[0]);
return 1;
}
f=fopen(argv[1],"r");
if (NULL==f) {
printf("Can not open file [%s]!\n",argv[1]);
return 2;
}
z=0;
b=0;
n=0;
L=0;
while (1) {
if (NULL==fgets(ln,MAXLEN,f)) break;
L=strlen(ln);
if ('\n'==ln[L-1]) {
if (0==z) {
for (i=0;i<L-1;i++) {
if (!(' '==ln[i] || '\t'==ln[i])) break;
}
if (i<L-1) z=1;//当前行不是空行
}
if (0==z) b++; else n++;
z=0;
} else {
if (0==z) {
for (i=0;i<L;i++) {
if (!(' '==ln[i] || '\t'==ln[i])) break;
}
if (i<L) z=1;//当前行不是空行
}
}
}
fclose(f);
if (L>0 && '\n'!=ln[L-1]) {
if (0==z) b++; else n++;//最后一行末尾无'\n'也计算
}
printf("File:[%s] total blank/non-blank/total linenumbers is %d/%d/%d\n",argv[1],b,n,b+n);
return 0;
}
变量z的含义是什么?
你猜。
#19
仅供参考:#include <stdio.h>
#include <string.h>
#define MAXLEN 1000
char ln[MAXLEN];
FILE *f;
int i,z;
int b,n,L;
int main(int argc,char **argv) {
if (argc<2) {
printf("Usage:%s fullpathfilename.ext\nget total blank/non-blank/total linenumbers.\n",argv[0]);
return 1;
}
f=fopen(argv[1],"r");
if (NULL==f) {
printf("Can not open file [%s]!\n",argv[1]);
return 2;
}
z=0;
b=0;
n=0;
L=0;
while (1) {
if (NULL==fgets(ln,MAXLEN,f)) break;
L=strlen(ln);
if ('\n'==ln[L-1]) {
if (0==z) {
for (i=0;i<L-1;i++) {
if (!(' '==ln[i] || '\t'==ln[i])) break;
}
if (i<L-1) z=1;//当前行不是空行
}
if (0==z) b++; else n++;
z=0;
} else {
if (0==z) {
for (i=0;i<L;i++) {
if (!(' '==ln[i] || '\t'==ln[i])) break;
}
if (i<L) z=1;//当前行不是空行
}
}
}
fclose(f);
if (L>0 && '\n'!=ln[L-1]) {
if (0==z) b++; else n++;//最后一行末尾无'\n'也计算
}
printf("File:[%s] total blank/non-blank/total linenumbers is %d/%d/%d\n",argv[1],b,n,b+n);
return 0;
}
变量z的含义是什么?
你猜。
我猜:
z的含义表面上看是标记非空行,但在处理超长行时有特殊用途:
如果z为1,表明当前行非空,则只需读完改行剩下的内容即可。
否则,需要对当前读到的内容进行判断。
#20
到达文件末尾的时候,可以让文件位置指针后退2位,去读取最后一个字符,这样你不就知道最后一个字符是不是‘\n’
如果是'\n'的话,段落数+1,不是的话,就不用加1了
如果是'\n'的话,段落数+1,不是的话,就不用加1了
#21
#1
不要使用
while (条件)
更不要使用
while (组合条件)
要使用
while (1) {
if (条件1) break;
//...
if (条件2) continue;
//...
if (条件3) return;
//...
}
因为前两种写法在语言表达意思的层面上有二义性,只有第三种才忠实反映了程序流的实际情况。
典型如:
下面两段的语义都是当文件未结束时读字符
while (!feof(f)) {
a=fgetc(f);
//...
b=fgetc(f);//可能此时已经feof了!
//...
}
而这样写就没有问题:
while (1) {
a=fgetc(f);
if (feof(f)) break;
//...
b=fgetc(f);
if (feof(f)) break;
//...
}
类似的例子还可以举很多。
#2
不要使用
while (条件)
更不要使用
while (组合条件)
要使用
while (1) {
if (条件1) break;
//...
if (条件2) continue;
//...
if (条件3) return;
//...
}
因为前两种写法在语言表达意思的层面上有二义性,只有第三种才忠实反映了程序流的实际情况。
典型如:
下面两段的语义都是当文件未结束时读字符
while (!feof(f)) {
a=fgetc(f);
//...
b=fgetc(f);//可能此时已经feof了!
//...
}
而这样写就没有问题:
while (1) {
a=fgetc(f);
if (feof(f)) break;
//...
b=fgetc(f);
if (feof(f)) break;
//...
}
类似的例子还可以举很多。
不要使用
while (条件)
更不要使用
while (组合条件)
要使用
while (1) {
if (条件1) break;
//...
if (条件2) continue;
//...
if (条件3) return;
//...
}
因为前两种写法在语言表达意思的层面上有二义性,只有第三种才忠实反映了程序流的实际情况。
典型如:
下面两段的语义都是当文件未结束时读字符
while (!feof(f)) {
a=fgetc(f);
//...
b=fgetc(f);//可能此时已经feof了!
//...
}
而这样写就没有问题:
while (1) {
a=fgetc(f);
if (feof(f)) break;
//...
b=fgetc(f);
if (feof(f)) break;
//...
}
类似的例子还可以举很多。
那请问基于我的程序怎么改呢
#3
char ch;
应改为
int ch;
应改为
int ch;
#4
将while语句中的条件判断挪到while循环的第一句或中间某句或最后一句视具体情况而定。
#5
char ch;
应改为
int ch;
定义为char的目的就是为了读取文件中的字符,如果改为int类型是否也能实现同样的功能呢?
#6
char ch;//会导致无法区分到底是读到了0xFF字符还是到了文件末尾。
#7
仅供参考:
#include <stdio.h>
#include <string.h>
#define MAXLEN 1000
char ln[MAXLEN];
FILE *f;
int i,z;
int b,n,L;
int main(int argc,char **argv) {
if (argc<2) {
printf("Usage:%s fullpathfilename.ext\nget total blank/non-blank/total linenumbers.\n",argv[0]);
return 1;
}
f=fopen(argv[1],"r");
if (NULL==f) {
printf("Can not open file [%s]!\n",argv[1]);
return 2;
}
z=0;
b=0;
n=0;
L=0;
while (1) {
if (NULL==fgets(ln,MAXLEN,f)) break;
L=strlen(ln);
if ('\n'==ln[L-1]) {
if (0==z) {
for (i=0;i<L-1;i++) {
if (!(' '==ln[i] || '\t'==ln[i])) break;
}
if (i<L-1) z=1;//当前行不是空行
}
if (0==z) b++; else n++;
z=0;
} else {
if (0==z) {
for (i=0;i<L;i++) {
if (!(' '==ln[i] || '\t'==ln[i])) break;
}
if (i<L) z=1;//当前行不是空行
}
}
}
fclose(f);
if (L>0 && '\n'!=ln[L-1]) {
if (0==z) b++; else n++;//最后一行末尾无'\n'也计算
}
printf("File:[%s] total blank/non-blank/total linenumbers is %d/%d/%d\n",argv[1],b,n,b+n);
return 0;
}
#8
char ch;//会导致无法区分到底是读到了0xFF字符还是到了文件末尾。
谢谢详解,我想再问个问题,我之前考虑的优化方案是再定义一个ch2,用来存放从文件读取的ch上一个值,大概想法是如果ch=EOF,ch2!=\n时,段落数++,请问把EOF作为从文件中读到的最后一个字符,这样的做法合理吗?可行吗?或者有什么能够定义文本文件最后一个字符的?(因为想在源程序的基础上进行较少的改动,对于之前楼层提出的建议会采纳再写一个程序)
#9
char ch;//会导致无法区分到底是读到了0xFF字符还是到了文件末尾。
谢谢详解,我想再问个问题,我之前考虑的优化方案是再定义一个ch2,用来存放从文件读取的ch上一个值,大概想法是如果ch=EOF,ch2!=\n时,段落数++,请问把EOF作为从文件中读到的最后一个字符,这样的做法合理吗?可行吗?或者有什么能够定义文本文件最后一个字符的?(因为想在源程序的基础上进行较少的改动,对于之前楼层提出的建议会采纳再写一个程序)
不是合不合理的问题,而是取舍的问题,
当时这么定义的读写文件的函数,自然有他的考量。
#10
谢谢详解,我想再问个问题,我之前考虑的优化方案是再定义一个ch2,用来存放从文件读取的ch上一个值,大概想法是如果ch=EOF,ch2!=\n时,段落数++,请问把EOF作为从文件中读到的最后一个字符,这样的做法合理吗?可行吗?或者有什么能够定义文本文件最后一个字符的?(因为想在源程序的基础上进行较少的改动,对于之前楼层提出的建议会采纳再写一个程序)
不是合不合理的问题,而是取舍的问题,
当时这么定义的读写文件的函数,自然有他的考量。那请问一下我可不可以做较小程度的修改来实现段落数的正确统计,因为段落数是以回车为标志的,如果最后一段没有回车就少统计一个。能不能帮忙看一下我对修改段落数统计的想法,谢谢。
#11
这个
读到文件结束,在上一个段落和文件结束前,有文字那就添加一个段落
如果,换行后(段落后)紧接着就是文件结束了,那就不用添加这个段落。
这是个+1 ,-1 的问题,处理一下就好。
读到文件结束,在上一个段落和文件结束前,有文字那就添加一个段落
如果,换行后(段落后)紧接着就是文件结束了,那就不用添加这个段落。
这是个+1 ,-1 的问题,处理一下就好。
#12
#include <stdio.h>
#include <stdlib.h>
int main()
{
FILE *fp1, *fp2; /*定义两个指向FILE类型结构体的指针变量*/
int ch;// 定义整型,用来读取字符
long paraglen =0;//定义段长
char filename1[100],filename2[100] ; /*定义数组变量为字符型*/
long character,word,sentence,paragraph; /*定义变量为长整型*/
character=word=sentence=paragraph=0; /*长整型变量的初值均为0*/
printf("Enter file name \n");
scanf("%s", filename1); /*输入要进行统计的文件的路径及名称*/
if((fp1=fopen(filename1, "r"))==NULL) /*以只读方式打开指定文件*/
{
printf("cannot open file.\n");
exit(1);
}
printf ( "Enter file name for write data:\n");
scanf("%s",filename2); /*输入文件名即将统计结果放到那个文件中*/
if((fp2=fopen(filename2, "w"))==NULL) /*已可写方式要存放统计结果的文件*/
{
printf("cannot open file \n");
exit(1);
}
while((ch=fgetc(fp1))!=EOF) /*知道文件内容结束处停止while循环*/
{
paraglen++;//每读取一个字符,段长加一
if(ch>='A' && ch<'Z'||ch>='a' && ch<='z')
{
character++;
} /*当遇到字母时字符个数+1*/
else if(ch==' ')
{
character++;
word++;
} /*当遇到空格时字符数+1*/
else if(ch>='0' && ch<='9')
{
character++;
} /*当遇到数字时数字个数+1*/
else if(ch=='.'||ch=='!'||ch=='?')
{
sentence++;
character++;
} /*当遇到.!?时句子数+1,字符数+1*/
else if ((ch=='\r')||(ch=='\n'))
{ paragraph++;
paraglen = 0;//段长,实际上是行长,每当换行就清零
} /*当遇到换行符时段落数+1*/
else
{
character++;
word++;
} /*遇到其他字符时字符个数+1*/
ch =0;
}
if(paraglen)
paragraph++; /*遇到段长非零,表示读到 文件结束,最后一个段(行),没有计算所以,段(行)数加一*/
/* (或者读出错,这里不考虑读文件出错),需要的话,使用ferror 函数,读取文件错误码 */
fclose(fp1); /*关闭fp1指向的文件*/
fprintf(fp2,"character:%ld word:%ld sentence:%ld paragraph:%ld\n", character, word, sentence,paragraph);/*将统计结果写入fp指向的磁盘文件中*/
fclose(fp2);
while(getchar()!='q');
}
这是修改后的代码
ch ++ 是不必要的,因为ch 是从文件里读出来的,需要的话,重置为 0
#13
这个
读到文件结束,在上一个段落和文件结束前,有文字那就添加一个段落
如果,换行后(段落后)紧接着就是文件结束了,那就不用添加这个段落。
这是个+1 ,-1 的问题,处理一下就好。
else
{
character++;
word++;
} /*遇到其他字符时字符个数+1*/
ch++;
ch2=ch;
}
if(ch2=='\n')
{
printf("a");
character++;
}
#14
1)ch 必须改为 int 类型,
因为 (ch=fgetc(fp1)) 同样是 ch类型的 和 EOF 比较是有问题的
2)多定义一个 字符类型,不如直接计算最后一行的长度简单明了
3) ch++; //这个++ 是不对的 ch 是从文件读到的数据 不用++,这个++ 造成 ch,ch2 通常不会 ‘\n'
ch2=ch; // 这是做什么用的?
因为 (ch=fgetc(fp1)) 同样是 ch类型的 和 EOF 比较是有问题的
2)多定义一个 字符类型,不如直接计算最后一行的长度简单明了
3) ch++; //这个++ 是不对的 ch 是从文件读到的数据 不用++,这个++ 造成 ch,ch2 通常不会 ‘\n'
ch2=ch; // 这是做什么用的?
#15
1)ch 必须改为 int 类型,
因为 (ch=fgetc(fp1)) 同样是 ch类型的 和 EOF 比较是有问题的
2)多定义一个 字符类型,不如直接计算最后一行的长度简单明了
3) ch++; //这个++ 是不对的 ch 是从文件读到的数据 不用++,这个++ 造成 ch,ch2 通常不会 ‘\n'
ch2=ch; // 这是做什么用的?
首先谢谢指正前面的错误。ch2=ch是想保存跳出while之前的最后一个字符,我觉得是ch==EOF之前的字符也就是文本中最后一个字符。如果ch2是\n,那段落数就少加一个。不谈前面的错误,这样的理解哪里有问题?为什么实现不了段落数的正确获取?
#16
这样理解是对的,你把错误的地方修改一下看看
#17
仅供参考:#include <stdio.h>
#include <string.h>
#define MAXLEN 1000
char ln[MAXLEN];
FILE *f;
int i,z;
int b,n,L;
int main(int argc,char **argv) {
if (argc<2) {
printf("Usage:%s fullpathfilename.ext\nget total blank/non-blank/total linenumbers.\n",argv[0]);
return 1;
}
f=fopen(argv[1],"r");
if (NULL==f) {
printf("Can not open file [%s]!\n",argv[1]);
return 2;
}
z=0;
b=0;
n=0;
L=0;
while (1) {
if (NULL==fgets(ln,MAXLEN,f)) break;
L=strlen(ln);
if ('\n'==ln[L-1]) {
if (0==z) {
for (i=0;i<L-1;i++) {
if (!(' '==ln[i] || '\t'==ln[i])) break;
}
if (i<L-1) z=1;//当前行不是空行
}
if (0==z) b++; else n++;
z=0;
} else {
if (0==z) {
for (i=0;i<L;i++) {
if (!(' '==ln[i] || '\t'==ln[i])) break;
}
if (i<L) z=1;//当前行不是空行
}
}
}
fclose(f);
if (L>0 && '\n'!=ln[L-1]) {
if (0==z) b++; else n++;//最后一行末尾无'\n'也计算
}
printf("File:[%s] total blank/non-blank/total linenumbers is %d/%d/%d\n",argv[1],b,n,b+n);
return 0;
}
变量z的含义是什么?
#18
仅供参考:#include <stdio.h>
#include <string.h>
#define MAXLEN 1000
char ln[MAXLEN];
FILE *f;
int i,z;
int b,n,L;
int main(int argc,char **argv) {
if (argc<2) {
printf("Usage:%s fullpathfilename.ext\nget total blank/non-blank/total linenumbers.\n",argv[0]);
return 1;
}
f=fopen(argv[1],"r");
if (NULL==f) {
printf("Can not open file [%s]!\n",argv[1]);
return 2;
}
z=0;
b=0;
n=0;
L=0;
while (1) {
if (NULL==fgets(ln,MAXLEN,f)) break;
L=strlen(ln);
if ('\n'==ln[L-1]) {
if (0==z) {
for (i=0;i<L-1;i++) {
if (!(' '==ln[i] || '\t'==ln[i])) break;
}
if (i<L-1) z=1;//当前行不是空行
}
if (0==z) b++; else n++;
z=0;
} else {
if (0==z) {
for (i=0;i<L;i++) {
if (!(' '==ln[i] || '\t'==ln[i])) break;
}
if (i<L) z=1;//当前行不是空行
}
}
}
fclose(f);
if (L>0 && '\n'!=ln[L-1]) {
if (0==z) b++; else n++;//最后一行末尾无'\n'也计算
}
printf("File:[%s] total blank/non-blank/total linenumbers is %d/%d/%d\n",argv[1],b,n,b+n);
return 0;
}
变量z的含义是什么?
你猜。
#19
仅供参考:#include <stdio.h>
#include <string.h>
#define MAXLEN 1000
char ln[MAXLEN];
FILE *f;
int i,z;
int b,n,L;
int main(int argc,char **argv) {
if (argc<2) {
printf("Usage:%s fullpathfilename.ext\nget total blank/non-blank/total linenumbers.\n",argv[0]);
return 1;
}
f=fopen(argv[1],"r");
if (NULL==f) {
printf("Can not open file [%s]!\n",argv[1]);
return 2;
}
z=0;
b=0;
n=0;
L=0;
while (1) {
if (NULL==fgets(ln,MAXLEN,f)) break;
L=strlen(ln);
if ('\n'==ln[L-1]) {
if (0==z) {
for (i=0;i<L-1;i++) {
if (!(' '==ln[i] || '\t'==ln[i])) break;
}
if (i<L-1) z=1;//当前行不是空行
}
if (0==z) b++; else n++;
z=0;
} else {
if (0==z) {
for (i=0;i<L;i++) {
if (!(' '==ln[i] || '\t'==ln[i])) break;
}
if (i<L) z=1;//当前行不是空行
}
}
}
fclose(f);
if (L>0 && '\n'!=ln[L-1]) {
if (0==z) b++; else n++;//最后一行末尾无'\n'也计算
}
printf("File:[%s] total blank/non-blank/total linenumbers is %d/%d/%d\n",argv[1],b,n,b+n);
return 0;
}
变量z的含义是什么?
你猜。
我猜:
z的含义表面上看是标记非空行,但在处理超长行时有特殊用途:
如果z为1,表明当前行非空,则只需读完改行剩下的内容即可。
否则,需要对当前读到的内容进行判断。
#20
到达文件末尾的时候,可以让文件位置指针后退2位,去读取最后一个字符,这样你不就知道最后一个字符是不是‘\n’
如果是'\n'的话,段落数+1,不是的话,就不用加1了
如果是'\n'的话,段落数+1,不是的话,就不用加1了