【Linux】应用篇三--流的刷新定位与格式化输入输出

流的刷新定位与格式化输入输出

  • 一、流的刷新定位
    • 1、流的刷新
    • 2、流的定位
    • 3、检测流结束和出错(了解)
  • 二、格式化输入输出
    • 1、格式化输出
    • 2、格式化输入
  • 三、日志存放程序


一、流的刷新定位

1、流的刷新

#include 
int fflush(FILE *fp);

成功返回0出错返回EOF(-1)

  • 流缓冲区中的数据写入实际的文件
  • Linux下只能刷新输出缓冲区,输入缓冲区丢弃
  • 如果输出到屏幕使用fflush(stdout)

2、流的定位

long ftell(FILE *stream); //获取定位
/*定位到指定位置*/
long fseek(FILE *stream, long offset,  int whence); 
void rewind(FILE *stream); //定位到内容开头
  • fseek函数hence参数SEEK_SET/SEEK_CUR/SEEK_END
  • SEEK_SET: 从距文件开头 offset 位移量为新的读写位置
  • SEEK_CUR:以目前的读写位置往后增加 offset 个位移量
  • SEEK_END:将读写位置指向文件尾后再增加 offset 个位移量
  • offset参数:偏移量,可正可负

注意事项:

1 文件的打开使用a模式 fseek无效
2 rewind(fp) 相当于 fseek(fp,0,SEEK_SET);
3 这三个函数只适用2G以下的文件

示例:(获取文件长度)

FILE  *fp;
if ((fp = fopen(“test.txt”, “r+)) == NULL)
{
     perror(“fopen”);
     return  -1;
}
  fseek(fp, 0, SEEK_END);
  printf(“length is %d\n”, ftell(fp));

3、检测流结束和出错(了解)

#include  
int ferror(FILE *stream);
int feof(FILE *stream);
  • ferror():返回1表示流出错;否则返回0
  • feof():返回1表示文件已到末尾;否则返回0

二、格式化输入输出

1、格式化输出

#include  
int printf(const char *fmt,);
int fprintf(FILE *stream, const char *fmt,);
int sprintf(char *s, const char *fmt,);

成功时返回输出的字符个数出错时返回EOF(-1)

  • fprintf:将格式化的字符串打印到文件
  • sprintf:将格式化的字符存入字符类型的数组中

示例:
以指定格式 “年-月-日” 分别写入文件和缓冲区

int  year, month, date;
FILE *fp;
char buf[64];
year = 2014; month = 10; date = 26;
fp = fopen(“test.txt”, “a+);
fprintf(fp,%d-%d-%d\n”, year, month, date);
sprintf(buf,%d-%d-%d\n”, year, month, date);

2、格式化输入

int fscanf(FILE *stream, const char *format, ...);
int sscanf(const char *str, const char *format, ...);

成功时返回输出的字符个数出错时返回EOF(-1)
作用与格式化输出相反

重点掌握sprintf 和sscanf

三、日志存放程序

程序要求:

每隔1秒向文件1.txt中写入当前系统时间,格式如下:

1,  2014-10-15 15:16:42
2,  2014-10-15 15:16:43
  • 该程序无限循环,直到按Ctrl-C中断程序
  • 每次执行程序时,系统时间追加到文件末尾序号递增

1, 2014-10-15 15:16:42
2, 2014-10-15 15:16:43
3, 2014-10-16 11:35:07
4, 2014-10-16 11:35:08


写前准备:

  • time():用来获取系统时间(秒数)
/*获得的时间是1970.1.1 0:0:0到现在的所过的秒数*/
time_t time(time_t *seconds) 
  • localtime():将系统时间转换成本地时间
struct tm *localtime(const time_t *timer)
struct tm 
{
   int tm_sec;     /* 秒,范围从 0 到 59        */
   int tm_min;     /* 分,范围从 0 到 59        */
   int tm_hour;    /* 小时,范围从 0 到 23            */
   int tm_mday;    /* 一月中的第几天,范围从 1 到 31    */
   int tm_mon;     /* 月份,范围从 0 到 11            */
   int tm_year;    /* 自 1900 起的年数               */
   int tm_wday;    /* 一周中的第几天,范围从 0 到 6     */
   int tm_yday;    /* 一年中的第几天,范围从 0 到 365   */
   int tm_isdst;   /* 夏令时                         */    
};

注意:

  • int tm_mon: 获取的值要加1是正确的月份
  • int tm_year: 获取的值1900是正确的年份

得到文件内的所有行数量:

while(fgets(buf,32,fp)!=NULL)
{
	if(buf[strlen(buf)-1] =='\n') //注意判断是否是一行结束
	{  
		linecount++;
	}
}
  • 写完文件使用fflush,将缓存区的内容写到文件内。
  • 标准IO磁盘文件的缓冲区一般为4096
  • 注意和标准输出的全缓冲区别,标准输出1024

程序为:

/*
 * @Author: xiuchengzhen
 * @Date: 2022-03-16 19:40:09
 * @LastEditTime: 2022-03-16 21:00:03
 */
#include
#include
#include
#include


int main(int argc, const char *argv[])
{
	long int clock;
	struct tm *clocktim;
	int order = 1;
	char str[32] = {0};
	FILE *p = fopen("1.txt", "a+");
	if(p == NULL)
	{
		perror("fopen:");
		return -1;
	}

	while(fgets(str, 32, p))  //得到最底层行号
	{
		if(str[strlen(str)-1] == '\n')
			order++;
	}
	while(1)
	{
		clock = time(NULL);  //得到系统时间
		clocktim = localtime(&clock);  //将系统时间转换为本地时间

		printf("%04d-%02d-%02d %02d:%02d:%02d\n", clocktim->tm_year+1900, clocktim->tm_mon+1, clocktim->tm_mday,
				clocktim->tm_hour, clocktim->tm_min, clocktim->tm_sec); //打印在标准输出,看是否正确
		fprintf(p,"%d.%04d-%02d-%02d %02d:%02d:%02d\n", order, clocktim->tm_year+1900, clocktim->tm_mon+1, 
				clocktim->tm_mday,clocktim->tm_hour, clocktim->tm_min, clocktim->tm_sec);  //打印入文件
		fflush(p);  //刷新流,使缓存区内容写入文件

		order++;  //序号自增

		sleep(1); //延时1秒
	}

	fclose(p);
	
	return 0;
}

【Linux】应用篇三--流的刷新定位与格式化输入输出_第1张图片

你可能感兴趣的:(Linux,c语言,开发语言,linux)