文件读写操作C++

最近整理了一下使用C++语言实现文件读写,比较简单,直接贴上代码:

#include <iostream>
#include <stdlib.h>
#include <string.h>
#include <string>
#include <fstream>

#define SERIAL_NO_LEN		32
#define NAME_LEN			32
#define GENDER_LEN			8
#define PHONE_LEN			16
#define AGE_LEN				16
#define SALARY_LEN			16
#define STAFF_SIZE			3
#define STAFF_FILE_NAME		"staff_info.txt"

struct Staff
{
	char szSerialNo[SERIAL_NO_LEN];
	char szName[NAME_LEN];
	char szGender[GENDER_LEN];
	char szPhone[PHONE_LEN];
	int iAge;
	double dSalary;

	void show()
	{
		std::cout << szSerialNo << '\t' << szName << '\t' << szGender << '\t'
			<< szPhone << '\t' << iAge << '\t' << dSalary << std::endl;
	}
};

void fileReadTest()
{
	std::ifstream fin(STAFF_FILE_NAME);
	if (!(fin.is_open()))
	{
		std::cout << "打开文件错误!" << std::endl;
		return;
	}

	// 方式一:按行读取
	/*char szInfo[256] = { 0 };
	while (!(fin.eof()))
	{
		fin.getline(szInfo, 255);
		std::cout << szInfo << std::endl;
	}*/

	// 方式二:string按行读
	/*std::string strInfo = "";
	getline(fin, strInfo);
	std::cout << "Tag: "<< strInfo.c_str() << std::endl;
	getline(fin, strInfo);
	std::cout << "Count: "<< strInfo.c_str() << std::endl;
	getline(fin, strInfo);
	std::cout << strInfo.c_str() << std::endl;*/

	// 注意:各种方式不能混合使用,混合使用出现读取错乱

	// 方式三:根据数据类型读取
	int iTag = 0, iCount = 0;
	fin >> iTag >> iCount;
	//fin >> iCount;

	std::cout << "Tag: " << iTag << ", count: " << iCount << std::endl;
	char szSerialNo[SERIAL_NO_LEN] = { 0 };
	char szName[NAME_LEN] = { 0 };
	char szGender[GENDER_LEN] = { 0 };
	char szPhone[PHONE_LEN] = { 0 };
	char szAge[AGE_LEN] = { 0 };
	char szSalary[SALARY_LEN] = { 0 };

	fin >> szSerialNo >> szName >> szGender >> szPhone >> szAge >> szSalary;
	std::cout << szSerialNo << '\t' << szName << '\t' << szGender << '\t'
		<< szPhone << '\t' << szAge << '\t' << szSalary << std::endl;

	Staff staff;
	for (int i = 0; i < iCount; ++i)
	{
		memset(&staff, 0, sizeof (staff));
		fin >> staff.szSerialNo >> staff.szName >> staff.szGender >> staff.szPhone >> staff.iAge >> staff.dSalary;
		staff.show();
	}

	fin.close();

	return;
}

void fileWriteTest()
{
	int iTag = 2;
	Staff szStaffs[STAFF_SIZE] = { 0 };

	strcpy(szStaffs[0].szSerialNo, "ST000001");
	strcpy(szStaffs[0].szName, "张三");
	strcpy(szStaffs[0].szGender, "男");
	strcpy(szStaffs[0].szPhone, "15656697812");
	szStaffs[0].iAge = 25;
	szStaffs[0].dSalary = 4568.23;

	strcpy(szStaffs[1].szSerialNo, "ST000002");
	strcpy(szStaffs[1].szName, "蔡明花");
	strcpy(szStaffs[1].szGender, "女");
	strcpy(szStaffs[1].szPhone, "15156647862");
	szStaffs[1].iAge = 23;
	szStaffs[1].dSalary = 3569.04;

	strcpy(szStaffs[2].szSerialNo, "ST000003");
	strcpy(szStaffs[2].szName, "李四");
	strcpy(szStaffs[2].szGender, "男");
	strcpy(szStaffs[2].szPhone, "13856748869");
	szStaffs[2].iAge = 56;
	szStaffs[2].dSalary = 9549.57;

	std::ofstream fout(STAFF_FILE_NAME); // std::ofstream fout(STAFF_FILE_NAME, ios::app);
	if (!(fout.is_open()))
	{
		std::cout << "打开文件错误!" << std::endl;
		return;
	}

	fout << iTag << std::endl;
	fout << STAFF_SIZE << std::endl;
	fout << "编号" << '\t' << "姓名" << '\t' << "性别" << '\t'
		<< "电话" << '\t' << "年龄" << '\t' << "工资" << std::endl;

	for (int i = 0; i < STAFF_SIZE; ++i)
	{
		szStaffs[i].show();
		fout << szStaffs[i].szSerialNo << '\t' << szStaffs[i].szName << '\t' << szStaffs[i].szGender << '\t'
			<< szStaffs[i].szPhone << '\t' << szStaffs[i].iAge << '\t' << szStaffs[i].dSalary << std::endl;
	}

	fout.close();

	return;
}

int main(int argc, char** argv)
{
	fileWriteTest();
	fileReadTest();

    getchar();
	return 0;
}

再补充直接读写std::string中的接口和测试接口

#include <sstream>
#include <fstream>
#include <algorithm>
#include <string>
#include <sys/time.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include <sys/types.h>
#include <fcntl.h>
#include <dirent.h>
#include <unistd.h>
#include <string.h>

// 内容追加入文件
void appendFile(const std::string& strFilePath, const std::string& strContent)
{
    std::ofstream fout;
    fout.open(strFilePath, std::ios::app | std::ios::binary | std::ios::out);

    if (!(fout.is_open()))
    {
        LOG_ERROR("open file (%s) failed.", strFilePath.data());
        return;
    }

    fout << strContent;
	fout.flush();
	fout.close();

    return;
}

// 写入文件
void writeFile(const std::string& strFilePath, const std::string& strContent)
{
#if 1
    // 效率ok
    int fd = open(strFilePath.data(), O_RDWR | O_CREAT | O_TRUNC, 0777);
    if (0 <= fd)
    {
        size_t len = strContent.length();
        truncate(strFilePath.data(), len);
        void *mp = mmap(NULL, len, PROT_WRITE | PROT_READ, MAP_SHARED, fd, 0);
        if (mp)
        {
            memcpy(mp, strContent.data(), len);
            munmap(mp, len);
        }

        close(fd);
    }
#elif 0
    // 效率差不多
    std::ofstream fout(strFilePath, std::ios::binary | std::ios::out); // 需要指定模式,否则存在数据丢失问题
    if (!(fout.is_open()))
    {
        LOG_ERROR("open file (%s) failed.", strFilePath.data());
        return;
    }

    fout << strContent;
    fout.flush();
    fout.close();
#else
    // 效率差不多
    FILE *fp = fopen(strFilePath.data(), "wb+"); // 注意只用w或者wb时,存在数据丢失问题,建议用wb+
    if (fp)
    {
        // fputs(strContent.data(), fp);
        fwrite(strContent.data(), strContent.size(), 1, fp);
        fflush(fp);
        fclose(fp);
    }
#endif

	return;
}

// 读出文件
void readFile(const std::string& strFilePath, std::string& strContent)
{
	std::ifstream fin(strFilePath);
	if (!(fin.is_open()))
	{
		printf("open file (%s) failed.\r\n", strFilePath.data());
		return;
	}

#if 0
	// 方法1:ok
	std::istreambuf_iterator<char> iterBeg(fin), iterEnd;
	strContent = std::string(iterBeg, iterEnd);
	//fin >> strContent;
#elif 0
	// 方法2:ok
	fin.seekg(0, std::ios::end); // 跳到文件尾
	size_t iFileSize = fin.tellg(); // 获取字节长度
	fin.seekg(0, std::ios::beg); // 跳到文件开头

	char* pBuffer = new (std::nothrow) char[iFileSize];
	if (pBuffer)
	{
		memset(pBuffer, 0, iFileSize * sizeof(char));
		fin.read(pBuffer, iFileSize); // 读取文件
		strContent = std::string(pBuffer, iFileSize);

		delete[] pBuffer;
		pBuffer = nullptr;
	}
#else
    // 方法3(推荐):ok,该方法效率较一般读取方法快20倍
    std::vector<char> buffer;
    buffer.clear();
    buffer.resize(fin.seekg(0, std::ios::end).tellg());
    fin.seekg(0, std::ios::beg).read(&buffer[0], static_cast<std::streamsize>(buffer.size()));
    strContent = std::string(buffer.data(), buffer.size());
#endif // 0

	fin.close();

	return;
}

void fileTest()
{
	std::string strFilePath = "abc123.txt";
	std::string strContent = "abc123456789              0000 \r\n7891212abcdfghijklmn.";
	std::string strContentTemp = "";

	writeFile(strFilePath, strContent);
	readFile(strFilePath, strContentTemp);
	printf("read: %s\r\n", strContentTemp.data());

	return;
}

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值