C++流操作之fstream用法介绍

所属分类: 软件编程 / C 语言 阅读数: 64
收藏 0 赞 0 分享

在Windows平台对文件进行存取操作可选的方案有很多,如果采用纯C,则需要用到File*等,当然也可以直接调用Windows API来做;如果采用C++,首先想到的就是文件流fstream。虽然在COM层面上,我们还可以使用IStream来实现文件的读写,其效率也非常高。不过本文仅对C++流操作做简单的探讨,相比于Windows API或IStream,C++的流操作通用性更好一些,因为你能轻松将代码移植到其它平台上。

fstream有两个派生类,即ifstream和ofstream,分别对应输入文件流、输出文件流。在使用它们之前,必须将它们的头文件包含到你的cpp文件中。

创建一个文件流的方法很简单:

ifstream fin; 
fin.open("C:\filename.txt"); 
这样就创建了一个输入文件流fin,它对应的文件是C盘根目录下的filename.txt。实际上,open方法还包含一个参数mode,用以指定其打开方式。
ios::in 以读取方式打开文件
ios::out 以写入方式打开文件
ios::ate 存取指针在文件末尾
ios::app 写入时采用追加方式
ios::trunc 写入时抹去旧数据
ios::binary 以二进制方式存取
上面的代码并未指定任何打开方式,则采用默认参数:输入文件流即ios::in,输出文件流即ios::out。一般在需要组合特殊的mode才显式指定,比如:
ios::in | ios::binary; //以二进制方式读取文件

除此之外,还可以在构造时指定相应的文件路径和名称,让创建过程一步到位。上述代码可改写为:

ifstream fin("C:\filename.txt");
与open方法相反的是close方法,它的作用与open正好相反。open是将文件流对象与外设中的文件关联起来,close则是解除二者的关联。但是需要注意的是,close还起到清空缓存的作用。最好让open方法与close方法成对出现。

创建并打开一个文件流后,就能像操作标准I/O那样使用流插入操作符(<<)与流提取操作符(>>)。对于输入文件流来说,可以调用getline函数从文件流中读取一整行数据,这样就可以读入含有空格的字符串。

下面是一个例子,该例的作用是读取一个STLA格式的文件。STL是一种常用快速成像文件格式,其格式非常简单,特别是ASCII版本(即STLA)。代码如下所示:

stdafx.h

复制代码 代码如下:

// stdafx.h : include file for standard system include files, 
// or project specific include files that are used frequently, but 
// are changed infrequently 
// 

#pragma once 

#include "targetver.h" 

#include <stdio.h> 
#include <tchar.h> 
//added 
#include <iostream> 
#include <sstream> 
#include <fstream> 
#include <string> 
#include <vector> 
using namespace std; 

// TODO: reference additional headers your program requires here 
readstla.cpp

// readstla.cpp : Defines the entry point for the console application. 
// 

#include "stdafx.h" 

struct facet { 
    float normal[3]; 
    float vertex[3][3]; 
}; 

int _tmain(int argc, _TCHAR* argv[]) 

    if (argc < 2) { 
        printf("specify an input file!\n"); 
        return 1; 
    } 
    ifstream in(argv[1]); 
    if (!in.is_open()) { 
        printf("fail to open file!\n"); 
        return 1; 
    } 
    //var 
    vector<facet> solid; 
    string line; 
    string word; 
    //check format 
    getline(in, line); 
    if (line.find("solid") != 0) { 
        printf("wrong file format!\n"); 
        in.close(); 
        return 1; 
    } 
    while (getline(in, line)) { 
        if (line.find("facet normal") != string::npos) { 
            facet f; 
            //read normal 
            stringstream ns(line); 
            ns >> word; //eat "facet" 
            ns >> word; //eat "normal" 
            ns >> f.normal[0] >> f.normal[1] >> f.normal[2]; 
            //read vertices 
            getline(in, line); //"outer loop" 
            for (int i = 0; i < 3; i++) { 
                getline(in, line); 
                stringstream vs(line); 
                vs >> word; //eat "vertex" 
                vs >> f.vertex[i][0] >> f.vertex[i][1] >> f.vertex[i][2]; 
            } 
            getline(in, line); //"endloop" 
            getline(in, line); //"endfacet" 
            solid.push_back(f); 
        } 
    } 
    in.close(); 
    //output 
    int cnt = solid.size(); 
    printf("read %d facet\n", cnt); 
    for (int i = 0; i < cnt; i++) { 
        facet& f = solid[i]; 
        printf("\nfacet %d:\nnormal = (%f, %f, %f)\n", \ 
                       i+1, f.normal[0], f.normal[1], f.normal[2]); 
        for (int j = 0; j < 3; j++) { 
            printf("vertex[%d] = (%f, %f, %f)\n", \ 
                              j+1, f.vertex[j][0], f.vertex[j][1], f.vertex[j][2]); 
        } 
    } 
    return 0; 
}

测试文件为:
cube_corner.stl
复制代码 代码如下:


solid cube_corner 
  facet normal 0.0 -1.0 0.0 
    outer loop 
      vertex 0.0 0.0 0.0 
      vertex 1.0 0.0 0.0 
      vertex 0.0 0.0 1.0 
    endloop 
  endfacet 
  facet normal 0.0 0.0 -1.0 
    outer loop 
      vertex 0.0 0.0 0.0 
      vertex 0.0 1.0 0.0 
      vertex 1.0 0.0 0.0 
    endloop 
  endfacet 
  facet normal 0.0 0.0 -1.0 
    outer loop 
      vertex 0.0 0.0 0.0 
      vertex 0.0 0.0 1.0 
      vertex 0.0 1.0 0.0 
    endloop 
  endfacet 
  facet normal 0.577 0.577 0.577 
    outer loop 
      vertex 1.0 0.0 0.0 
      vertex 0.0 1.0 0.0 
      vertex 0.0 0.0 1.0 
    endloop 
  endfacet 
endsolid 

输入结果为:

read 4 facet 

facet 1: 

normal = (0.000000, -1.000000, 0.000000) 
vertex[1] = (0.000000, 0.000000, 0.000000) 
vertex[2] = (1.000000, 0.000000, 0.000000) 
vertex[3] = (0.000000, 0.000000, 1.000000) 

facet 2: 

normal = (0.000000, 0.000000, -1.000000) 
vertex[1] = (0.000000, 0.000000, 0.000000) 
vertex[2] = (0.000000, 1.000000, 0.000000) 
vertex[3] = (1.000000, 0.000000, 0.000000) 

facet 3: 
normal = (0.000000, 0.000000, -1.000000) 
vertex[1] = (0.000000, 0.000000, 0.000000) 
vertex[2] = (0.000000, 0.000000, 1.000000) 
vertex[3] = (0.000000, 1.000000, 0.000000) 

facet 4: 
normal = (0.577000, 0.577000, 0.577000) 
vertex[1] = (1.000000, 0.000000, 0.000000) 
vertex[2] = (0.000000, 1.000000, 0.000000) 
vertex[3] = (0.000000, 0.000000, 1.000000) 
Press any key to continue . . . 

更多精彩内容其他人还在看

C++广播通信实例

这篇文章主要介绍了C++实现广播通信的方法,实例讲述了C++ socket广播通信的原理与实现方法,需要的朋友可以参考下
收藏 0 赞 0 分享

C++计算ICMP头的校验和实例

这篇文章主要介绍了C++计算ICMP头的校验和的方法,代码简单实用,对于校验ICMP报文来说有不错的实用价值,需要的朋友可以参考下
收藏 0 赞 0 分享

C++设置超时时间的简单实现方法

这篇文章主要介绍了C++设置超时时间的简单实现方法,涉及系统函数setsockopt对套接口的操作,具有一定的实用价值,需要的朋友可以参考下
收藏 0 赞 0 分享

C++实现ping程序实例

这篇文章主要介绍了C++实现ping程序实例,涉及C++对于ICMP数据包的发送与回显处理,具有一定的实用价值,需要的朋友可以参考下
收藏 0 赞 0 分享

C++之boost::array的用法

这篇文章主要介绍了C++之boost::array的用法,以实例的形式简单讲述了静态数组的容器boost::array的使用技巧,具有一定的参考借鉴价值,需要的朋友可以参考下
收藏 0 赞 0 分享

C++之Boost::array用法简介

这篇文章主要介绍了C++之Boost::array用法简介,较为详细的分析了Boost::array中的常见用法,并用实例的形式予以总结归纳,需要的朋友可以参考下
收藏 0 赞 0 分享

VC文件目录常见操作实例汇总

这篇文章主要介绍了VC文件目录常见操作实例汇总,总结了VC针对文件目录的各种常用操作,非常具有实用价值,需要的朋友可以参考下
收藏 0 赞 0 分享

VC打印word,excel文本文件的方法

这篇文章主要介绍了VC打印word,excel文本文件的方法,是VC操作文本文件中非常实用的技巧,需要的朋友可以参考下
收藏 0 赞 0 分享

VC++获得当前进程运行目录的方法

这篇文章主要介绍了VC++获得当前进程运行目录的方法,可通过系统函数实现该功能,是非常实用的技巧,需要的朋友可以参考下
收藏 0 赞 0 分享

VC中SendMessage和PostMessage的区别

这篇文章主要介绍了VC中SendMessage和PostMessage的区别,较为全面的分析了SendMessage和PostMessage运行原理及用法上的不同之处,非常具有实用价值,需要的朋友可以参考下
收藏 0 赞 0 分享
查看更多