C++文件的读取详解,以及使用eof出现末行数据被读取两次情况

2023-10-31

目录

0.前言

对文件流的读写

文件打开方式:

1.写文本文件

2.读文本文档

2.1使用efo函数判断出现数据被读取两次

3.二进制方式写文件

4.二进制读文件

 5.按指定格式读写数据stringstream


0.前言

对文件流的读写

   ifstream    对文件输入(读文件)

   ofstream    对文件输出(写文件)

   fstream     对文件输入或输出

文件打开方式:

ios::in

读方式打开文件

ios::out

写方式打开文件

ios::trunc

如果此文件已经存在, 就会打开文件之前把文件长度截断为0

ios::app

尾部最加方式(在尾部写入)

ios::ate

文件打开后, 定位到文件尾   

ios::binary

二进制方式(默认是文本方式)

 以上打开方式, 可以使用位操作 |  组合起来。

1.写文本文件

#include<iostream>
#include<fstream>
#include<sstream>
using namespace std;


int main() {

	ofstream ofs;   //也可以使用fstream ,但是fstream默认打开方式不截断文件长度

    //ofstream 的默认打开方式是截断式写入   ios::out|ios::trunc
    //fstream 的默认打开方式是截断写入   ios::out
    //建议指定打开方式
	ofs.open("temp.txt",ios::out|ios::trunc);
	string name;
	int age;
	while (1) {
		cout << "请输入姓名([ctrl]+z退出):" ;
		cin >> name;
		if (cin.eof()) {
			break;
		}
		cout << "请输入年龄:" ;
		cin >> age;
		stringstream s;
		s << name << '\t' << age<<'\n';
		ofs << s.str();
	}
	ofs.close();




	system("pause");
	return 0;
}

运行截图:

  打开temp.txt文档:

2.读文本文档

#include<iostream>
#include<fstream>
#include<sstream>
using namespace std;


int main() {

	ifstream ifs;
	ifs.open("temp.txt");
	string name;
	int age;
	while (1) {
		if (ifs.eof()) {
			break;
		}
		ifs >> name;
		ifs>> age;
		cout << name << '\t' << age << endl;
	}
	ifs.close();
	cout << line << endl;
	system("pause");
	return 0;
}

运行结果:


 

由运行结果可知,文档的最后一行元素被读取两次,这是为什么呢?

2.1使用efo函数判断出现数据被读取两次

在使用C/C++读文件的时候,一定都使用过eof()这个函数来判断文件是否为空或者是否读到文件结尾了,大家可能有一个误区,认为eof()返回true时是读到文件的最后一个字符,其实不然,eof()返回true时是读到文件结束符0xFF,而文件结束符是最后一个字符的下一个字符。

 这就是在判断文档是否为空时要先用char读取,再使用eof函数。

解决方法:
1.提前读取,再进行判断(注意要使用string类型读取)

#include<iostream>
#include<fstream>
#include<sstream>
using namespace std;


int main() {
	ifstream ifs;
	ifs.open("temp.txt");
	string name;
	int age;
	int line = 0;
	while (1) {
		ifs >> name;
		if (ifs.eof()) {
			break;
		}
		ifs>> age;
		cout << name << '\t' << age << endl;
	}
	ifs.close();
	system("pause");
	return 0;
}

 运行结果:

3.二进制方式写文件

#include<fstream>
#include<iostream>
using namespace std;

int main()
{
	string name ;
	int age ;
	ofstream ofs;
	//.dat文件用记事本打开会是乱码
	ofs.open("user.dat", ios::out | ios::trunc | ios::binary);

	while (1) {
		cout << "请输入姓名([ctrl]+z退出):";
		cin >> name;
		if (cin.eof()) {
			break;
		}
		cout << "请输入年龄:";
		cin >> age;
		ofs << name << "\t";
		//outfile << age << endl;  //会自动转成文本(字符串)方式写入

		ofs.write((char*)&age, sizeof(age)); //将age的地址转为char指针类型
	}
	ofs.close();



	// 关闭打开的文件
	ofs.close();

	system("pause");
	return 0;
}

 使用notepad++查看运行后的二进制文件:

4.二进制读文件

#include <fstream>
#include <iostream>
#include <string>

using namespace std;

int main()
{
	string name;
	int age;

    //ifs>>age;  temp是二进制存储,直接读取会以文本方式读出
    //使用read读取会读取空格符\制表符.....
    //ifs.read((char*)&age,sizeof(age));   
	ifstream ifs;
	ifs.open("user.dat", ios::in | ios::binary);
	while (1) {
		ifs >> name;
		if (ifs.eof()) { //判断文件是否结束
			break;
		}
		cout << name << "\t";

		// 跳过中间的制表符
		char tmp;
		ifs.read(&tmp, sizeof(tmp));

		//infile >> age; //从文本文件中读取整数, 使用这个方式
		ifs.read((char*)&age, sizeof(age));
		cout << age << endl;  //文本文件写入
	}

	// 关闭打开的文件
	ifs.close();

	system("pause");
	return 0;
}

运行结果:

 5.按指定格式读写数据stringstream

#include<fstream>
#include<string>
#include<iostream>
#include<sstream>
using namespace std;

//按指定格式写文件
void funWrite() {
    string name = "凌云志";
    int age =18;
    ofstream ofs;
    ofs.open("temp.txt");
    stringstream s;
    s << "姓名:" << name << "\t\t年龄:" << age << endl;

    //把指定格式数据写入文件
    ofs << s.str();

    ofs.close();

}

//按指定格式读文件
void funRead() {
    ifstream ifs;
    ifs.open("temp.txt");
    string line;

    char name[32];
    int age;
    while (1) {
        getline(ifs, line);     //每次读取一行
        if (ifs.eof()) { break; }
        //按C语言格式将读取的一行转为char*数组格式(line.c_str())
        //注意文档中的“:”冒号是中文还是英文
        sscanf_s(line.c_str(), "姓名:%s 年龄:%d", name, sizeof(name), &age);
        cout << "姓名:" << name << "\t\t年龄:" << age << endl;
    }
    ifs.close();
}

int main() {



    funWrite();
    funRead();
    system("pause");
    return 0;

}

运行结果以及文档截图:

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

C++文件的读取详解,以及使用eof出现末行数据被读取两次情况 的相关文章

  • 具有相同参数类型但具有不同常量限定符的 std::vector 的转换

    问题很简单 静态转换 或其他一些转换 通常是安全的 std vector lt Foo gt to std vector lt const Foo gt 就二进制而言 我不明白为什么本机类型会有所不同 毕竟const是一种语言约束 不应影响
  • 生成多个随机数

    我想生成 25 个唯一的随机数并将它们列在控制台中 数字的长度应至少为 10 个字符 有什么简单的方法可以做到这一点吗 尝试将数字构建为字符串 并使用 HashSet 确保它们是唯一的 Random random new Random Ha
  • ASP.NET Web 应用程序中的身份验证遇到问题

    我正在尝试对从登录页面登录我的 Web 应用程序的用户进行身份验证 我正在使用本教程 http support microsoft com kb 301240作为指南 它几乎准确地解释了我希望做什么 但是当我输入用户名和密码时 验证不起作用
  • 深拷贝和动态转换 unique_ptr

    假设我有一个如下所示的类 class A virtual A class B public A class C public A 我还有一个 unique ptr 向量 它是这样声明的 std vector
  • 使用 C# 将多个音频样本混合到单个文件中

    Closed 此问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 我正在寻找一个能够创建音频文件 mp3 或 wav 的库 NAudio http www codeple
  • 如何从 Qt 应用程序通过 ODBC 连接到 MySQL 数据库?

    我有一个新安装的 MySQL 服务器 它监听 localhost 3306 从 Qt 应用程序连接到它的正确方法是什么 原来我需要将MySQL添加到ODBC数据源 我在遵循这个视频教程后做到了这一点 https youtu be K3GZi
  • Monotouch全局异常处理

    我在野外发现了一只令人讨厌的虫子 但我无法确定它的具体情况 有没有办法拥有全局 Try Catch 块 或者有办法处理 Monotouch 中未处理的任何异常 我可以包起来吗UIApplication Main args 在 try cat
  • 无法加载程序集问题

    我收到以下错误 无法加载程序集 错误详细信息 System BadImageFormatException 无法加载文件或程序集 文件 或其依赖项之一 该程序集是由比当前加载的运行时更新的运行时构建的 无法加载 该程序集是使用 Net Fr
  • opencv中如何去除二值图像噪声?

    将图像转换为二值图像 黑白 后如果有任何噪音怎么办 我消除了那些不需要的噪音 您可以看到下图的黑色区域内有一些白噪声 我该如何去除噪声 使用opencv http img857 imageshack us img857 999 blackn
  • 如何减少 MinGW g++ 编译器生成的可执行文件的大小?

    我有一个简单的 Hello world C 程序 在 Win XP 下由 MinGW g 编译器编译为 500kB 可执行文件 有人说这是由于iostream的库和静态链接libstdc dll Using s链接器选项有点帮助 减少了 5
  • 如何将STL容器数据转储到gdb中?

    我无法在 gdb 中转储 STL 无序映射容器值 变量类型是 std unordered map var 我的 gdb 版本 7 7 1 GDB配置 configure host x86 64 linux gnu target x86 64
  • 处理“未找到细胞”。 Excel 中的错误

    我正在使用 Excel VSTO 应用程序并使用以下代码在工作表中查找错误单元格 Excel Range rngTemp Excel Range rngErrorRange Excel Worksheet Sheet1 Excel Work
  • 配置:错误:无法运行C编译的程序

    我正在尝试使用 Debian Wheezy 操作系统在我的 Raspberry Pi 上安装不同的软件 当我运行尝试配置软件时 我尝试安装我得到此输出 checking for C compiler default output file
  • DataGridView 行背景颜色没有改变

    我想根据加载时的特定条件更改 DGV 行的背景颜色 即使在 Windows 窗体中也是如此 但我看不到任何 DGV 行的颜色有任何变化 谁能告诉我如何解决这个问题 private void frmSecondaryPumps Load ob
  • 从 DataRow 单元格解析 int [关闭]

    Closed 这个问题是基于意见的 help closed questions 目前不接受答案 如何从 DataRow 单元格解析 int 值 Int32 Parse item QuestionId ToString 这段代码可以工作 但看
  • 选择合适的IDE

    您会推荐使用以下哪种 IDE 语言来在 Windows 下开发涉及识别手势并与操作系统交互的项目 我将使用 OpenCV 库来执行图像处理任务 之后 我将使用 win32 API 或 NET 框架与操作系统交互 具体取决于您建议的工具 性能
  • 连接到没有元数据的网络服务

    我想连接到此网络服务 https training api temando com schema 2009 06 server wsdl https training api temando com schema 2009 06 serve
  • 具有四个 && 的 LINQ Where 子句

    我正在尝试在Where 子句中创建一个带有4 个参数的LINQ 查询 这是一个 Windows 8 应用程序项目 我正在使用 SQLite 数据库 SQLite 实现 https github com praeclarum sqlite n
  • 使用 CodeDOM 将程序集添加到 BuildManager 会导致间歇性错误

    我正在使用 CodeDOM 在运行时创建内存中程序集 如下所示 public Assembly Compile CodeCompileUnit targetUnit string path Path GetDirectoryName new
  • 实体框架代码首次日期字段创建

    我正在使用实体框架代码优先方法来创建我的数据库表 下面的代码 创建一个DATETIME数据库中的列 但我想创建一个DATE柱子 DataType DataType Date DisplayFormatAttribute ApplyForma

随机推荐

  • springboot+mybatis+druid+postgreSql案例

    springboot mybatis druid postgreSql mysql 示例 springboot mybatis druid postgreSql mysql 示例 简介 结构解析 代码剖析 entity层 Dao层 serv
  • Java-System、Math、BigInteger、BigDecimal常用类的使用

    Java System Math BigInteger BigDecimal常用类的使用 1 System类 System类代表系统 系统级的很多属性和控制方法都放置在该类的内部 该类位于java lang包 由于该类的构造器是privat
  • 解决Linux7 ping出现 未知的名称或服务 错误

    问题描述 Linux7在利用命令nmtui进入图形化界面配置Linux的网络后为测试是否成功联网 ping配置的IP成功但ping如www baidu com常见网站时出现 gt ping www baidu com 未知的名称或服务 解决
  • 网络编程知识预备(5) ——libcurl库安装及其编程访问百度首页(断点续传)

    本文为学习笔记 整合课程内容以及下列文章 其中 libcurl函数库常用字段解读部分 参考博文 原文地址 作者 冬冬他哥哥 目录 Libcurl库简介 Libcurl等三方库的通用编译方法 三方库使用前通读方法 库的配置 编译 安装 调用l
  • protobuf生成prototxt文件

    使用protobuf可以分为以下几步 1 proto文件的定义 在这个文件中定义了最终生成的prototxt格式 举个例子如下所示 syntax proto2 package label proto message DetectLabel
  • scrapy缺点

    Scrapy 是一个功能强大的网络爬虫框架 但也有一些缺点 Scrapy 只能爬取静态网页 无法爬取动态网页 Scrapy 只能爬取一个网站的数据 无法爬取多个网站的数据 Scrapy 需要编写代码 对于那些不会编写代码的人来说可能会有些困
  • LiteOS内存管理

    1 内存管理简介 内存管理模块管理系统的内存资源 它是操作系统的核心模块之一 主要包括内存的初始化 分配以及释放 在系统运行过程中 内存管理模块通过对内存的申请 释放操作 来管理用户和OS对内存的使用 使内存的利用率和使用效率达到最优 同时
  • obs无法连接服务器?PotPlayer获取不到视频

    搭建基于nginx的rtmp直播服务器 https hywlovexyc info blog archives 572 rtmp server listen 1935 监听的端口 chunk size 4000 application yu
  • 删除中间节点

    题目 若链表中的某个节点 既不是链表头节点 也不是链表尾节点 则称其为该链表的 中间节点 假定已知链表的某一个中间节点 请实现一种算法 将该节点从链表中删除 例如 传入节点 c 位于单向链表 a gt b gt c gt d gt e gt
  • sqlserver查看数据表结构

    可以通过两种方式 1 sp help 表名 2 sp columns 表名
  • 我的世界服务器config文档,Essentials/配置文件/config.yml

    ops name color none nickname prefix max nick length 15 change displayname true change playerlist true add prefix suffix
  • Unity--虚拟轴

    1 查看虚拟轴 Edit gt project settings gt Input 2 获取虚拟轴 input GetAxis 用法 GetAxis Mouse X GetAxis Mouse Y GetAxis Mouse ScrollW
  • centos7Linux中的lvm、pv、vg、lv,以及Linux扩容,创建新分区

    概念 本着言简意赅的目的 以下概念会在扩容时用到 需熟知 不然会不理解具体操作在干什么 lvm 逻辑卷管理器 Logical Volume Manager 它使系统管理员可以更方便的为应用与用户分配存储空间 在LVM管理下的存储卷可以按需要
  • QT信号槽原理(一)connect函数

    目录 2个类型和1个签名 Qt ConnectionType QMetaMethod MethodType 方法签名 connect函数源码解析 函数原型 第一步 参数检查 第二步 获取信号和槽的index 第三步 检查信号和槽的参数是否匹
  • Opencv之图像固定阈值二值化处理threshold

    目录 一 图像二值化 二 threshold 三 代码 一 图像二值化 定义 图像的二值化 就是将图像上的像素点的灰度值设置为0或255 也就是将整个图像呈现出明显的只有黑和白的视觉效果 灰度值0 黑 灰度值255 白 一幅图像包括目标物体
  • Cygwin编译JNI的环境配置

    一 什么是NDK NDK提供了一系列的工具 帮助开发者快速开发C 或C 的动态库 并能自动将so和java应用一起打包成apk 这些工具对开发者的帮助是巨大的 NDK 集成了交叉编译器 并提供了相应的mk文件隔离CPU 平台 ABI 等差异
  • MacBook怎么安装使用Windows软件和虚拟机?

    作为一名MacBook用户 你可能会发现有些软件和应用程序只适用于Windows操作系统 但别担心 今天我们将介绍两种方法 让你的MacBook轻松安装Windows软件和运行Windows虚拟机 为你的工作 学习和娱乐任务带来更多可能性
  • Vue 3 使用 vue-echarts 的柱状图 barItem 和 x, y 轴点击事件实现

    需求背景 最近使用 Vue 3 开发柱状图功能 图表已经绘制完成了 但是突然有需求加进来要可以点击柱状图的柱子 barItem 和 x y 轴的坐标 然后根据点击的位置 处理不同区域的点击事件 作为 CV 程序员 第一时间搜索网上的解决方案
  • 抖音养号步骤有哪些?最重要的3步你做到了吗?

    国仁网络资讯 为大家整理一份超详细的 短视频运营手册 回复私信限时免费领取 有人问我 新手养号怎么养 老账号养号要怎么养 其实 严格来说 养号不分新老 不管你是刚注册的抖音号 还是已经用过很久的抖音号 养号都是运营账号必做的事项之一 那么
  • C++文件的读取详解,以及使用eof出现末行数据被读取两次情况

    目录 0 前言 对文件流的读写 文件打开方式 1 写文本文件 2 读文本文档 2 1使用efo函数判断出现数据被读取两次 3 二进制方式写文件 4 二进制读文件 5 按指定格式读写数据stringstream 0 前言 对文件流的读写 if