C語言讀寫二進制文件


fseek用法

fseek用來移動文件指針。函數原型

 int fseek(FILE * stream, long offset, int fromwhere);

參數解釋:

  • stream 是文件流指針
  • offset 是相對文件起始位置的偏移量
  • fromwhere移動到哪兒。 其值如下
    • SEEK_SET:從距文件開頭 offset 位移量為新的讀寫位置;
    • SEEK_CUR:以目前的讀寫位置往后增加 offset 個位移量;
    • SEEK_END:將讀寫位置指向文件尾后再增加 offset 個位移量。

例如:

將讀寫位置移動到文件開頭:fseek(fp, 0, SEEK_SET);
將讀寫位置移動到文件尾時:fseek(fp, 0, SEEK_END);
將讀寫位置動到離文件開頭100字節處:fseek(fp,100L, SEEK_SET);
將讀寫指針移動到離文件當前位置100字節處:fseek(fp,100L, SEEK_CUR);
將讀寫指針退回到離文件結尾100字節處:fseek(fp, -100L, SEEK_END);

准備代碼

准備一個下面的結構體,用作演示

struct st_type_no_item_
{
      /// 類型
	int type_ = 0;
      /// 編號
	int no_ = 0;

	st_type_no_item_()
	{
		type_ = 0;
		no_ = 0;
	}
};
/// 
using st_type_no_item = st_type_no_item_;

寫二進制文件

使用函數fwrite實現寫入,演示使用,當然,你可以加上函數的返回值,表示寫入文件的結果

void write_file_(std::string str)
{
	FILE *pfile = nullptr;
	int ret = fopen_s(&pfile, str.c_str(), "wb");

	/// 0 = 打開成功,
	if (0 == ret)
	{
		if (pfile)
		{
			/// 准備內存
			st_type_no_item item;
			item.type_	= 0x22;
			item.no_	= 0x33;
			
			int len = sizeof(st_type_no_item);
			/// 寫文件
			int write_length = fwrite(&item, sizeof(st_type_no_item), 1, pfile);
			fclose(pfile);
			pfile = nullptr;

			std::cout << "\n 寫文件成功, 寫入長度=" << write_length << "\n";
		}
		else
		{
			;/// pfile 文件指針為null
			std::cout << "\n 寫文件失敗, pfile = null \n\n";
		}
	}
	else
	{
		;/// 打開失敗
		std::cout << "\n 寫文件失敗,文件打開失敗\n\n";
	}
}

讀二進制文件

使用函數fread讀取二進制文件。 需要注意fread函數的參數。 應該檢查其返回值於函數的第三個參數是否相等,如果不相等,則讀取失敗。 相等則讀取成功

/// ----------------------------------------------------------------------------------------
/// 讀文件
void read_file_(std::string str)
{
	FILE *pfile = nullptr;
	int ret = fopen_s(&pfile, str.c_str(), "rb");

	/// 0 = 打開成功,
	if (0 == ret)
	{
		if (pfile)
		{
			fseek(pfile, 0, SEEK_END);
			unsigned int file_length_bytes = ftell(pfile);
			fseek(pfile, 0, SEEK_SET);

			if (0 < file_length_bytes)
			{
				/// 准備內存
				st_type_no_item item;
				char arr[8] = { 0 };
				/// 讀文件.參數依次是: 文件讀取緩存、緩存的類型基本長度、需要讀取多少個單位的緩存、文件流
				/// 這里演示: item是緩存, sizeof(st_type_no_item)表示item的長度, 1表示讀取一個單位的item(8字節),pfile是文件流
				/// fread成功,將返回 第三個參數相同的值,說明讀取成功,其他失敗。
				int readlen = fread(&item, sizeof(st_type_no_item), 1, pfile);

				std::cout << "\n 讀文件成功, type=" << item.type_ << ", no=" << item.no_ << "\n\n";
			}
			else
			{
				;/// 文件長度為0 
			}
		
			/// 關閉文件
			fclose(pfile);
			pfile = nullptr;
		}
		else
		{
			;/// pfile 文件指針為null
			std::cout << "\n 讀文件失敗, pfile = null \n\n";
		}
	}
	else
	{
		;/// 打開失敗
		std::cout << "\n 讀文件失敗,文件打開失敗\n\n";
	}
}

結果

完整演示代碼


#include <iostream>

/// 判斷文件是否存在
bool is_exist_file_(std::string&& str_file)
{
	struct stat st;

	return (0 == stat(str_file.c_str(), &st));
}


struct st_type_no_item_
{
	int type_ = 0;
	int no_ = 0;

	st_type_no_item_()
	{
		type_ = 0;
		no_ = 0;
	}
};
/// 
using st_type_no_item = st_type_no_item_;


/// ----------------------------------------------------------------------------------------
/// 寫文件
void write_file_(std::string str)
{
	FILE *pfile = nullptr;
	int ret = fopen_s(&pfile, str.c_str(), "wb");

	/// 0 = 打開成功,
	if (0 == ret)
	{
		if (pfile)
		{
			/// 准備內存
			st_type_no_item item;
			item.type_	= 0x22;
			item.no_	= 0x33;
			
			int len = sizeof(st_type_no_item);
			/// 寫文件
			int write_length = fwrite(&item, sizeof(st_type_no_item), 1, pfile);
			fclose(pfile);
			pfile = nullptr;

			std::cout << "\n 寫文件成功, 寫入長度=" << write_length << "\n";
		}
		else
		{
			;/// pfile 文件指針為null
			std::cout << "\n 寫文件失敗, pfile = null \n\n";
		}
	}
	else
	{
		;/// 打開失敗
		std::cout << "\n 寫文件失敗,文件打開失敗\n\n";
	}
}


/// ----------------------------------------------------------------------------------------
/// 讀文件
void read_file_(std::string str)
{
	FILE *pfile = nullptr;
	int ret = fopen_s(&pfile, str.c_str(), "rb");

	/// 0 = 打開成功,
	if (0 == ret)
	{
		if (pfile)
		{
			fseek(pfile, 0, SEEK_END);
			unsigned int file_length_bytes = ftell(pfile);
			fseek(pfile, 0, SEEK_SET);

			if (0 < file_length_bytes)
			{
				/// 准備內存
				st_type_no_item item;
				char arr[8] = { 0 };
				/// 讀文件.參數依次是: 文件讀取緩存、緩存的類型基本長度、需要讀取多少個單位的緩存、文件流
				/// 這里演示: item是緩存, sizeof(st_type_no_item)表示item的長度, 1表示讀取一個單位的item(8字節),pfile是文件流
				/// fread成功,將返回 第三個參數相同的值,說明讀取成功,其他失敗。
				int readlen = fread(&item, sizeof(st_type_no_item), 1, pfile);

				std::cout << "\n 讀文件成功, type=" << item.type_ << ", no=" << item.no_ << "\n\n";
			}
			else
			{
				;/// 文件長度為0 
			}
		
			/// 關閉文件
			fclose(pfile);
			pfile = nullptr;
		}
		else
		{
			;/// pfile 文件指針為null
			std::cout << "\n 讀文件失敗, pfile = null \n\n";
		}
	}
	else
	{
		;/// 打開失敗
		std::cout << "\n 讀文件失敗,文件打開失敗\n\n";
	}
}


/// ----------------------------------------------------------------------------------------
int main()
{
	std::string str = "C:\\game\\demo.txt";

	bool is_exist = true;// is_exist_file_(std::move(str));
	if (!is_exist)
		return 0;

	/// 寫文件

	write_file_(str);
	read_file_(str);



	std::cout << is_exist << "\n\n\n";
}

fread_s讀取文件

下面的完整代碼演示了使用函數fread_s讀取二進制文件


#include <iostream>

/// 判斷文件是否存在
bool is_exist_file_(std::string&& str_file)
{
	struct stat st;

	return (0 == stat(str_file.c_str(), &st));
}


struct st_type_no_item_
{
	int type_ = 0;
	int no_ = 0;

	st_type_no_item_()
	{
		type_ = 0;
		no_ = 0;
	}
};
/// 
using st_type_no_item = st_type_no_item_;


/// ----------------------------------------------------------------------------------------
/// 寫文件
void write_file_(std::string str)
{
	FILE *pfile = nullptr;
	int ret = fopen_s(&pfile, str.c_str(), "wb");

	/// 0 = 打開成功,
	if (0 == ret)
	{
		if (pfile)
		{
			/// 准備內存
			st_type_no_item item[2];
			item[0].type_	= 0x1;
			item[0].no_		= 0x1;
			item[1].type_	= 0x2;
			item[1].no_		= 0x2;


			int len = sizeof(st_type_no_item);
			/// 寫文件
			int write_result = fwrite(item, sizeof(st_type_no_item), 2, pfile);
			if (write_result != 2)
			{
				std::cout << "write error , ret=" << write_result << "\n";
			}
			else
			{
				std::cout << "write success, ret=" << write_result << "\n";
			}


			fclose(pfile);
			pfile = nullptr;
		}
		else
		{
			;/// pfile 文件指針為null
			std::cout << "\n 寫文件失敗, pfile = null \n\n";
		}
	}
	else
	{
		;/// 打開失敗
		std::cout << "\n 寫文件失敗,文件打開失敗\n\n";
	}
}


/// ----------------------------------------------------------------------------------------
/// 讀文件
void read_file_(std::string str)
{
	FILE *pfile = nullptr;
	int ret = fopen_s(&pfile, str.c_str(), "rb");

	/// 0 = 打開成功,
	if (0 == ret)
	{
		if (pfile)
		{
			fseek(pfile, 0, SEEK_END);
			unsigned int file_length_bytes = ftell(pfile);
			fseek(pfile, 0, SEEK_SET);

			if (0 < file_length_bytes)
			{
				/// 准備內存
				st_type_no_item item[2];
				/// 讀文件.參數依次是: 文件讀取緩存、緩存的類型基本長度、需要讀取多少個單位的緩存、文件流
				/// 這里演示: item是緩存, sizeof(st_type_no_item)表示item的長度, 1表示讀取一個單位的item(8字節),pfile是文件流
				/// fread成功,將返回 第三個參數相同的值,說明讀取成功,其他失敗。
				//int readlen = fread(&item, sizeof(st_type_no_item), 1, pfile);
				int ret = fread_s(item, sizeof(st_type_no_item) * 2, sizeof(st_type_no_item), 2, pfile);
				std::cout << "ret=" << ret << "\n";
				std::cout << "type0=" << item[0].type_ << ", no0=" << item[0].no_ << "\n";
				std::cout << "type1=" << item[1].type_ << ", no1=" << item[1].no_ << "\n";
				//std::cout << "\n 讀文件成功, type=" << item.type_ << ", no=" << item.no_ << "\n\n";
			}
			else
			{
				;/// 文件長度為0 
			}
		
			/// 關閉文件
			fclose(pfile);
			pfile = nullptr;
		}
		else
		{
			;/// pfile 文件指針為null
			std::cout << "\n 讀文件失敗, pfile = null \n\n";
		}
	}
	else
	{
		;/// 打開失敗
		std::cout << "\n 讀文件失敗,文件打開失敗\n\n";
	}
}


/// ----------------------------------------------------------------------------------------
int main()
{
	std::string str = "C:\\game\\demo.txt";

	bool is_exist = true;// is_exist_file_(std::move(str));
	if (!is_exist)
		return 0;

	/// 寫文件

	write_file_(str);
	read_file_(str);



	std::cout << is_exist << "\n\n\n";
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM