C_I/O流

1、计算机组成了解:

首先了解计算机组成结构(冯诺·依曼体系),五部分:输入单元、输出单元、存储器、cpu(运算器、控制器)。
所谓的输入输出(I/O)是在内存的角度。

运行程序必须在cpu中运行,然而根据他们的执行速度,cpu只与内存进行交互,所以cpu要执行的程序必须从其他外设(除cpu和内存之外) 先加载到内存中
几个例子体现:
发送QQ文字的过程:
A方键盘输入 ---> A方内存 ---> A方cpu封装 ---> A方内存 ---> A方网卡输出 --->
B方网卡输入 ---> B方内存 ---> B方cpu解封 ---> B方内存 ---> B方显示器输出


发送QQ文件的过程:(文件存储于硬盘中)
A方硬盘输入 ---> A方内存 ---> A方cpu封装 ---> A方内存 ---> A方网卡输出 --->
B方网卡输入 ---> B方内存 ---> B方cpu解封 ---> B方内存 ---> B方硬盘输出
2、程序的错误码和退出码
错误报告函数:void perror(const char * str);
perror("error");
printf("error: %s", strerror(errno));

此两行代码的输出是相同的:errno(程序的错误码)

终止程序执行函数:void exit(int status);//status(程序的退出码)
exit函数就等价于main函数中的return status;(main函数的返回值)
程序退出码:0、正常退出、EXIT_SUCCESS;非0、非正常退出、EXIT_FAILURE
3、I/O流
概念:就C程序而言,所有的I/O操作就是简单的从程序移进、移出字节的事情,这种字节流被称为 ,“读取”和“写入”都是在一块内存区域(缓冲区)来回复制数据,缓冲区是按行刷新的(fflush)
分类:文本流(字符流)、二进制流
FILE: 是一个数据结构,用于访问一个流;程序运行中,默认打开三个流:标准输入(stdin):键盘设备、标准输出(stdout):终端或显示器、标准错误(stderr),他们都是一个指向FILE结构的指针。
I/O常量:EOF( 文本类文件结束标志、常量-1)
4、打开关闭流
    1、打开流:
FIEL* fopen( const char *filename, const char *mode);
mode:"r":只读,"r+":读、更新
"w":覆盖已有,"w+":写、更新
"a":追加, "a+"、追加写、更新
"t":文本形式,"b":二进制形式
    2、关闭流:
int fclose(FILE *stream);
5、字符I/O
    1、getchar函数和putchar函数
int getchar(void);
int putchar(int character);
    2、getc函数和putc函数
int getc( FILE *stream); // int c = getc(stdin); 等价于int c = getchar( );
int putc( int character, FILE *stream); // putc(c, stdout); 等价于putchar( );
    3、fgetc函数和fputc函数//功能同getc函数和putc函数一样
int fgetc( FILE *stream);
int fputc( int character, FILE *stream);
6、未格式化行I/O
    1、gets函数和puts函数
char *gets( char *str);
int puts( const char *str);
    2、fgets函数和fputs函数
char *fgets( char *str, int num, FILE *stream);//num:读取的字节数
//char buf[128];// fgets(buf, sizeof(buf)-1, stdio); 等价于gets(buf);
int fputs( const char *str, FILE *stream);// fputs(buf, stdout); 等价于puts(buf);
7、格式化行I/O
    1、scanf函数和printf函数
int scanf( const char *format, ...);
int printf( const char *format, ...);
说明:
printf("%5s","hello!"); //5代表最多读取5个字符
printf("%10d",1234); //10代表预留10个位置(右对齐),最少输出1234。
printf("%010d",1234); //0代表对预留位置空出的位置补0
printf("%x, %#x", 100, 100); //#代表着格式输出,结果为64,0x64
printf("%4.2f", 3.1416); //4代表预留的位置总大小,2代表精度
printf("%*d", 5, 10); //*会被5代替,预留5个位置的大小
    2、fscanf函数和fprintf函数
int fscanf( FILE *stream, const char *format, ... );// fscanf(stdio,"%d", &i); 等价于scanf("%d", &i);
int fprintf( FILE *stream, const char *format, ... );// fprintf(stdout,"%d", i); 等价于printf("%d", i);
    3、sscanf函数和sprintf函数

int sscanf( const char * buffer, const char * format [, argument ] ... );//从字符串(buffer)中读取格式化数据
int sprintf( char * buffer, const char * format [, argument] ... );//将格式化数据写入字符串 (buffer)
可以将要输入的内容保存在数组中,读取数组;
可以以不同的格式读取同一个数据。
#include<stdio.h>
#include<windows.h>

#pragma warning(disable:4996)

int main()
{
	char  tokenstring[] = "15 12 14...";
	char  s[81];
	char  c;
	int   i;
	float fp;

	/* Input various data from tokenstring: */
	sscanf(tokenstring, "%s", s);
	sscanf(tokenstring, "%c", &c);
	sscanf(tokenstring, "%d", &i);
	sscanf(tokenstring, "%f", &fp);

	/* Output the data read */
	printf("String:    = %s\n", s);
	printf("Character: = %c\n", c);
	printf("Integer:   = %d\n", i);
	printf("Real:      = %f\n", fp);

	system("pause");
	return 0;
}
运行结果:

8、二进制I/O(写入、读出一致)
size_t fread( void *ptr, size_t size, size_t count, FILE *stream);//读取count个size大小的二进制
size_t fwrite( const void *ptr, size_t size, size_t count, FILE *stream);//count*size == 要操作的总大小即可
#include<stdio.h>
#include<windows.h>

#pragma warning(disable:4996)

int main()
{
	FILE *stream;
	char list[30];
	int  i, numread, numwritten;

	/* Open file in text mode: */
	if ((stream = fopen("fread.txt", "w+t")) != NULL)
	{
		for (i = 0; i < 25; i++)
			list[i] = (char)('z' - i);
		/* Write 25 characters to stream */
		numwritten = fwrite(list, sizeof(char), 25, stream);
		fclose(stream);

	}
	else{
		perror("opening the file\n");
	}

	if ((stream = fopen("fread.txt", "r+t")) != NULL){
		/* Attempt to read in 25 characters */
		numread = fread(list, sizeof(char), 25, stream);
		printf("Contents of buffer = %.25s\n", list);
		fclose(stream);
	}
	else{
		perror("could not be opened\n");
	}
	system("pause");
	return 0;
}

运行结果:

9、其他函数
    1、fflush函数:刷新流, 强迫将缓冲区内的数据写回stream指定的流中
int fflush( FILE * stream );
#include<stdio.h>
#include<windows.h>

#pragma warning(disable:4996)

int main()
{
	int integer;
	char string[81];

	/* Read each word as a string. */
	printf("Enter a sentence of four words with scanf: ");
	for (integer = 0; integer < 4; integer++)
	{
		scanf("%s", string);
		printf("%s\n", string);
	}

	/* You must flush the input buffer before using gets. */
	fflush(stdin);//stdin流中有最后一个字符"":上个scanf接收字符时,以回车结束输入,但不接收此字符。
	printf("Enter the same sentence with gets: ");
	gets(string);
	printf("%s\n", string);

	system("pause");
	return 0;
}
    2、ftell函数:用于得到文件位置指针当前位置相对于文件首的偏移字节数。
long ftell( FILE * stream );//即, 返回的值为当前文件的大小
    3、fseek函数: 设置文件指针stream的位置
int fseek( FILE * stream, long offset, int origin );//stream将指向以origin(取值:SEEK_SET(文件首位置)、SEEK_CUR(文件当前位置)、SEEK_END(文件末尾处))为基准,偏移量offset个字节的位置。
    4、rewind函数:将文件指针重新定位到文件的开头。
void rewind( FILE * stream );
实现获取文件的大小:
FILE *pf;
long fSize;
pf = fopen("text.txt", "rt");
fseek(pf, 0, SEEK_END);
fSize = ftell(pf);
rewind(pf);
printf("%ld\n", fSize);

    5、feof函数:判断文件是否结束(其实是在判断写入位置与文件大小的关系)
feof函数既可判断二进制文件也可判断文本文件

int feof( FILE *stream );//遇到文件结束,返回非零值,否则返回0。
当把数据以二进制形式存放到文件中时,就会有-1值的出现,因此不能采用EOF作为二进制文件的结束标志。
FILE *pf;
char c;
pf = fopen("text.txt", "rt");
c = fgetc(pf);
while (!feof(pf))
{
	printf("%c\n", c);
	c = fgetc(pf);
}
特别注意:只有文件读到最后一个元素的后一个位置,才会判断出与文件大小不符。所以循环操作时,上述为正确写法。

猜你喜欢

转载自blog.csdn.net/tec_1535/article/details/80585830