【C写文件】C/C++读写文本文件、二进制文件/文件读写

编程入门 行业动态 更新时间:2024-10-23 18:35:30

【C写<a href=https://www.elefans.com/category/jswz/34/1771438.html style=文件】C/C++读写文本文件、二进制文件/文件读写"/>

【C写文件】C/C++读写文本文件、二进制文件/文件读写

目录

一:目的

二:C语言文本文件读写

1. 文本文件写入

2. 文本文件读取

三:C语言二进制文件读写

1. 二进制文件写入

2.二进制文件读取

四:C++文本文件读写

1. 文本文件写入

2.文本文件读取

五:C++二进制文件读写

1. 二进制文件写入

2.二进制文件读取

六 总结

获取文件大小

方法一

方法二


一:目的

掌握C语言文本文件读写方式;

掌握C语言二进制文件读写方式;

掌握CPP文本文件读写方式;

掌握CPP二进制文件读写方式;

二:C语言文本文件读写

1. 写入文本文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26

 

//采用C模式对Txt进行写出
void TxtWrite_Cmode()
{
    //准备数据
    int index[50] ;
    double x_pos[50], y_pos[50];
    for(int i = 0; i < 50; i ++ )
    {
        index[i] = i;
        x_pos[i] = rand()%1000 * 0.01 ;
        y_pos[i] = rand()%2000 * 0.01;
    }
    //写出txtFILE * fid = fopen("txt_out.txt","w");
    if(fid == NULL)
    {
        printf("写出文件失败!\n");
        return;
    }
    for(int i = 0; i < 50; i ++ )
    {  fprintf(fid,"d\t%4.6lf\t%4.6lf\n",index[i],x_pos[i],y_pos[i]);
    }  fclose(fid);
}

2. 读取文本文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50

 

//采用C模式对Txt进行读取
void TxtRead_Cmode()
{  FILE * fid = fopen("txt_out.txt","r");
    if(fid == NULL)
    {
        printf("打开%s失败","txt_out.txt");
        return;
    }
    vector<<span style="color:#8000ff;">int> index;
    vector<<span style="color:#8000ff;">double> x_pos;
    vector<<span style="color:#8000ff;">double> y_pos;
    int mode = 1;
    printf("mode为1,按字符读入并输出;mode为2,按行读入输出;mode为3,知道数据格式,按行读入并输出\n");
    scanf("%d",&mode);
    if(mode == 1)
    {
        //按字符读入并直接输出
        char ch;       //读取的字符,判断准则为ch不等于结束符EOF(end of file)    while(EOF!=(ch= fgetc(fid)))
             printf("%c", ch); 
    }
    else if(mode == 2)
    {
        char line[1024];
        memset(line,0,1024);  while(!feof(fid))
        {
            fgets(line,1024,fid);
            printf("%s\n", line); //输出
        }

    }
    else if(mode == 3)
    {
        //知道数据格式,按行读入并存储输出
        int index_tmp;
        double x_tmp, y_tmp; while(!feof(fid))  
        {  
            fscanf(fid,"%d%lf%lf\n",&index_tmp, &x_tmp, &y_tmp);
            index.push_back(index_tmp);
            x_pos.push_back(x_tmp);
            y_pos.push_back(y_tmp);
        }

        for(int i = 0; i < index.size(); i++)
            printf("d\t%4.8lf\t%4.8lf\n",index[i], x_pos[i], y_pos[i]);
    } fclose(fid);
}

注意:上面的代码用while(!feof(fid)) 判断文件是否结束有一个问题,就是如果文件是空文件,第一次循环会进去。

feof(fp) 就是判断fp是否已经读取了EOF字符。如果已读取,返回true值,所以在调用feof(fp) 之前,都应该先调用读文件的函数: fgets(ar, 50,fid)、fgetc(fid),然后再判断就OK。

正确使用feof():

#include<stdio.h>
int main(void)
{FILE *p;p = fopen("open.txt", "r");getc(p);if (feof(p)){printf("文件为空。");}else{rewind(p);//将光标跳回到文件开头int a;fscanf(p,"%d",&a);printf("%d", a);}return 0;}

feof():

.html

————————

三:C语言二进制文件读写

1. 写入二进制文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29

 

//采用C模式写二进制文件
void DataWrite_CMode()
{
    //准备数据
    double pos[200];
    for(int i = 0; i < 200; i ++ )
        pos[i] = i ;
    //写出数据 FILE *fid;
    fid = fopen("binary.dat","wb");
    if(fid == NULL)
    {
        printf("写出文件出错");
        return;
    }
    int mode = 1;
    printf("mode为1,逐个写入;mode为2,逐行写入\n");
    scanf("%d",&mode);
    if(1==mode)
    {
        for(int i = 0; i < 200; i++)      fwrite(&pos[i],sizeof(double),1,fid);
    }
    else if(2 == mode)
    {  fwrite(pos, sizeof(double), 200, fid);
    }fclose(fid);
}

---------

2.读取二进制文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43

 

//采用C模式读二进制文件
void DataRead_CMode()
{  FILE *fid;
    fid = fopen("binary.dat","rb");

    if(fid == NULL)
    {
        printf("读取文件出错");
        return;
    }
    int mode = 1;
    printf("mode为1,知道pos有多少个;mode为2,不知道pos有多少个\n");
    scanf("%d",&mode);
    if(1 == mode)
    {
        double pos[200];   fread(pos,sizeof(double),200,fid);
        for(int i = 0; i < 200; i++)
            printf("%lf\n", pos[i]);
        free(pos);
    }
    else if(2 == mode)
    {
        //获取文件大小    fseek (fid , 0 , SEEK_END);       
        long lSize = ftell (fid);    rewind (fid); 
        //开辟存储空间
        int num = lSize/sizeof(double);
        double *pos = (double*) malloc (sizeof(double)*num);  
        if (pos == NULL)  
        {  
            printf("开辟空间出错");   
            return; 
        } 
        fread(pos,sizeof(double),num,fid);
        for(int i = 0; i < num; i++)
            printf("%lf\n", pos[i]);
        free(pos);     //释放内存
    }    fclose(fid);
}

——————

四:C++文本文件读写

1. 写入文本文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24

 

//采用CPP模式写txt

#include <fstream>
void TxtWrite_CPPmode()
{
    //准备数据
    int index[50] ;
    double x_pos[50], y_pos[50];
    for(int i = 0; i < 50; i ++ )
    {
        index[i] = i;
        x_pos[i] = rand()%1000 * 0.01 ;
        y_pos[i] = rand()%2000 * 0.01;
    }
    //写出txt  fstream f("txt_out.txt", ios::out); if(f.bad())  //判断文件打开是否成功,使用is_open()接口,不能使用bad()接口,bad()接口是用来判断读写是否有错。
    {
        cout << "打开文件出错" << endl;
        return;
    }
    for(int i = 0; i < 50; i++)   f << setw(5) << index[i] << "\t" << setw(10) << x_pos[i] <<"\t" <<setw(10)<< y_pos[i] << endl;
    f.close();

}

-----

2.读取文本文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71

 

/采用CPP模式读取txt

#include <fstream>
void TextRead_CPPmode()
{   fstream f;
    f.open("txt_out.txt",ios::in);  

    //文件打开方式选项:
    // ios::in    = 0x01, //供读,文件不存在则创建(ifstream默认的打开方式)
    // ios::out    = 0x02, //供写,文件不存在则创建,若文件已存在则清空原内容(ofstream默认的打开方式)
    // ios::ate    = 0x04, //文件打开时,指针在文件最后。可改变指针的位置,常和in、out联合使用
    // ios::app    = 0x08, //供写,文件不存在则创建,若文件已存在则在原文件内容后写入新的内容,指针位置总在最后
    // ios::trunc   = 0x10, //在读写前先将文件长度截断为0(默认)
    // ios::nocreate = 0x20, //文件不存在时产生错误,常和in或app联合使用
    // ios::noreplace = 0x40, //文件存在时产生错误,常和out联合使用
    // ios::binary  = 0x80  //二进制格式文件
    vector<<span style="color:#8000ff;">int> index;
    vector<<span style="color:#8000ff;">double> x_pos;
    vector<<span style="color:#8000ff;">double> y_pos;  if(!f)
    {
        cout << "打开文件出错" << endl;
        return;
    }
    cout<<"mode为1,按字符读入并输出;mode为2,按行读入输出;mode为3,知道数据格式,按行读入并输出"<<endl;
    int mode = 1;
    cin>>mode;
    if(1== mode)
    {
        //按字节读入并输出
        char ch;   while(EOF != (ch= f.get()))
            cout << ch;

    }
    else if(2 == mode)
    {
        //按行读取,并显示
        char line[128];
        int numBytes;   f.getline(line,128);
        cout << line << "\t" << endl ;
        f.getline(line,128);
        cout << line << "\t" << endl ;
        f.seekg(0,0);                           //跳过字节
        //seekg(绝对位置);      //绝对移动,    //输入流操作
        //seekg(相对位置,参照位置);  //相对操作
        //tellg();                   //返回当前指针位置 while(!f.eof())
        {
            //使用eof()函数检测文件是否读结束
            f.getline(line,128);
            numBytes = f.gcount();      //使用gcount()获得实际读取的字节数
            cout << line << "\t" << numBytes << "字节" << endl ;
        }
    }
    else if(3 == mode)
    {
        //如果知道数据格式,可以直接用>>读入
        int index_temp = 0;
        double x_pos_temp = 0, y_pos_temp = 0;  while(!f.eof())
        {
            f >> index_temp >> x_pos_temp >> y_pos_temp ;
            index.push_back(index_temp);
            x_pos.push_back(x_pos_temp);
            y_pos.push_back(y_pos_temp);
            cout << index_temp << "\t" << x_pos_temp << "\t" << y_pos_temp << endl;
        }
    }  f.close();
}

--

五:C++二进制文件读写

1. 写入二进制文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

 

/采用CPP模式写二进制文件

#include <fstream>void DataWrite_CPPMode()
{
    //准备数据double pos[200];
    for(int i = 0; i < 200; i ++ )
        pos[i] = i ;
    //写出数据   ofstream f("binary.dat",ios::binary);  if(!f)
    {
        cout << "创建文件失败" <<endl;
        return;
    }   f.write((char*)pos, 200*sizeof(double));      //fwrite以char *的方式进行写出,做一个转化
    f.close();

}

--

2.读取二进制文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

 

//采用CPP模式读二进制文件

#include <fstream>
void DataRead_CPPMode()
{
    double pos[200];    ifstream f("binary.dat", ios::binary);
    if(!f)

    {
        cout << "读取文件失败" <<endl;
        return;
    } f.read((char*)pos,200*sizeof(double));
    for(int i = 0; i < 200; i++)
        cout << pos[i] <<endl;  f.close();
}

--

六 总结

1. C语言读写文件均通过FILE指针执行操作,其中文本文件的读写用fprintf,fscanf,二进制文件的读写用fread,fwrite

2. C++读写文件通过fstream、ifstream、ofstream进行操作,文本文件用<< 和 >> 进行读写,二进制文件用read和write进行读写

获取文件大小

获取文件大小这里有两种方法:

方法一

范例:

unsigned long get_file_size(const char *path)  
{  unsigned long filesize = -1;  FILE *fp;  fp = fopen(path, "r");  if(fp == NULL)  return filesize;  fseek(fp, 0L, SEEK_END);  filesize = ftell(fp);  fclose(fp);  return filesize;  
}

此种以打开文件的方法取得文件的大小,不适合大文件,并且可能会出现访问冲突(比如正在下载的文件),效率也比较低

方法二

 范例:

view plain

  1. #include <sys/stat.h>  
  2.   
  3. unsigned long get_file_size(const char *path)  
  4. {  
  5.     unsigned long filesize = -1;      
  6.     struct stat statbuff;  
  7.     if(stat(path, &statbuff) < 0){  
  8.         return filesize;  
  9.     }else{  
  10.         filesize = statbuff.st_size;  
  11.     }  
  12.     return filesize;  
  13. }  

此种使用读取文件属性的方法得到文件的大小,效率较高,也较稳定

用fstream读写文件容易犯的错

系统学习Windows客户端开发

fstream属于C++标准,使用fstream进行文件读写,具有跨平台性。使用过程中要注意几点:

第一,构造函数中指定文件路径时内部会调用open(),如果再次调用open(),调用将会返回失败。

第二,判断文件打开是否成功,使用is_open()接口,不能使用bad()接口,bad()接口是用来判断读写是否有错。

第三,如果文件内容有包含\0,open()时指定fstream::binary标志位进行二进制流的读写。如果写文件希望追加不清除原有内容,open()时指定fstream::app标志位(append的缩写)。

第四,为了计算文件大小,需要先将位置指向结尾,这时要调seekg(0, ios_base::end),而不是seekg(ios_base::end),seekg有两个重载函数,只带一个参数的接口表示相对开始的位置,ios_base::end的值为2,seekg(ios_base::end)表示移到2的位置,而不是文件末尾。

第五,慎用操作符>>和<<读写文件,操作符>>和<<类似于scanf()接口,它是基于字符串格式化输入输出,比如unsigned short x=200, y=300; ofs <<x<<y;文件内容是字符串200300,而不是数值c8002c01,因为操作符<<会先将数值转化为字符串再写入文件。ifs>>x>>y;操作符>>读取x和y时,首先获得字符串200300,再赋值给x,因为x是unsigned short类型最大值为65535,200300超过65535,读取失败。所以某些场景下用操作符<<和>>进行文件读写是不可逆,应该用read(), write()接口读写。

下面代码详细演示fstream的使用及要注意的地方。

#include <string>
#include <fstream>using namespace std;#pragma pack(1)
struct CPoint
{
public:char m_cType = 0;  // 0 down, 1 up, 2 moveunsigned short m_nX = 0;unsigned short m_nY = 0;
};
#pragma pack()int main()
{const std::wstring strFilePath = L"C:\\test.dat";CPoint pt;pt.m_cType = 0;pt.m_nX = 200;pt.m_nY = 300;ofstream ofs(strFilePath.c_str(), fstream::out | fstream::binary);if (ofs.is_open()){// 判断文件打开是否成功,使用is_open()// 不能使用bad(),bad()用来判断读写有没错误// 操作符<<输出整型时,并不是存储数值,而是将数值格式化成字符串后存储,// 此时文件内容第一字节是数值0,然后是字符串200300ofs << pt.m_cType << pt.m_nX << pt.m_nY;ofs.close();}ifstream ifs(strFilePath.c_str(), fstream::in | fstream::binary);if (ifs.is_open()){// 操作符>>输入整型时,会扫描数字串直到非数字为止,// 此时扫描到字符串是200300,然后转化为unsigned short赋值给m_nX,// 因为200300超过unsigned short最大值65535,读取失败CPoint pt2;ifs >> pt2.m_cType >> pt2.m_nX >> pt2.m_nY;printf("x= %d, y = %d\n", pt2.m_nX, pt2.m_nY);  // 输出的值是 0, 0ifs.close();}// 下面是正确代码,使用read(),write()来实现ofstream ofs2(strFilePath.c_str(), fstream::out | fstream::binary);if (ofs2.is_open()){    ofs2.write((const char*)&pt, sizeof(pt));ofs2.close();}ifstream ifs2(strFilePath.c_str(), fstream::in | fstream::binary);if (ifs2.is_open()){CPoint pt2;ifs2.read((char*)&pt2, sizeof(pt2));printf("x= %d, y = %d\n", pt2.m_nX, pt2.m_nY);  // 输出的值是 200, 300ifs2.close();}return 0;
}

更多推荐

【C写文件】C/C++读写文本文件、二进制文件/文件读写

本文发布于:2024-03-23 02:07:59,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1739184.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:文件   文本文件   二进制文件

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!