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);
}
特别注意:只有文件读到最后一个元素的后一个位置,才会判断出与文件大小不符。所以循环操作时,上述为正确写法。