C++流操作之fstream
在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++流操作之fstream的更多相关文章
- ndk学习之c++语言基础复习----C++容器、类型转换、异常与文件流操作
继续来复习C++,比较枯燥,但是这是扎实掌握NDK开发的必经之路,不容小觑. 容器: 容器,就是用来存放东西的盒子. 常用的数据结构包括:数组array, 链表list, 树tree, 栈stack, ...
- Node学习笔记(一):stream流操作
NodeJs中谈及较多的可能就是Stream模块了,先写一个简单的ajax回调 $.post("index.php",{data:'aaa',order:'ccc'},functi ...
- [WCF编程]10.操作:流操作
一.流操作概述 在默认情况下,当客户端调用服务时,服务只有在接收到完整的消息后才会被调用,同样,客户端只有在包含了调用结果的返回消息被完整接受时,才会解除对它的阻塞. 对于数据量小的消息,这种交换模式 ...
- io流操作大全
JAVA 中的IO流 一.流的概念 流(stream)的概念源于UNIX中管道(pipe)的概念.在UNIX中,管道是一条不间断的字节流,用来实现程序或进程间的通信,或读写外围设备.外部 ...
- Stream 流操作
Stream 类 先看下面的图 Stream 是所有流的抽象基类(不能被实例化,需要使用他的派生类FileStream/MemoryStream/BufferedStream).流是字节序列的抽象概 ...
- delphi 基础之三 文件流操作
文件流操作 Delphi操作流文件:什么是流?流,简单来说就是建立在面向对象基础上的一种抽象的处理数据的工具.在流中,定义了一些处理数据的基本操作,如读取数据,写入数据等,程序员是对流进行所有操作的, ...
- IOS文件操作的两种方式:NSFileManager操作和流操作
1.常见的NSFileManager文件方法 -(NSData *)contentsAtPath:path //从一个文件读取数据 -(BOOL)createFileAtPath: path cont ...
- Java基础---IO(一)---IO流概述、字符流、字节流、流操作规律
第一讲 IO概述 概述 1.IO流:即InputOutput的缩写. 2.特点: 1)IO流用来处理设备间的数据传输. 2)Java对数据的操作是通过流的方式. 3)Java用于操作流的对象都 ...
- JAVA之旅(二十七)——字节流的缓冲区,拷贝mp3,自定义字节流缓冲区,读取键盘录入,转换流InputStreamReader,写入转换流,流操作的规律
JAVA之旅(二十七)--字节流的缓冲区,拷贝mp3,自定义字节流缓冲区,读取键盘录入,转换流InputStreamReader,写入转换流,流操作的规律 我们继续来聊聊I/O 一.字节流的缓冲区 这 ...
随机推荐
- XML新手入门 创建构造良好的XML(1)
XML新手入门 创建构造良好的XML(1) 2009-03-19 09:24 Kay Whatley IBM Developerworks 我要评论(0) 字号:T | T 本文描述了构建良好的XML ...
- 自动化高效css开发,畅谈less的灵活变化
css是一种让html与样式分离解析而出现的代码,它的出现大大提高了程序员的工作效率,和后期进行维护的效率.但是发展至今,由于起死板单调的写法,越来越不能满足程序员们灵活的思维,很多时候是种恨铁不成钢 ...
- CKfinder中文乱码的解决.
最近在写一个类似博客的系统,使用了ckeditor和ckfinder,但是发现ckfinder在上传中文文件名的文件过程中会出现中文乱码的情况. 于是百度google乎,发现大多数的解决办法都是将文件 ...
- win7 PHP7.0的PDO扩展
一个非常棘手的问题,win7(64位)环境,编译安装的mysql,php无法使用pdo扩展. 而我的centos中yum安装的php,pdo是好用的. 百度了一大堆,都无法解决. 基本上百度到的都是要 ...
- ASP.NET MVC5+ORACLE 身份认证
菜鸟来的,刚接触mvc,看到mvc5上默认带有identity身份验证的东西,公司用的oracle数据库,便想着东西能不能支持oracle数据库,折腾了半天弄出下面的东西来,有些东西可能不太准确,望大 ...
- 一步一步学python(三) - 使用字符串
1.基本字符串操作 序列和元组的索引.分片.乘法.判断成员资格.求长度.取最小值和最大值对字符串同样适用. 字符串是不可变的 2.字符串格式化 %左侧放字符串右侧放格式化的值.一般情况下使用元组 fo ...
- vs2005的MFC程序在64位机上不能运行
出现上述错误大多因为该机上没有安装vs2005程序,vs2005要运行需要一些必要的文件,没有添加到你发布的可执行文件目录下,所以程序不能运行. 解决方法: 安装目录\Microsoft Visual ...
- ZigBee 技术简介
Zigbee是IEEE 802.15.4协议的代名词.根据这个协议规定的技术是一种短距离.低功耗的无线通信技术.这一名称来源于蜜蜂的八字舞,由于蜜蜂(bee)是靠飞翔和“嗡嗡”(zig)地抖动翅 ...
- linux服务器开发浅谈
[开发前准备] 在进行linux服务器开发之前,必须很清楚地了解所开发的对象需要考虑的相关问题比如:功能架构:提供服务的模块体系结构稳定性:服务器的出core率,内存泄露情况性能:请求与返回的速度与正 ...
- JQuery弹出窗口小插件ColorBox
本文来自: Small_陌 http://www.cnblogs.com/wggmqj/archive/2011/11/04/2236263.html 今天在博客园看到一篇<ASP.NET MV ...