
以下代码实现将文件中第6行处插入一行, 即原来的第6行以后依次往后移一行.
#include <stdio.h>
int main(void)
{
FILE *fp
int i
char buf[1024] // 假设每行不超过1024字节, 根据情况调节大小
if (!(fp = fopen("./a.txt", "r+"))) { // 尝试以读写方式打开文件.
fprintf(stderr, "Open failed.\n")
return 1
}
for (i = 0i <5i++) { // 循环5次, 读掉前5行
fgets(buf, 1024, fp) // 读取一行
}
// 此时文件指针指向第6行行首
long offset = ftell(fp) // 记录文件指针位置, 因为后面还要读, 文件指针会移走
// 这里为了程序易懂, 假设后面不超过100行, 每行不超过1024字节, 否则需要用链表或二重//指针的方式, 可以保证不浪费空间, 但代码就较复杂
char save[100][1024]
i = 0 // 清0, 记录后面共有多少行
while ((fgets(save[i], 1024, fp))) { // 循环读取文件, 直到fgets返回NULL表示读完
i++
}
printf("请输入要插入的数据内容:")
fgets(buf, 1024, stdin) // 接收键盘输入的内容
// 由于读完文件后, 文件指针指向文件尾, 这里重新定位到之前保存的位置
fseek(fp, offset, SEEK_SET)
fputs(buf, fp) // 写要插入的数据
int j
for (j = 0j <ij++) { // 之前保存的数据, 依次往后面写
fputs(save[j], fp)
}
return 0
}
结构体的大小不能简单认为就是成员的叠加..!!!所以你fprintf(“%d”)并不是说数据存文本里面就占四个字节,只是用10进制打印出来,可能是1个字节,也可能是5个字节,你fprintf("%s"),虽然长度在实际上就是24+1个字节,但是结构体中组织数据是需要对齐的.. temp2[25]占用内存是28个字节,因为是32位机,数据一般会四个字节对齐...对一个字节也是这样..自己看看sizeof(struct shijian)的大小....
fprintf("%4d")
fprintf("%28s")
用格式输出保证这个10进制数字的字符串占4个字节,这个时间的字符串占28个字节
这样就把文本的数据组织的和结构体一样大了..
调试的时候看看到底读出了多少个字节...fread你可以把单元设置为1,这样就能自己看读出出多少个字节,fread给你算了你当然看不到细节...
#include<stdio.h>
#include<time.h>
#include<string.h>
int main(int argc,char *argv[])
{
time_t timep1
struct shijian
{
int number
char timep2[25]
}
FILE *fp=NULL
if ((fp=fopen("1.txt","a+"))==NULL)
{
printf("can not open !")
return -1
}
struct shijian shijian[200]
int i=1
int rc
while(i==1 &&rc <10000)//rc超出10000的话,程序就又会不对劲了...只给了4个位
{
rc=fread(shijian,sizeof(struct shijian),200,fp)
// fflush(fp)
shijian->number=rc+1
// shijian->number=i
// i=rc
time(&timep1)
strcpy(shijian->timep2,ctime(&timep1))
printf("%d %s\n",shijian->number,shijian->timep2)
// fwrite(q->number,sizeof(q->number),1,fp)
// fflush(fp)
fprintf(fp,"%4d",shijian->number)fflush(fp)
fprintf(fp,"%28s",shijian->timep2)fflush(fp)
// fwrite(shijian->timep2,sizeof(shijian->timep2),1,fp)
rewind(fp)
sleep(3)
// fseek(fp,0,SEEK_SET)
// (shijian->number)++
}
fclose(fp)
return 0
}
程序功能:查询IP使用方法:
将IP库保存为c:\data.txt,将要查询的IP保存为c:\ip.txt;编译好本程序后,运行后产生c:\result.txt结果文件
程序BUG:data文件最后需要以两个换行结束
*/
#include <stdio.h>
#include <string.h>
#include <windows.h>
#include <stdlib.h>
#define TOTAL_INFO 100
extern void str_init(char* str1, char* str2, char* str3, char* str4) //字符串初始化函数
extern void str_init_total_info(char *str)
extern int read_file(FILE *fp, char *str) //读取IP
extern void read_dt2_next(FILE *fp, char *str) //单独保存数据库中第二IP段,最大IP范围
extern void next_line_data(FILE *fp) //专用:跳到下一行
extern void next_line_ip(FILE *fp)
extern int total_line(FILE *fp)//检测文件总行数
int main(int argc, char *argv[])
{
FILE *fp_data, *fp_ip, *fp_result
char t_dt1[5], t_dt2[5], t_dt3[5], t_dt4[5]
char t_ip1[5], t_ip2[5], t_ip3[5], t_ip4[5]//4个IP段,便于比较和保存
char t_dt2_next[5] //保存数据库中同一行第二IP段,最大IP范围
char addr_ip[50] //输出处理后的IP归属地
char temp
char ip_total_info[30]
int flag_loop_ip=1, flag_loop_data=1
int i=0, j=0, k=0, flag_complete=0
int len_dt1, len_dt2
int len_ip1, len_ip2
int total_line_nu=0
str_init(t_dt1, t_dt2, t_dt3, t_dt4) //初始化:将字符串以'\0'填充
str_init(t_ip1, t_ip2, t_ip3, t_ip4)
str_init_total_info(ip_total_info)
fp_data=fopen("c:\\data.txt", "r")
fp_ip=fopen("c:\\ip.txt", "r")
fp_result=fopen("c:\\result.txt", "a+") //追加文件,若存在
total_line_nu=total_line(fp_ip) //获取ip.txt文件的总行数
fseek(fp_ip, 0, SEEK_SET) //将fp_ip移动到文件开头
for(i=0i<total_line_nui++) //外层总循环,由ip.txt文件的总行数控制
{
flag_complete=0
len_ip1=read_file(fp_ip, t_ip1)
len_ip2=read_file(fp_ip, t_ip2)
read_file(fp_ip, t_ip3)
read_file(fp_ip, t_ip4)
for(j=0flag_complete == 0j++) //内层总循环,控制条件:是否完成一次比较
{
len_dt1=read_file(fp_data, t_dt1) //读取各段IP,并保存各段IP长度
len_dt2=read_file(fp_data, t_dt2)
read_file(fp_data, t_dt3)
read_file(fp_data, t_dt4)
read_dt2_next(fp_data, t_dt2_next) //单独保存数据库中第二IP段,最大IP范围
fseek(fp_data,9,SEEK_CUR) //文件指针后移9位,指向汉字将要出现的地方
fgets(addr_ip, 20 , fp_data) //单独保存IP信息(汉字)
for(k=0(temp=fgetc(fp_data)) != '\n'k++) //此处为了使主程序的内层循环自动换行
{
}
// fseek(fp_data,2,SEEK_CUR) //使fp_data指向下一行
// next_line(fp_data)
if(len_dt1==len_ip1 && len_dt2==len_ip2) //如果各段IP都一样长,则比较
{
if( !strcmp(t_dt1, t_ip1) ) //如果第一段的IP内容一样,比较第二段
{
if( ((strcmp(t_dt2, t_ip2)) <= 0) && ((strcmp(t_dt2_next, t_ip2)) >= 0) )
{ //如果要查询IP在这个IP段(BUG为:最小范围和最大范围个数不一样)
flag_complete = 1//完成一次循环
strcpy(ip_total_info,t_ip1) //整理要输出的信息
strcat(ip_total_info,".")
strcat(ip_total_info,t_ip2)
strcat(ip_total_info,".")
strcat(ip_total_info,t_ip3)
strcat(ip_total_info,".")
strcat(ip_total_info,t_ip4)
strcat(ip_total_info,"\t")
strcat(ip_total_info,addr_ip)
fputs(ip_total_info, fp_result)
fseek(fp_data, 0, SEEK_SET) //将fp_data移动到文件开头
}
}
}
//不满足条件时返回循环,因为readfile函数的设置,不用再重置到下一行
}
}
// printf("ftell:%d\n",ftell(fp_data)) //获取文件流的读取位置
// fseek(fp,2,SEEK_CUR) //
fclose(fp_data)
fclose(fp_ip)
fclose(fp_result)
return 0
}
void str_init(char *str1, char *str2, char *str3, char *str4)
{
int i
for(i=0i<5i++)
{
str1[i]='\0'
str2[i]='\0'
str3[i]='\0'
str4[i]='\0'
}
}
///////////////////////////////////////////////////////////////////////////////////////////////////
int read_file(FILE *fp, char* str)
{
int i, len
char t
for(i=0( (str[i]=fgetc(fp)) >= '0') &&(str[i] <= '9')i++) //从文件中读取字符串,直到非数字结束
{
}
str[i] = '\0'//将最后读取的非数字填充掉
len=strlen(str)
return len
}
void read_dt2_next(FILE *fp, char *str)//单独保存数据库中第二IP段,最大IP范围
{
char temp
int flag=0,i
for (i=0flag != 1i++ ) //直到找到第二段最大范围IP
{
temp = fgetc(fp)
if(temp == '.')//第二段IP以第一段的.开始
{
flag = 1
}
}
//保存找到的第二段最大范围IP
for(i=0( (str[i]=fgetc(fp)) >= '0') &&(str[i] <= '9')i++) //从文件中读取字符串,直到非数字结束
{
}
str[i] = '\0'//将最后读取的非数字填充掉
}
void next_line_data(FILE *fp) //使文件指针指向下一行
{
char t
t=fgetc(fp)
while(t != '\n')
{
// printf("temp t:%c\n", t)
// system("pause")
t=fgetc(fp)
}
t=fgetc(fp)
if (t != '\n')
{
fseek(fp,-1,SEEK_CUR)
}
else
{
t=getc(fp)
if (t != '\n')
{
fseek(fp,-1,SEEK_CUR)
}
}
//fseek(fp,4,SEEK_CUR) //精确定位到下下一行,因为两行之间有一个空白行
//t=fgetc(fp)//读取换行符,使文件指针指向下一行
}
void next_line_ip(FILE *fp) //使文件指针指向下一行
{
char t
t=fgetc(fp)
while(t != '\n')
{
// printf("temp t:%c\n", t)
// system("pause")
t=fgetc(fp)
}
fseek(fp,2,SEEK_CUR) //精确定位到下下一行,因为两行之间有一个空白行
//t=fgetc(fp)//读取换行符,使文件指针指向下一行
}
int total_line(FILE *fp) //检测总行数
{
char t1, t2
int flag=0, flag2=0
t1 = fgetc(fp)
t2 = fgetc(fp)
while (t1 != EOF) //到达文件尾或出错返回EOF
{
if( (t1 == '\n') &&(t1=fgetc(fp) != EOF))
{
flag2=0
flag+=1
}
else flag2=1
t1 = fgetc(fp)
}
flag=flag+flag2
return flag
}
void str_init_total_info(char *str)
{
int i
for(i=0i<TOTAL_INFOi++)
{
str[i]='\0'
}
}
另外,团IDC网上有许多产品团购,便宜有口碑
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)