栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

C++

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

C++

C文件I/O
  • C文件I/O
    • 1.1 文件类型
    • 1.2 文件的打开与关闭
      • 1.2.1文件打开
      • 1.2.2文件关闭
    • 1.3 文件的读写
      • 1.3.1 fputc和fgetc
      • 1.3.2 fwrite和fread
      • 1.3.3 注意点
    • 1.4 程序案例
      • 1.4.1 fputc和fgetc的读写
      • 1.4.2 fgets函数读取文件
      • 1.4.3 fwrite和fread的读写

C文件I/O 1.1 文件类型

> 文本文件
  又称为ASCII文件,文件中每个字节存放一个ASCII码,代表一个字符。
> 二进制文件
  把内存中数据按照其在内存中的存储形式原样输出到磁盘上存放。

1.2 文件的打开与关闭 1.2.1文件打开
FILE* pFile = fopen(filePath, mode);

第一个参数:文件路径
第二个参数:打开方式

常用打开方式列表:

打开方式含义
“r”只读,文件必须存在
“w”只写,文件不存在时创建文件,文件存在时原数据清零
“a”追加,向文件末尾增加数据
“rb”二进制,只读
“wb”二进制,只写
“ab”二进制,追加
“r+”读写,打开一个文本文件
“w+”读写,创建一个文本文件
1.2.2文件关闭
fclose(pFile);		// pFile为要关闭的文件指针
1.3 文件的读写 1.3.1 fputc和fgetc
char result = fputc(ch, pFile);		// 写入一个字符
char result = fgetc(pFile);			// 读取一个字符
1.3.2 fwrite和fread
size_t fwrite(const void* pBuffer, size_t nSize, size_t nCount, FILE* pFile); 

参数

  • pBuffer:一个指针,被写入数据的地址
  • nSize:写入的字节数
  • nCount:进行写入nSize字节的数据项的个数
  • pFile:文件指针

返回值
如果成功,该函数返回一个 size_t 对象,表示元素的总数,该对象是一个整型数据类型。如果该数字与 nmemb 参数不同,则会显示一个错误。

size_t fread(void* pBuffer, size_t nSize, size_t nCount, FILE* pFile);

参数

  • pBuffer:一个指针,读取数据的地址
  • nSize:读取的字节数
  • nCount:进行读取nSize字节的数据项的个数
  • pFile:文件指针

返回值
成功读取的元素总数会以 size_t 对象返回,size_t 对象是一个整型数据类型。如果总数与 nmemb 参数不同,则可能发生了一个错误或者到达了文件末尾。

1.3.3 注意点

  读写最好采用配套操作,写如果用了"b"标记,读也最好用"b"标记。

1.4 程序案例 1.4.1 fputc和fgetc的读写
#pragma warning(disable : 4996)

#include 

using namespace std;

class FileIO
{
public:
    FileIO(const string& strPath, const string& strMode);
    ~FileIO();

public:
    bool Initialize();
    
    bool WriteToFile(const string& strData);
    bool ReadFromFile(string& strData);

    void Release();
    
private:
    string m_strPath;
    string m_strMode;
    FILE* m_pFile;
    bool m_bInitOk;
};

FileIO::FileIO(const string& strPath, const string& strMode) : 
    m_strPath(strPath),
    m_strMode(strMode),
    m_pFile(nullptr),
    m_bInitOk(false)
{
    // ...
}

FileIO::~FileIO()
{
    Release();
}

bool FileIO::Initialize()
{
    m_pFile = fopen(m_strPath.c_str(), m_strMode.c_str());
    
    if (nullptr == m_pFile)
    {
        m_bInitOk = false;
        cout << "Create Or Open File Failedn";
        return false;
    }

    m_bInitOk = true;

    return true;
}

bool FileIO::WriteToFile(const string& strData)
{
    if (!m_bInitOk)
    {
        cout << "m_bInit Is Falsen";
        return false;
    }

    size_t nLength = strData.length();

    for (size_t i = 0; i != nLength; ++i)
    {
        // 如果没有发生错误,则返回被写入的字符。如果发生错误,则返回 EOF,并设置错误标识符。
        if (EOF == fputc(strData.at(i), m_pFile))
        {
            cout << "Write File Failedn";
            return false;
        }
    }
    return true;
}

bool FileIO::ReadFromFile(string& strData)
{
    if (!m_bInitOk)
    {
        cout << "m_bInit Is Falsen";
        return false;
    }

    strData.clear();

    // feof(m_pFile):此函数用于判断文件是否结束
    while (!feof(m_pFile))
    {
        char result = fgetc(m_pFile);
        if (EOF != result)
            strData.append(string(1, result));
    }

    return true;
}

void FileIO::Release()
{
    if (nullptr != m_pFile)
    {
        fclose(m_pFile);
        m_pFile = nullptr;
    }
}

  备注:在读取文件字符时不要使用下面的方式判断是否到文件尾部,因为文件中假设存在一个值为-1的字符,那么将会误判文件已经到尾部。

char result;
while(EOF != result)
{
	result = fgetc(m_pFile);
}
1.4.2 fgets函数读取文件
char* fgets(char* str, int nLength, FILE* pFile);

参数

  • str:这是指向一个字符数组的指针,该数组存储了要读取的字符串。
  • nLength:这是要读取的最大字符数(包括最后的空字符)。通常是使用以 str 传递的数组长度。
  • pFile:这是指向 FILE 对象的指针,该 FILE 对象标识了要从中读取字符的流。

返回值
  如果成功,该函数返回相同的 str 参数。如果到达文件末尾或者没有读取到任何字符,str 的内容保持不变,并返回一个空指针。如果发生错误,返回一个空指针。

备注
  fgets函数读取一行,在遇到rn时,r被舍弃,只保留n

字符简称含义字符ASCII值
CRCarriage Return 回车‘r’ASCII为13
LFLineFeed 换行‘n’ASCII码为10

Unix/Linux换行使用:LF(0x0A)
Dos/Windows使用的是:CRLF(0x0D0A)

void Test()
{
    FILE* pFile = fopen("Config.txt", "r");

    if (nullptr == pFile)
    {
        cout << "Open File Failedn";
        return;
    }

    char szBuffer[1024];
    
    while (!feof(pFile))
    {
        memset(szBuffer, '', sizeof(szBuffer));
        
        char* pResult = fgets(szBuffer, sizeof(szBuffer) - 1, pFile);       // 减1为了保证最后一个字符为''
        
        if (nullptr == pResult)
            continue;

        // 清除行尾的回车符合换行符 回车:0x0D 换行:0x0A
        int nLength = strlen(szBuffer);

        if (nLength <= 0)
            continue;

        while ('r' == szBuffer[nLength - 1] || 'n' == szBuffer[nLength - 1])
        {
            szBuffer[nLength - 1] = '';
            nLength = strlen(szBuffer);
            
            if (nLength <= 0)
                break;
        }

        printf("Line Data : %sn", szBuffer);
    }

    fclose(pFile);
}
1.4.3 fwrite和fread的读写

采用二进制方式进行结构体数据的读写

void WriteStudentData()
{
    Student arrStu[2];

    strcpy(arrStu[0].m_szName, "zhangsanA");
    arrStu[0].m_nAge = 21;
    arrStu[0].m_dScore = 99.5;

    strcpy(arrStu[1].m_szName, "zhangsanB");
    arrStu[1].m_nAge = 22;
    arrStu[1].m_dScore = 92.5;

    FILE* pFile = fopen("struct_file.bin", "wb");

    if (nullptr == pFile)
    {
        cout << "Create File Failedn";
        return;
    }

    // 一般可以不要 nResult 结果
    size_t nResult = fwrite(arrStu, sizeof(Student), 2, pFile);
    
    fclose(pFile);
}

void ReadStudentData()
{
    Student arrStu[2];

    FILE* pFile = fopen("struct_file.bin", "rb");

    if (nullptr == pFile)
    {
        cout << "Open File Failedn";
        return;
    }

    size_t nResult = fread(arrStu, sizeof(Student), 2, pFile);

    fclose(pFile);
}
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/835959.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号