TIL - 13(file IO)

jh Seo·2024년 8월 9일

C++ fstream

Text 파일인 경우

//test. txt 파일 outputStream에 할당
std::ofstream OutputStream = std::ofstream("Test.txt", std::ios::out);
if (OutputStream.is_open())
{
	//작성할 string
	std::string String = "Hello File! Hello~~~\n";
    //작성할 string 크기
	const size_t WriteSize = String.size();
    // write함수에 write할 사이즈를 입력해둔다. read에서 사용하기 위해
	OutputStream.write((const char*)&WriteSize, sizeof(size_t));
    // string 값을 작성한다.
	OutputStream.write(String.c_str(), String.size());

	//이런 식으로 int도 넣는다.
	int Int = 65;
	OutputStream.write(reinterpret_cast<char*>(&Int), sizeof(int));
	OutputStream.close(); // 파일 닫기
}

ofstream을 이용해 Test.txt파일을 write모드로 열고
원하는 값들을 작성 후, 마지막에 닫기

std::ifstream InputStream = std::ifstream("Test.txt", std::ios::in);
if (InputStream.is_open())
{
	//위 write에서 작성한 사이즈를 읽어온다.
	size_t ReadSize = 0;
	InputStream.read(reinterpret_cast<char*>(&ReadSize), sizeof(size_t));
	std::string String;
    //읽어올 크기만큼 할당 후,
	String.resize(ReadSize);
    //값을 읽어온다.
	InputStream.read(String.data(), String.size());
	//InputStream >> String;

	int Int = 0;
	InputStream.read(reinterpret_cast<char*>(&Int), sizeof(int));

	InputStream.close();
}

ifstream을 이용해 Test.txt파일을 읽기모드로 열고
원하는 값들 읽어온 후, 닫는다.

Binary 파일인 경우

std::ofstream OutputStream = std::ofstream("TestBinary.txt", std::ios::out | std::ios::binary);
if (OutputStream.is_open())
{
	std::string String = "Hello File! Hello~~~\n";
	const size_t WriteSize = String.size();
	OutputStream.write((const char*)&WriteSize, sizeof(size_t));
	OutputStream.write(String.c_str(), String.size());

	int Int = 65;
	OutputStream.write(reinterpret_cast<char*>(&Int), sizeof(int));
	OutputStream.close(); // 파일 닫기
}

ofstream 끝에 인자를 추가해준다. std::ios::binary를 이용해 읽는다.
그 외 나머지는 텍스트파일인 경우와 같다.

std::ifstream InputStream = std::ifstream("TestBinary.txt", std::ios::in | std::ios::binary);
if (InputStream.is_open())
{
	size_t ReadSize = 0;
	InputStream.read(reinterpret_cast<char*>(&ReadSize), sizeof(size_t));
	std::string String;
	String.resize(ReadSize);
	InputStream.read(String.data(), String.size());
	//InputStream >> String;

	int Int = 0;
	InputStream.read(reinterpret_cast<char*>(&Int), sizeof(int));

	InputStream.close();
}

읽는 경우도 마찬가지다. std::ios::binary를 이용해 바이너리 파일인 걸 표시해준다.

ini파일

INI(Initialization) 파일 포맷은 설정 파일에 대한 사실상 표준이다. INI 파일은 단순 구조의 텍스트 파일로 이루어져 있다. 보통 마이크로소프트 윈도우와 연결되어 있지만 다른 운영 체제에서도 사용할 수 있다.
출처 위키백과 - INI 파일

Rookfighter님의 ini파일 깃허브

위의 깃허브에 작성된 ini 파일 관리 헤더를 이용했다.

어쩌다보니 위 깃허브의 ini파일 헤더의 사용법을 위주로 작성중인데

#include를 이용해 연동 후, 값을 저장하려면

ini::IniFile File;
File["A Section"]["FieldKey1"] = 0;
File["A Section"]["FieldKey2"] = 1;
File["A Section"]["FieldKey3"] = 2;
File["B Section2"]["FieldKey1"] = 3;
File["B Section2"]["FieldKey2"] = 4;
File["B Section2"]["FieldKey3"] = 5;
File["C Graphics"]["Width"] = 1920;
File["C Graphics"]["Height"] = 1080;
File["C Graphics"]["Test"] = "Hello";

File.save("IniFile.ini");

이런 식으로, map의 key-value값을 이용해 저장을 하면 설정한 IniFile.ini 파일로 저장이 된다.

읽을 땐

ini::IniFile File("IniFile.ini");
ini::IniField& Field = File["C Graphics"]["Test"];
std::string String = Field.as<std::string>();
std::string String2 = File["C Graphics"]["Test"].as<std::string>();

이런식으로 읽어오고 File의 key값을 이용해 value값에 접근 가능하다.
값을 원하는 형식으로 변환할 때는,

int IntVar2 = File["A Section"]["FieldKey2"].as<int>();

이런 식으로 as키워드로 변환이 가능하다.

ini::IniSection Section = File["B Section2"];
for (auto It : Section)
{
	std::cout << std::format("Key: {}, Value: {}\n", It.first, It.second.as<std::string>());
}

한 섹션을 불러올 땐,

ini::IniSection Section = File["B Section2"];
for (auto It : Section)
{
	std::cout << std::format("Key: {}, Value: {}\n", It.first, It.second.as<std::string>());
}

이런식으로 inisection자료형으로 불러오고, 범위기반 반복문으로 순회도 가능하다

for (auto It : Section)
{
	std::cout << std::format("Key: {}, Value: {}\n", It.first, It.second.as<std::string>());
}
profile
코딩 창고!

0개의 댓글