c语言完整的数据输入输出(CC语言5)
c语言完整的数据输入输出(CC语言5)8 输出阶段:显示程序执行的结果。6.1 显示提示信息; 6.2 读取数据; 7 计算阶段 :由输入推导出输出的过程。通常通过各种计算得到。4 其他文件中的全局变量的extern声明;5 变量定义:为一些在程序编写时值未知的数据预约他们的存放处 ;6 输入阶段 :获取执行时才能确定的用户数据。输入过程一般包括两步 :
首先看一下一般程序的组成:
1 库文件包含,为可能需要调用的库函数或类定义包含库文件。
2 类型定义,包括结构体类型、类类型;
3 函数声明;
4 其他文件中的全局变量的extern声明;
5 变量定义:为一些在程序编写时值未知的数据预约他们的存放处 ;
6 输入阶段 :获取执行时才能确定的用户数据。输入过程一般包括两步 :
6.1 显示提示信息; 6.2 读取数据;
7 计算阶段 :由输入推导出输出的过程。通常通过各种计算得到。
8 输出阶段:显示程序执行的结果。
由上可知,输入、输出是程序很重要的组成部分。
通常,输入输出的方向性问题是站在内存的角度去看的:
输入输出作为库载入,也是为了空间效率的考量,当你不需要时,就可以不载入,让程序更轻量级。
一、C语言的输入输出程序输入源和输出目标统称为设备(device)。无论什么设备,是用于输入还是输出,C语言都通过流进行输入和输出操作。
流与文件息息相关。这里的文件指的不是磁盘文件,而是程序待处理的流和实际物理设备之间的媒介。大多数情况下,C语言的初学者无需了解这些文件,因为流、文件、设备之间的交互都由C库函数和操作系统自动完成。
C语言的流有两种模式:文本模式和二进制模式。文本流只由字符组成,如发送至屏幕的文本数据。文本流被组织成行,每行最多可255个字符,且以行结束符或换行符结尾。文本流中的某些字符(如换行符)有特殊的含义。
ASCII文件是将存储在文件中的每个字节解释成一个ASCII字符,二进制文件是将文件内容解释成一个二进制的比特流,由程序解释这些比特流的意义。
1 C语言控制台的输入输出
可以用printf()、scanf()等函数直接读取和写入控制台或文件。控制台I/O函数自动写入stdout(标准输出,输入缓冲区)或读取stdin(标准输入,输出缓冲区),这些是预定义的文件指针。
1.1 输出
printf("格式控制串" "输出项列表")
格式控制串包括: ① 普通字符:原样输出; ② 转义字符,以"\"开头; ③ 格式说明符,以"%"开头,控制数据输出格式以及作为变量的占位符。 输出项列表:是与“格式控制串”中以“%”开头的占位符对应的变量;
1.2 输入
在用scanf()函数传参时,数值和字符类型变量之前要使用取地址符&,而字符串变量则不需要,因为其变量名本身就代表内存地址。
scanf("%d %d" &a &b); 函数返回值为int型。如果a和b都被成功读入,那么scanf的返回值就是2; 如果只有a被成功读入,返回值为1; 如果a和b都未被成功读入,返回值为0; 如果遇到错误或遇到end of file,返回值为EOF。end of file为Ctrl z 或者Ctrl d。
2 C语言文件的输入输出
对文件操作的顺序:打开文件→读写文件→关闭文件。打开文件是指将文件从磁盘调入内存,并与文件操作指针建立关联。文件使用结束应及时关闭,以免丢失信息,关闭文件的同时也是存盘的过程。
一旦建立了一个流,将它与文件相关联的一种方法是使用函数fopen()。
fopen()打开一个文件并且创建一个用于存储文件和缓冲区信息的结果,返回指向该结构的指针。
fclose()关闭文件并刷新缓冲区。
c语言在文件中存取数据有两种方式:顺序读写和随机读写,即可以通过一般的读写操作函数进行顺序存取,又可以通过函数fseek(fp 位移量 起始点)对文件中的位置指针进行定位,再用读写操作函数进行存取,即实现随机存取。
文本文件在读入内存时先转换为二进制文件,并直接在屏幕上显示字符,因此便于阅读和逐个字符打印。
二进制文件在读写数据时不需要转换,但显示在屏幕上时需要先转换为ASCII码再显示。
fgets(str n fp)的功能是:从fp所指向的文件中读取长度不超过n-1的字符串存入str开始的内存。
fputs(p1 p2)从p1开始的内存中读取一个字符串存入p2指向的文件。
若在取字符过程中遇到行结束标志\n或文件结束标志EOF(-1),则读取操作自动结束。取出的字符数可以少于n-1个。取字符结束后自动在末尾加上字符串结束标志\0。
feof(fp)测试文件是否结束,返回1或0。
fread(buffer size cout fp)从文件指针fp指向的文件中读取count个size大小的数据存入内存buffer开始的单元
FILE* file=fopen("test.txt" "r"); int iSize=filelength(fileno(file)); fclose(file);
filelength函数用于获取文件的长度,但是最大只能获取2g的文件大小,因为返回值类型long使用4个字节大小来表示,最大为2的31次方也就是2G的大小。
long filelength(int _FileHandle); _FileHandle:文件的句柄。 返回值:文件的大小,单位为字节。
缓冲输入,将若干内容先存储到称为缓冲区(buffer)的临时存储区域,等待适当时机将缓冲区内的内容变得对程序可用,非缓冲输入是不使用缓冲区,直接让输入对程序可用。缓冲输入对于频繁读写有更高的效率,而非缓冲输入是即时交互程序所需要的。
fwrite() 向指定的文件中写入若干数据块,如成功执行则返回实际写入的数据块数目。该函数以二进制形式对文件进行操作,不局限于文本文件。
size_t fwrite(const void* buffer size_t size size_t count FILE* stream); 返回值:返回实际写入的数据块数目 (1)buffer:是一个指针,对fwrite来说,是要获取数据的地址; (2)size:要写入内容的单字节数; (3)count:要进行写入size字节的数据项的个数; (4)stream:目标文件指针; (5)返回实际写入的数据项个数count。 FILE * pFile; char buffer[] = { 'x' 'y' 'z' }; pFile = fopen ( "myfile.bin" "wb" ); fwrite (buffer sizeof(char) sizeof(buffer) pFile ); fclose (pFile);
文件指针FILE *fp,FILE是一个结构:
typedef struct { short level; /* fill/empty level of buffer */ unsigned flags; /* File status flags */ char fd; /* File descriptor */ unsigned char hold; /* Ungetc char if no buffer */ short bsize; /* Buffer size */ unsigned char *buffer; /* Data transfer buffer */ unsigned char *curp; /* Current active pointer */ unsigned istemp; /* Temporary file indicator */ short token; /* Used for validity checking */ } FILE; /* This is the FILE object */ 二、C 语言的输入输出
1 C 控制台的输入输出
输入是数据从输入设备(如键盘、磁盘和鼠标等)到内存的过程,输出是内存中的数据输出到输出设备(如显示屏幕、打印机和磁盘等)的过程。输入输出过程中,数据像流水一样从一处流到另外一处,C 形象地描述该过程为流。流的内容可以是ASCII码字符、二进制形式的数据、图形图像、数字音频视频或者其他形式的信息。
C 语言本身是不提供输入输出操作的,它的输入/输出(input/output)由标准库提供。标准库定义了一组类型,支持对文件和控制窗口等设备的读写(I\O)。还定义了其他一些类型,使string 对象能够像文件一样操作,从而使编程者无须I\O 就能实现数据与字符之间的转换。这些I\O 类型都定义了如何读写内置数据类型的值。此外,类的设计者还可以很方便地使用I\O 标准库设施读写自定义类的对象。类类型通常使用IO 标准库为内置类型定义的操作符和规则来进行读写。
printf()、scanf()不能“智能”地处理类型,这个任务交给程序员去完成。同时,也无法直接用预定义的库函数来完成类类型的输入输出。这使得程序员不得不用更多的代码来完成新类型数据的输入输出。作为比C更好的语言,C 当然会提出解决问题的方式,这就是流(Stream)。 流(stream)是由字符(或其他类型的数据)构成的“流”(flow)。流向程序,称为输入流(inputstream)。流出程序,则称为输出流(output stream)。如输入流来自键盘,表明程序要从键盘获取输入。如输入流来自文件,表明程序要从文件获取输入。类似地,输出流可发送给屏幕或文件 可将流连接到的文件视为这个流的值。可以将流与文件断开,再连接到另一个文件,换言之,可以更改流变量的值。然而,必须使用专门处理流的函数才能完成这些更改。不能像使用int 或char 类型的变量那样在赋值语句中使用流变量。虽然流是变量,但它们是特殊的变量。
C 标准库的输入输出功能就涉及了流的使用。C 的输入输出流是指由若干字节组成的字节序列,这些字节中的数据按顺序从一个对象传送到另一个对象。流实际上是程序中输入或者输出设备的一种抽象表示,它表示了信息从源端到目的端的运动。在输入操作时, 字节流从输入设备(如键盘、磁盘)流向内存;在输出操作时,字节流从内存流向输出设备(例如屏幕、打印机、磁盘等)。流中的内容可以是ASCII 字符、二进制形式的数据、图形图像、数字音频视频或其他形式的信息。
实际上,在内存中为每个数据流开辟一个内存缓冲区,是用来存放流中的数据。流是与内存缓冲区相对应的,或者可以说,缓冲区中的数据就是流。
C 采用继承的方法建立了比较实用的流库。
输入输出流被定义为类,C 的I/O库中的类称为流类,用流类定义的对象称为流对象。
C 预定义了四个流对象:cin、cout、cerr和clog,分别对应于标准输入流、标准输出流、无缓冲的标准错误流以及有缓冲的标准错误流。
C 流库中的所有流、对象和函数都定义在标准名字空间std中,因此,使用I/O流需要用到以下名字限定语法。
std::cin、std::cout、std::endl
endl插入一个新行并刷新流;flush刷新流。
cin对象的默认输入设备是键盘;cout对象的默认输出设备是屏幕。不同数据类型的输入和输出是对插入操作符和抽取操作符的重载。操作后的返回结果仍然是输入输出流的对象,便于连续输入或输出。
当开始执行C 程序时,C 会有几个自动打开的预定义流,分别是:cin(相当于C的stdin)、cout(相当于C的stdout)、cerr和clog(相当于C的stderr)。
cerr没有被缓冲,而clog有被缓冲。
默认情况下,C 标准流cin和cout被连到控制台上,但它也可以被重新定向。cerr和clog与标准错误设备相关连,它不能被重新定向,因此,输出到cerr和clog的信息总是能在屏幕上显示。
istream流类将运算符>>重载为输入运算符。重载运算符函数operator>>的第二个参数必须是一个引用。
ostream流类将运算符<<重载为输出运算符。重载运算符函数operator<<的第二个参数必须是一个引用。
istream和ostream两个类提供了流库的主要输入输出界面。
输出运算符<<也称为插入(Inserting)运算符,通过输出运算符传送到输出设备。输出运算符有两个操作数,左操作数为ostream类类型的对象,右操作数是存储输出数据的变量,可以是一个预定义类型的变量,也可以是重载了该运算符(<<)的类的对象。输出运算符采用左结合方式,允许多个输出操作组合到一个语句中。
输入出运算符>>也称为提取(Extraction)运算符,通过输入运算符传送到输入设备。输入运算符有两个操作数,左操作数为istream类类型的对象,右操作数是存储输出数据的变量,可以是一个预定义类型的变量,也可以是重载了该运算符(>>)的类的对象。输出运算符采用左结合方式,允许多个输出操作组合到一个语句中。
在默认情况下,运算符>>跳过空白符,然后读入对应于输入变量类型的值。对于类型char*(作为串看待),运算符>>的作用也是跳过空白,读入以下非空白字符,直到发现另一个空白字符为止,并在串尾放一个字符'\0',要小心避免串溢出。
C 预定义的流对象也可以使用操纵符进行格式化输出:操纵符算子manipulator是一系列特殊的函数,它不属于任何类的成员,主要用来格式化输入输出,定义在iostream.h和iomanip.h两个头文件中。
如width,setf 和precision可用于格式化输出。这些输出函数同时适用于连接到屏幕的cout 流和连接到文件的输出流。
cout<<a; cout是对象,<<是操作符,a是操作数。 输出a的16进制:cout<<hex<<a<<endl; //表明浮点数用科学表示法输出 cout.setf(ios::scientific ios::floatfield); cout.setf(ios::fixed ios::floatfield);
cin以空格作为字符串的结束依据,不会被读入。
用cin输入时是以空格、回车或Tab键作为结束符。因此无法输入包含空白字符的字符串
在用cin输入时,要注意输入的字符串的长度不能超过数组的长度。因此,最好在输出的提示信息中告知允许的最长字符串长度。
成员函数getline可以将空格一起读入;
istream& getline(char * int char = '\n');
第一个参数用于指定字符数组的首地址; 第二个参数用于指定允许诗篇的最多字符个数; 第三个参数用于指定表示输入结束的字符,默认为回车
操作实例:
a.使用流操纵符输出整数100的八进制、十进制和十六进制的表示。 cout << oct << 100 << ‘\t’ << dec << 100 << ‘\t’ << hex << 100 << endl; b.以科学计数法显示实型数123.4567。 cout << scientific << 123.456 << endl; c.将整型数a输出到一个宽度为6的区域,空余部分用’$’填空。 cout << setw(6) << setfill(‘$’) << a << endl ; d.输出char *类型的变量ptr中保存的地址。 cout << (void *)ptr << endl;
2 C 文件的输入输出
文件和程序变量都可存储值,而且都可从中检索(获取)值。程序变量只存在于程序运行期间,而文件在程序运行前就可能存在,而且在程序终止之后可继续存在。简单地说,文件可以是永久性的,变量则不然。文件能存储大量数据,变量则不能提供如此大的存储量。
如直接处理而不需显示的数据一般以二进制形式存储文件,字符串显示数据通常以文本形式存储。
如何对文件进行读写操作?
实例化一个流对象,利用流对象方法open打开一个文件(参数是路径 打开方式),这样就可以对文件进行读写了。如果某些文件因为某些原因不能打开(如欲写文件的磁盘已满,或想写到U盘,但U盘沿未插好等),流对象的值为0。在对文件进行操作前,必须确保文件已打开,否则要进行相应的处理。为确认打开文件是否成功,通常固定采用好下程序段。
ifstream ifile("test.txt"); if(!ifile) { cout<"Can't open the file!\n"; exit(1); //标准库函数,在stdlib.h中,程序结束,并返回1作为错误代码 }
在C 中有ifstream和ofstream类,它们的默认输入/输出设备都是磁盘文件。
在C 中,要进行文件I/O,首先必须创建一个流,然后将这个流与文件相关联(称为打开文件),这时才能进行读写操作。使用完后,需要关闭文件。
ofstream ofile("test.txt");
ofstream类自动打开文件的构造函数,该构造函数的参数和默认值与open()函数相同。
可用文件保存程序输入或接收程序输出。用于程序I/O 的“文件”和用于保存程序的“文件”没有区别。利用“流”,程序可以采用统一的方式处理文件输入与键盘输入,并可采用统一的方式处理文件输出与屏幕输出。
fstream file("test.txt" ios::out); file<"2 sex:"<endl;
cin 和cout 流是系统已经为你声明好的。要将流连接到文件,必须像声明其他任何变量那样声明流。“输入文件流”(input-file stream)变量的类型名称是ifstream;“输出文件流”(output-file stream)变量的类型名称是ofstream。所以,要将inStream 声明为用于文件的输入流,将outStream 声明为用于另一个文件的输出流。
ifstream 类型的流可通过调用成员函数open 连接到文件。之后就可从文件读取输入。
ofstream 类型的流可通过调用成员函数open 连接到文件。之后就可将输出发送到文件。
需要使用如下所示的语句:
ifstream inStream; ofstream outStream;
流变量(例如前面声明的inStream 和outStream)必须连接到一个文件。这称为打开文件,用open 函数完成该操作。例如,假定希望输入流inStream 连接到infile.dat 文件,程序首先执行以下语句,然后才能从该文件读取输入:
inStream.open("infile.dat");
程序使用的每个输入和输出文件都有两个名称。外部文件名是文件真实名称,但只在open函数调用中使用一次,该函数将文件连接到一个流。一旦调用了open,就必须将流名称作为文件名使用。
程序完成从文件输入或者向文件输出之后,应该将文件关闭。关闭文件导致流与文件断开。调用close 函数关闭文件。:inStream.close();
如程序正常终止,但没有关闭文件,系统会自动为你关闭。但最好养成主动关闭文件的好习惯,原因有二。
其一,只有在程序正常终止的前提下,系统才会为你关闭文件。假如程序因为错误而异常终止,文件就不会关闭,并可能损坏。程序在结束文件处理后立即关闭文件,文件损坏的几率就大大降低。
其二,你可能希望程序将输出发送给一个文件,以后又将那些输出读回程序。为此,程序应该在完成向文件的写入之后立即关闭文件,再用open 函数将文件连接到一个输入流(也可以打开一个文件,并同时进行输入和输出,但方式稍有区别)。
操作符>>和<<可像应用于cin 和cout 那样应用于连接到文件的流。但文件I/O 的编程风格有别于屏幕和键盘I/O。(读取键盘输入应提示并回显用户输入)
可同时打开多个流进行输入输出。因此,一个程序可以既从键盘获取输入,也从一个或多个文件获取输入。同一个程序可以既向屏幕发送输出,也向一个或多个文件发送输出。另外,还可从键盘获取所有输入,并将输出同时发送到屏幕和文件。输入流和输出流可任意组合。
流可作为函数实参使用。唯一限制就是形参必须传引用。
每个输入文件流都有名为eof 的成员函数,用于判断何时读完文件的全部内容,没有更多的输入。
C 读写文件实例:
#include<iostream> #include<fstream> using namespace std; int main() { fstream file("test.txt" ios::out); if(!file.fail()) { cout<<"star write"<<endl; file<<"1 name:"<<"\r\n"; file<<"2 sex:"<<endl; cout<<"successfully writed!"<<endl; } else cout<<"can not open"<<endl; file.close(); system("pause"); return 0; } // reading a text file #include<iostream.h> #include<fstream.h> #include<stdlib.h> int main () { char buffer[256]; ifstream in("test.txt"); if (! in.is_open()) { cout << "Error opening file"; exit (1); } while (!in.eof() ) { in.getline (buffer 100); cout << buffer << endl; } system("pause"); return 0; } 三、有关输入输出的常用函数
putc(); 字符 fscanf(); 字词,遇到空格和换行时结束 puts(); 串、行 fputs(); 串、行,比puts()安全,是puts()的替代函数 printf()与puts(),前者不只是字符串,scanf()与gets()也是一样;
-End-