c++文件流

概述

定义:

文件流是 C++ 中用于处理文件输入 / 输出(I/O)操作的一种抽象概念。它将文件视为字节序列的源(输入)或目标(输出),并提供了一系列的方法来读取和写入这些字节。文件流可以看作是连接程序和外部文件的通道,通过这个通道,程序可以从文件中获取数据(类似于从文件这个 “数据源” 中 “抽取” 数据),或者将数据存储到文件中(类似于将数据 “注入” 到文件这个 “存储库”)。

类型:

文件流类型
类型功能
输入文件流:ifstream读数据
输出文件流:ofstream写数据
文件流:fstream读写数据

函数

基础函数

// 输出文件流(打开文件写入)
 ofstream outFile(fileName, ios::app);//以追加写入方式
 ofstream outFile(fileName, ios::out);//清空文件再写入
 ofstream outFile(fileName, ios::out|ios::binary);//清空文件再写入(以二进制写入)

//输入文件流(打开文件读取)
ifstream inFile;
inFile.open("文件名");//打开文件


//读取或写入方式
file.get(char);//读取一个字符到char中
getline(inFile, tempString);//读取一行到char中



//其他函数
file.open("文件名");//打开文件
file.close();//关闭文件
file.is_open()//判断文件是否被打开
file.eof()//检查是否已经到达文件末尾,若到达则返回1

 输入文件流的常用函数

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

int main() {
    std::ifstream file;
    // 1. 打开文件
    file.open("example.txt", std::ios::in);
    if (!file.is_open()) {
        std::cerr << "无法打开文件 example.txt" << std::endl;
        return 1;
    }

    // 2. 读取一个字符
    char firstChar = file.get();
    std::cout << "读取的第一个字符是: " << firstChar << std::endl;

    // 3. 忽略接下来的 5 个字符
    file.ignore(5);
    std::cout << "忽略了接下来的 5 个字符" << std::endl;

    // 4. 查看下一个字符但不读取
    char nextChar = file.peek();
    std::cout << "下一个字符是: " << nextChar << std::endl;

    // 5. 读取一行数据
    char buffer[100];
    file.getline(buffer, 100);
    std::cout << "读取的一行数据是: " << buffer << std::endl;

    // 6. 读取 20 个字节的数据
    char data[20];
    file.read(data, 20);
    std::cout << "读取的 20 个字节数据是: " << data << std::endl;

    // 7. 输出当前读取位置
    std::streampos currentPos = file.tellg();
    std::cout << "当前读取位置: " << currentPos << std::endl;

    // 8. 将读取位置向前移动 10 个字节
    file.seekg(-10, std::ios::cur);
    std::cout << "将读取位置向前移动 10 个字节" << std::endl;

    // 9. 再次读取一个字符
    char anotherChar = file.get();
    std::cout << "移动位置后读取的字符是: " << anotherChar << std::endl;

    // 10. 检查是否到达文件末尾
    if (file.eof()) {
        std::cout << "已到达文件末尾" << std::endl;
    } else {
        std::cout << "未到达文件末尾" << std::endl;
    }

    // 11. 检查文件流状态是否正常
    if (file.good()) {
        std::cout << "文件流状态正常" << std::endl;
    } else {
        std::cout << "文件流状态异常" << std::endl;
    }

    // 12. 检查是否发生读取失败或其他错误
    if (file.fail()) {
        std::cerr << "读取失败或其他错误发生" << std::endl;
    }

    // 13. 检查是否发生严重错误
    if (file.bad()) {
        std::cerr << "发生严重错误" << std::endl;
    }

    // 14. 清除文件流状态标志
    file.clear();
    std::cout << "清除文件流状态标志" << std::endl;

    // 15. 关闭文件
    file.close();

    return 0;
}

 输出文件流的常用函数

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

int main() {
    std::ofstream file;
    // 1. 打开文件
    file.open("output.txt", std::ios::out | std::ios::app);
    if (!file.is_open()) {
        std::cerr << "无法打开文件 output.txt" << std::endl;
        return 1;
    }

    // 2. 写入一个字符
    char ch = 'A';
    file.put(ch);
    std::cout << "写入一个字符: " << ch << std::endl;

    // 3. 写入一个字符串
    std::string str = "Hello, World!";
    file.write(str.c_str(), str.length());
    std::cout << "写入一个字符串: " << str << std::endl;

    // 4. 刷新文件缓冲区
    file.flush();
    std::cout << "刷新文件缓冲区" << std::endl;

    // 5. 输出当前写入位置
    std::streampos currentPos = file.tellp();
    std::cout << "当前写入位置: " << currentPos << std::endl;

    // 6. 将写入位置向后移动 5 个字节
    file.seekp(5, std::ios::cur);
    std::cout << "将写入位置向后移动 5 个字节" << std::endl;

    // 7. 再次写入一个字符
    char anotherChar = 'B';
    file.put(anotherChar);
    std::cout << "移动位置后写入的字符是: " << anotherChar << std::endl;

    // 8. 检查文件流状态是否正常
    if (file.good()) {
        std::cout << "文件流状态正常" << std::endl;
    } else {
        std::cout << "文件流状态异常" << std::endl;
    }

    // 9. 检查是否发生写入失败或其他错误
    if (file.fail()) {
        std::cerr << "写入失败或其他错误发生" << std::endl;
    }

    // 10. 检查是否发生严重错误
    if (file.bad()) {
        std::cerr << "发生严重错误" << std::endl;
    }

    // 11. 清除文件流状态标志
    file.clear();
    std::cout << "清除文件流状态标志" << std::endl;

    // 12. 关闭文件
    file.close();

    return 0;
}

例子

1.打开文件读取并打印

    string tempchars;
	ifstream ifsProgream;
	ifsProgream.open("F:/caozuoxitong/chuliqidiaodu/document/progream.txt");
	while (ifsProgream >> tempchars)
	{		
			cout << tempchars << endl;
	}

 2.返回


vector<unsigned char> FileModule::ReadFileBinary(string FileName)
{
    vector<unsigned char> buffer;
    ifstream inFile(FileName,ios::binary);
    if(!inFile.is_open())
    {
        cout << "打开文件失败" << endl;
        return buffer;
    }
    else
    {   //获取文件大小       
        streampos fileSize =GetFileSize(FileName);   
        buffer.resize(fileSize);      
        inFile.read(reinterpret_cast<char *>(buffer.data()),fileSize);
        inFile.close();     
    }
    return buffer;
}

 输入输出文件流常用函数

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

int main() {
    std::fstream inFile;
    std::fstream outFile;

    // 1. 打开输入文件
    inFile.open("input.txt", std::ios::in);
    if (!inFile.is_open()) {
        std::cerr << "无法打开输入文件 input.txt" << std::endl;
        return 1;
    }

    // 2. 打开输出文件
    outFile.open("output.txt", std::ios::out | std::ios::trunc);
    if (!outFile.is_open()) {
        std::cerr << "无法打开输出文件 output.txt" << std::endl;
        inFile.close();
        return 1;
    }

    // 3. 读取一行数据
    char buffer[100];
    inFile.getline(buffer, 100);
    std::cout << "从输入文件读取的一行数据是: " << buffer << std::endl;

    // 4. 对读取的数据进行处理,例如将字符全部转换为大写
    for (int i = 0; i < strlen(buffer); ++i) {
        if (buffer[i] >= 'a' && buffer[i] <= 'z') {
            buffer[i] = buffer[i] - 'a' + 'A';
        }
    }
    std::cout << "处理后的数据是: " << buffer << std::endl;

    // 5. 将处理后的数据写入输出文件
    outFile.write(buffer, strlen(buffer));
    std::cout << "将处理后的数据写入输出文件" << std::endl;

    // 6. 检查输入文件是否到达末尾
    if (inFile.eof()) {
        std::cout << "输入文件已到达末尾" << std::endl;
    }

    // 7. 读取一个字符
    char ch = inFile.get();
    if (inFile.good()) {
        std::cout << "从输入文件读取的一个字符是: " << ch << std::endl;
        // 8. 将该字符写入输出文件
        outFile.put(ch);
        std::cout << "将该字符写入输出文件" << std::endl;
    } else {
        std::cerr << "读取字符时出现错误" << std::endl;
    }

    // 9. 移动输入文件指针
    inFile.seekg(0, std::ios::beg);
    std::cout << "将输入文件指针移到文件开头" << std::endl;

    // 10. 读取一定数量的字节
    char data[20];
    inFile.read(data, 20);
    std::cout << "从输入文件读取的 20 个字节的数据是: " << data << std::endl;

    // 11. 将读取的数据再次写入输出文件
    outFile.write(data, inFile.gcount());
    std::cout << "将读取的 20 个字节的数据写入输出文件" << std::endl;

    // 12. 检查输入文件流状态
    if (inFile.good()) {
        std::cout << "输入文件流状态正常" << std::endl;
    } else if (inFile.eof()) {
        std::cout << "输入文件已到达末尾" << std::endl;
    } else if (inFile.fail()) {
        std::cerr << "输入文件读取失败" << std::endl;
    } else if (inFile.bad()) {
        std::cerr << "输入文件发生严重错误" << std::endl;
    }

    // 13. 检查输出文件流状态
    if (outFile.good()) {
        std::cout << "输出文件流状态正常" << std::endl;
    } else if (outFile.fail()) {
        std::cerr << "输出文件写入失败" << std::endl;
    } else if (outFile.bad()) {
        std::cerr << "输出文件发生严重错误" << std::endl;
    }

    // 14. 刷新输出文件缓冲区
    outFile.flush();
    std::cout << "刷新输出文件缓冲区" << std::endl;

    // 15. 关闭文件
    inFile.close();
    outFile.close();

    return 0;
}

易错点

1.任何情况下的文件流语句都会生效,如:循环的条件判断中文件流会生效,见下图中的ifsProgream >> tempChars语句,若有两个并列条件时,最好把文件流语句放在后边,这样判断第一个条件失败后就会跳出循环,跳过后边的文件流语句。

while ( i<3&& ifsProgream >> tempChars)
		{
			tempCharss[i] = tempChars;
			i++;
		}

2.读取二进制文件只能使用unsigned char储存,否则会出错。

有符号字符(signed char

可以表示范围为 -128 到 127 的整数。如果存储的数据超出这个范围,会导致符号位的解释问题。例如,如果一个字节存储的值是 255(二进制 11111111),在有符号字符中,它将被解释为 -1。

无符号字符(unsigned char

可以表示范围为 0 到 255 的整数,正好匹配一个字节的所有可能值。

二进制文件存储的是原始的字节数据,这些数据可以代表任何信息,包括但不限于文本、图像、音频、视频或自定义的二进制数据结构。每个字节的值范围是从 0 到 255(无符号)或 -128 到 127(有符号)。虽然二进制文件本身并不固有地是无符号的,但在存储和处理二进制文件的字节数据时,使用 unsigned char 是一种更安全、更准确和更通用的方法,因为它避免了符号位的解释问题,确保了数据的原始字节值的正确表示和处理。这有助于确保程序在不同平台上的一致性和正确性,尤其在处理图像、音频、视频和自定义二进制数据结构等应用中。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值