写一个象vi一样的文本浏览器
下面代码是读出文本每一行并保存。主要是三个参数: 行号,每行内容,每行的字节数
重点是分配内存,特别是struct line 中的data 内存分配,先预扫文件得到有多少行和最多一行的字节数。再malloc 内存。
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
typedef struct {
int hh; //行号
char *data; // 行内容(以 \n 结尾)
int len; //每行 实际长度
} Line;
int main(void){
FILE *f=fopen("/home/wjs/Documents/glibc.txt","r");
if(f==NULL){
perror("file");
exit(1);
}
int zhh=0; //总行数
int zh_len=0; //没行总字节数
int ch;
int ls=zh_len;
while((ch=fgetc(f))!=EOF){
zh_len++;
if(ch=='\n'){
zhh++;
if(zh_len>ls) ls=zh_len;
zh_len=0;
}
}
if(zh_len>0) zhh++; // 防止文件最后一句没有'\n',直接EOF
zh_len=ls;
rewind(f);
Line *p=malloc(zhh*sizeof(Line));
int hh=1;
int idx=0;
char *hnr=malloc(zh_len+1);
int h_len=0;
int h_char;
while((h_char=fgetc(f))!=EOF){
if(h_char=='\n'){
(p+idx)->data=malloc(zh_len+1);
(p+idx)->len=h_len;
(p+idx)->hh=hh;
strncpy((p+idx)->data,hnr,h_len);
((p+idx)->data)[h_len]='\0';
memset(hnr,'\0',zh_len+1);
idx++;
hh++;
h_len=0;
}
if(h_char!='\n'){
hnr[h_len]=h_char;
h_len++;
}
}
if (h_len > 0) { // 防止文件最后一句没有'\n',直接EOF
p[idx].data = malloc(h_len + 1);
p[idx].len = h_len;
p[idx].hh = hh;
memcpy(p[idx].data, hnr, h_len);
p[idx].data[h_len] = '\0';
idx++;
}
hh=284;
if(hh>zhh){
puts("hh over");
exit(1);
}
idx=hh-1;
printf("hh=%d:h_ken=%d\n%s\n",(p+idx)->hh,(p+idx)->len,(p+idx)->data);
for (int i = 0; i < zhh; i++) {
free(p[i].data);
}
free(p);
free(hnr);
return 0;
}