来源 《Pointers on C》:
Write a programe that reads input lines one by one until end of file is reached,determines the length of each input line,and then prints out only the longest line that was found. To simplicify matters, you may assume that no input line will be longer than 1000 characters.
问题解析:读文件,判断每一行字符的长度,输出最长的一行。为了简化问题,假设每一行的长度都不会大于1000个字符。
解题思路:
首先判断文件的行数,然后使用fgetc函数读取每一行,并将结果保存在结构体中,结构体的成员变量为 key,value ( key就是行号,value就是字符串长度)
找出最长的字符串之后,就按照行号进行读取。
代码如下:
#include <stdio.h>
#include <stdlib.h>
//结构体 用来存储 拥有最长字符串的行号和字符数。行号存放在 key里,字符数存放在 value里面。初始值为 0 。
struct length{
int key;
int value;
};
int main()
{
fpos_t pos1,pos2; //定义两个文件指针,pos1用来保存文件开头的位置。
struct length len;
FILE * source;
len.key = 0;
len.value = 0;
source = fopen("/program/addoverflowDemo.c","r");
//i,j为计数器
int i = 0;
int j = 0;
char c;
fgetpos(source,&pos1); //保存文件头指针
//计算文件的总行数,保存在i中
do {
c = fgetc(source);
if(c == '\n')
{
i ++;
}
}while(c != EOF);
printf("%d\n",i);
int lines;
lines = i;
fsetpos(source,&pos1); //恢复文件指针
for(i = 0; i < lines; i++) //外环为一共15行
{
//计算每一行有多少个字符,并进行保存。
do {
c = fgetc(source);
if(c != '\n'){
j ++;
}
}while(c != '\n');
if(j > len.value) //如果当前行的字符数大于len.value那么,就用新值替换。
{
len.value = j;
len.key = i;
}
j = 0;
}
printf("len.key= %d\nlen.value= %d\n",len.key,len.value);
fclose(source);
return EXIT_SUCCESS;
}
编译运行 本程序输出结果为:
[root@localhost program]# ./printlongestDemo
15
len.key= 9
len.value= 53
可见,最大的行号为行9,即第10行,字符数为53.
然后就可以找到行号,输出相应的字符串了。
但是,此时有一个问题,就是 如果我的两行的或者是多行的字符串一样怎么办?
解析:此时就不能够这样写了:
if(j > len.value) //如果当前行的字符数大于len.value那么,就用新值替换。
{
len.value = j;
len.key = i;
}
不能够替换了,而是要保存每一次的值。
修改后的核心代码为,定义一个len数组,分别用来存放每一行的行号和字符数。
修改后的代码如下:
#include <stdio.h>
#include <stdlib.h>
struct length{
int key;
int value;
};
int main()
{
fpos_t pos1,pos2;
FILE * source;
FILE * des;
source = fopen("/program/addoverflowDemo.c","r");
int i = 0;
int j = 0;
char c;
fgetpos(source,&pos1);
do {
c = fgetc(source);
if(c == '\n')
{
i ++;
}
}while(c != EOF);
printf("%d\n",i);
int lines;
lines = i;
struct length len[lines];
fsetpos(source,&pos1);
for(i = 0; i < 15; i++)
{
do {
c = fgetc(source);
if(c != '\n'){
j ++;
}
}while(c != '\n');
len[i].key = i;
len[i].value = j;
printf("len.key= %d\nlen.value= %d\n",len[i].key,len[i].value);
j = 0;
//printf("%d\n",i);
}
fclose(source);
return EXIT_SUCCESS;
}
编译运行输出为:
[root@localhost program]# ./printlongestDemo
15
len.key= 0
len.value= 18
len.key= 1
len.value= 19
len.key= 2
len.value= 0
len.key= 3
len.value= 10
len.key= 4
len.value= 1
len.key= 5
len.value= 9
len.key= 6
len.value= 21
len.key= 7
len.value= 49
len.key= 8
len.value= 16
len.key= 9
len.value= 53
len.key= 10
len.value= 52
len.key= 11
len.value= 25
len.key= 12
len.value= 0
len.key= 13
len.value= 20
len.key= 14
len.value= 1
这样,拥有最大字符串长度的所有的行号我们都找到了。下面的任务就是按照行号进行输出了。
运用以前学到的知识,我想首先对这个结构体数组按照关键字(value值)进行排序。
今天的关键收获就是学会了使用fpos_t类型还有操作 fpos_t类型的函数 fgetpos(source,&pos1); 和 fsetpos(source,&pos1); 对文件操作更熟练了!
太晚了,明天接着说。。。