一、C的文件处理
C语言中没有输入输出语句,所有的输入输出功能都用 ANSI C提供的一组标准库函数来实现。文件操作标准库函数有:
文件的打开操作 :fopen
FILE * fopen(char *filename, char *mode);
文件的关闭操作 :fclose
int fclose(FILE *fp);
模式 | 含 义 | 说 明 |
---|---|---|
r | 只读 | 文件必须存在,否则打开失败 |
w | 只写 | 若文件存在,则清除原文件内容后写入;否则,新建文件后写入 |
a | 追加只写 | 若文件存在,则位置指针移到文件末尾,在文件尾部追加写人,故该方式不 删除原文件数据;若文件不存在,则打开失败 |
r+ | 读写 | 文件必须存在。在只读 r 的基础上加 '+' 表示增加可写的功能。下同 |
w+ | 读写 | 新建一个文件,先向该文件中写人数据,然后可从该文件中读取数据 |
a+ | 读写 | 在” a”模式的基础上,增加可读功能 |
rb | 二进制读 | 功能同模式”r”,区别:b表示以二进制模式打开。下同 |
wb | 二进制写 | 功能同模式“w”。二进制模式 |
ab | 二进制追加 | 功能同模式”a”。二进制模式 |
rb+ | 二进制读写 | 功能同模式"r+”。二进制模式 |
wb+ | 二进制读写 | 功能同模式”w+”。二进制模式 |
ab+ | 二进制读写 | 功能同模式”a+”。二进制模式 |
返回值:打开成功,返回该文件对应的 FILE 类型的指针;打开失败,返回 NULL。故需定义 FILE 类型的指针变量,保存该函数的返回值。可根据该函数的返回值判断文件打开是否成功。
文件的读写操作:
fgetc 从文件中读取一个字符:int fgetc (FILE *fp);
putc 写一个字符到文件中去:int fputc (int c, FILE *fp);
fgets 从文件中读取一个字符串:char * fgets (char *s, int size, FILE * fp);
fputs 写一个字符串到文件中去:int fputs (const char *str, FILE *fp);
fprintf 往文件中写格式化数据:int fscanf (文件指针,格式控制串,输入地址表列);
fscanf 格式化读取文件中数据:int fprintf (文件指针,格式控制串,输出表列);
fread 以二进制形式读取文件中的数据:unsigned fread (void *buf, unsigned size, unsigned count, FILE* fp);
fwrite 以二进制形式写数据到文件中去:unsigned fwrite (const void *bufAunsigned size,unsigned count,FILE* fp);
二、C++的文件处理
介绍如何从文件读取流和向文件写入流。这就需要用到 C++ 中另一个标准库 fstream,它定义了三个新的数据类型:
数据类型 | 描述 |
---|---|
ofstream | 该数据类型表示输出文件流,用于创建文件并向文件写入信息。 |
ifstream | 该数据类型表示输入文件流,用于从文件读取信息。 |
fstream | 该数据类型通常表示文件流,且同时具有 ofstream 和 ifstream 两种功能,这意味着它可以创建文件,向文件写入信息,从文件读取信息。 |
要在 C++ 中进行文件处理,必须在 C++ 源代码文件中包含头文件 <iostream> 和 <fstream>。
打开文件:
在从文件读取信息或者向文件写入信息之前,必须先打开文件。ofstream 和 fstream 对象都可以用来打开文件进行写操作,如果只需要打开文件进行读操作,则使用 ifstream 对象。
下面是 open() 函数的标准语法,open() 函数是 fstream、ifstream 和 ofstream 对象的一个成员。
void open(const char *filename, ios::openmode mode);
在这里,open() 成员函数的第一参数指定要打开的文件的名称和位置,第二个参数定义文件被打开的模式。
模式标志 | 描述 |
---|---|
ios::app | 追加模式。所有写入都追加到文件末尾。 |
ios::ate | 文件打开后定位到文件末尾。 |
ios::in | 打开文件用于读取。 |
ios::out | 打开文件用于写入。 |
ios::trunc | 如果该文件已经存在,其内容将在打开文件之前被截断,即把文件长度设为 0。 |
读取方式:
(1)逐词读取
void readdatafromfile()
{
ifstream fin("data.txt");
string s;
while (fin >> s)
{
cout << s << " ";//空格是为了避免数据都连在一块儿
}
cout << endl;
}
(2) 逐行读取
void readdatafromfile()
{
ifstream fin("data.txt");
string s;
while (getline(fin, s))
{
cout << "Read from file: " << s << endl;//读取4次(4行)
}
}
回车输入结束
通过cin.get()检测回车字符,判断输入结束。
string value;
while (std::cin >> value)
{
cout<< value<<endl;
if (cin.get() == '\n')
break;
}
参考:
实例:读取配置文件
配置文件:
listenip=0.0.0.0
listenport=20001
filecachedir=./filecache/
logfiledir=logs/
logfilename=fileserver
ConfigFileReader.h
#ifndef __CONFIG_FILE_READER_H__
#define __CONFIG_FILE_READER_H__
#include <map>
#include <string>
class CConfigFileReader
{
public:
CConfigFileReader(const char* filename);
~CConfigFileReader();
char* GetConfigName(const char* name);
int SetConfigValue(const char* name, const char* value);
private:
void _LoadFile(const char* filename);
int _WriteFIle(const char*filename = NULL);
void _ParseLine(char* line);
char* _TrimSpace(char* name);
bool m_load_ok;
std::map<std::string, std::string> m_config_map;
std::string m_config_file;
};
#endif //!__CONFIG_FILE_READER_H__
ConfigFileReader.cpp
#include "ConfigFileReader.h"
#include <stdio.h> //for snprintf
#include <string.h>
CConfigFileReader::CConfigFileReader(const char* filename)
{
_LoadFile(filename);
}
CConfigFileReader::~CConfigFileReader()
{
}
char* CConfigFileReader::GetConfigName(const char* name)
{
if (!m_load_ok)
return NULL;
char* value = NULL;
std::map<std::string, std::string>::iterator it = m_config_map.find(name);
if (it != m_config_map.end())
{
value = (char*)it->second.c_str();
}
return value;
}
int CConfigFileReader::SetConfigValue(const char* name, const char* value)
{
if (!m_load_ok)
return -1;
std::map<std::string, std::string>::iterator it = m_config_map.find(name);
if (it != m_config_map.end())
{
it->second = value;
}
else
{
m_config_map.insert(std::make_pair(name, value));
}
return _WriteFIle();
}
void CConfigFileReader::_LoadFile(const char* filename)
{
m_config_file.clear();
m_config_file.append(filename);
FILE* fp = fopen(filename, "r");
if (!fp)
return;
char buf[256];
for (;;)
{
char* p = fgets(buf, 256, fp);
if (!p)
break;
size_t len = strlen(buf);
if (buf[len - 1] == '\n')
buf[len - 1] = 0; // remove \n at the end
char* ch = strchr(buf, '#'); // remove string start with #
if (ch)
*ch = 0;
if (strlen(buf) == 0)
continue;
_ParseLine(buf);
}
fclose(fp);
m_load_ok = true;
}
int CConfigFileReader::_WriteFIle(const char* filename)
{
FILE* fp = NULL;
if (filename == NULL)
{
fp = fopen(m_config_file.c_str(), "w");
}
else
{
fp = fopen(filename, "w");
}
if (fp == NULL)
{
return -1;
}
char szPaire[128];
std::map<std::string, std::string>::iterator it = m_config_map.begin();
for (; it != m_config_map.end(); it++)
{
memset(szPaire, 0, sizeof(szPaire));
snprintf(szPaire, sizeof(szPaire), "%s=%s\n", it->first.c_str(), it->second.c_str());
size_t ret = fwrite(szPaire, strlen(szPaire), 1, fp);
if (ret != 1)
{
fclose(fp);
return -1;
}
}
fclose(fp);
return 0;
}
void CConfigFileReader::_ParseLine(char* line)
{
char* p = strchr(line, '=');
if (p == NULL)
return;
*p = 0;
char* key = _TrimSpace(line);
char* value = _TrimSpace(p + 1);
if (key && value)
{
m_config_map.insert(std::make_pair(key, value));
}
}
char* CConfigFileReader::_TrimSpace(char* name)
{
// remove starting space or tab
char* start_pos = name;
while ((*start_pos == ' ') || (*start_pos == '\t'))
{
start_pos++;
}
if (strlen(start_pos) == 0)
return NULL;
// remove ending space or tab
char* end_pos = name + strlen(name) - 1;
while ((*end_pos == ' ') || (*end_pos == '\t'))
{
*end_pos = 0;
end_pos--;
}
int len = (int)(end_pos - start_pos) + 1;
if (len <= 0)
return NULL;
return start_pos;
}
main.cpp
#include <iostream>
#include <string>
#include "ConfigFileReader.h"
using namespace std;
int main(void)
{
CConfigFileReader config("fileserver.conf");
const char* logfilepath = config.GetConfigName("logfiledir");
if (logfilepath == NULL)
{
cout << "logdir is not set in config file";
return 1;
}
cout <<"read context ; "<< logfilepath << endl;
getchar();
return 0;
}