C和C++⽂件的写⼊和读出⽅式
在C中提供了对设备上⽂件调⽤的底层接⼝
⽂件写⼊
C中提供的打开⽂件的函数FILE *fopen( const char * filename, const char * mode )
其中filename是⽂件名,mode是对⽂件的操作,下表为常见的mode值
对于⽂件的写⼊,常⽤的有四种⽅式
int fputc( int c, FILE *fp );
可以存⼊单个字符,如果写⼊成功,会返回写⼊字符的ASCII码值,如果发⽣错误,则会返回 EOF。
int fputs( const char *s, FILE *fp );
是写⼊⼀个以null结尾的字符串,会返回⼀个⾮负值,如果发⽣错误,则会返回 EOF。
size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *fp);
第⼀个传⼊的是要写⼊的字符串的指针,第⼆个是要写⼊的数据的⼤⼩,第三个是写⼊的输⼊数据个数,第四个是⽬标⽂件指针,返回实际写⼊的数据块数⽬
int fprintf(FILE *fp,const char *format, ...) ;
将⼀个字符串写⼊到⽂件中,其⽤法和printf类似。
⽂件读出
同样,读出⽂件⾥的字符也有常⽤的四种⽅式。
int fgetc( FILE * fp );
读⼊⼀个字符,返回读取的ASCII码值,如果发⽣错误则返回EOF
char *fgets( char *buf, int n, FILE *fp );
从⽂件中读取n-1个字符存到部分⾥,并在最后增加⼀个null作为终⽌符。在读取字符的过程中,如果遇到换⾏符或者⽂件结束的标识,则会返回之前读到的字符串,包括换⾏符。
size_t fread ( void *buf, size_t size, size_t count, FILE *fp) ;
第⼀个是存字符的buf,第⼆个是读取的长度,第三个是要读取的数据个数,第四个是⽂件指正,返回实际读到的数据个数
int fscanf(FILE*stream,const char*format,[]);
⽤法和scanf类似,如果失败,返回EOF。需要注意的是fscanf在遇到第⼀个空格或者换⾏符时停⽌读取,返回的时候不包括换⾏符或者空格
FILE* outfile = NULL;
outfile = fopen(FILE_NAME_1, "w+");
int i = 48;
int r1 = fputc(i, outfile);
if (r1 == EOF) {
std::cout << "error: write file error" << std::endl;
}
int r2 = fputc(10, outfile); //写⼊换⾏符
std::string s1 = "input string with fputs\n";
int r3 = fputs(s1.c_str(), outfile);
if (r3 == EOF) {
std::cout << "error: write file error" << std::endl;
}
std::string s2 = "input string with fwrite\n";
fwrite(s2.c_str(), s2.length(), 1, outfile);
fprintf(outfile, "input string with fprintf\0");
fclose(outfile);
FILE* infile = NULL;
fgets和fgetc的区别
char buf[255];
infile = fopen(FILE_NAME_1, "r");
fscanf(infile, "%s", buf);
printf("1: %s\n", buf);
fgets(buf, 255, (FILE*)infile);
printf("2: %s\n", buf);
fgets(buf, 255, (FILE*)infile);
printf("3: %s\n", buf);
int r = fgetc(infile);
printf("4: %d\n", r);
fscanf(infile, "%s", buf);
printf("5: %s\n", buf);
fclose(infile);
⽂件⾥的内容为:
input string with fputs
input string with fwrite
input string with fprintf
输出结果为
1: 0
2:
3: input string with fputs
4: 105
5: nput string with fwrite
input string with fprintf烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫?ô&烫烫烫烫痱&X'烫烫烫烫烫烫
第⼀个0由fscanf得到,fscanf不返回特殊符号,所以第⼆次读取的时候先读取到第⼀⾏的换⾏符,结束第⼆次读取并打印出两个换⾏符(其中另⼀个是printf⾥的)。第三次读才读到⽂件的第⼆⾏。fgets能够读取并返回换⾏符,所以⼜打印两次。fgetc得到“i”的ASCII 码,并打印出105。最后⽤fread读取剩余的⽂本,出现乱码。因为fread会读到⽂件结束,由于⽂件最后是⽤fprintf写⼊的,fread⽆法读取其中的⼿动输⼊的“\0”,所以最后输出buf的时候会将后⾯空的显⽰出来,造成乱码。⽽如果采⽤fgets或者fscanf来读取的话,则不会出现乱码。
这也说明,我们平时在使⽤这些⽂件处理函数的时候,最好是⼀⼀对应使⽤,交错使⽤可能会产⽣⼀些问题。
注意:需添加#define _CRT_SECURE_NO_WARNINGS,否则会报错
C++中,对于⽂件采⽤的是⽂件流的形式
分别是ofstream和ifstream,其使⽤⽅式和iostream中的cin和cout相似
std::ofstream outfile;
outfile.open(FILE_NAME_2, std::ios::out | std::ios::trunc);
outfile << "input string with <<\nthis is the second line" << std::endl;
outfile.close();
char data[255];
std::ifstream infile;
infile.open(FILE_NAME_2, std::ios::out | std::ios::in);
int i = 5;
while (i--)
{
infile >> data;
std::cout << data << std::endl;
}
⽂件内容为:
input string with <<
this is the second line
输出结果为:
input
string
with
<<
this
ifstream的>>读取到空格或者换⾏符的时候,就会停⽌读取。