지난 시간에 이어서 C++ STD Library 추가학습 시우시작..
File I / O Streams
- Data 작업을 하려면 일단 기본적으로 file I / O 는 할 수 있어야 한다.
- C++에선 input file stream --> ifstream , output file stream --> ofstream class를 사용한다.
- 얘네는 전부 C++ STD Library의 <fstream> 헤더파일의 일부이다.
File I / O Streams - Reading
#include <iostream>
#include <fstream>
#include <string>
int main(void)
{
std::ifstream file("test_folder\\test.txt");
// std::ifstream file("test_folder/test.txt");
// file path는 위와 같이 두 가지 방식으로 처리 가능
if (!file.is_open())
{
std::cerr << "fail" << std::endl;
return 0;
} //파일이 열렸는지 체크
std::string line;
while(std::getline(file,line))
{
std::cout << line << std::endl;
}
file.close();
return 0;
}
- getline function을 쓰지 않으면 ifstream은 character를 input buffer로부터 읽을 때 white space를 만나면 읽기를 멈춘다.
(cin과 비슷)
- 사실상 ifstream은 istram class를 inherit 한 것이다.
1. getline 사용 X
// num_data :
// 123
// 4 5
// 67 8
#include <iostream>
#include <fstream>
int main()
{
std::ifstream file("num_data.txt");
int num;
while(file >> num)
{
std::cout << num << std::endl;
}
file.close();
return 0;
}
// 123
// 4
// 5
// 67
// 8
2. getline 사용 O --> getline은 int말고 string type variable로 써야한다.
// num_data :
// 123
// 4 5
// 67 8
#include <iostream>
#include <fstream>
#include <string>
int main()
{
std::ifstream file("num_data.txt");
int num;
std::string str;
// while(file >> num)
while(std::getline(file,str))
{
std::cout << str << std::endl;
}
file.close();
return 0;
}
// 123
// 4 5
// 67 8
File I / O Streams - Writing
// data.txt
// a b c
// d e
// f
#include <iostream>
#include <fstream>
int main()
{
std::ofstream file123("data.txt");
if(!file123.is_open())
{
std::cout << "ERROR" << std::endl;
return 1;
}
file123 << "ADD THIS COMMENT!!" << std::endl;
file123.close();
return 0;
}
// data.txt
// ADD THIS COMMENT!!
// 기존 내용 날라가고 덮어쓰기가 되어버리네..;;
- Write을 해보니 파일에 있던 기존 txt 파일은 다 날라가고 추가한 문구만 들어간다.
- 기존 문구 살리면서 추가 코멘트만 넣는 방법에 대해 고안..
// data.txt
// original txt is here!
#include <iostream>
#include <fstream>
#include <string>
int main()
{
std::string str1;
std::string str2;
std::ifstream file123("data.txt");
while(std::getline(file123,str1))
{
str2 = str2 + str1;
}
file123.close();
std::ofstream file("data.txt");
if(!file.is_open())
{
std::cout << "ERROR" << std::endl;
return 1;
}
file << str2 << std::endl;
file << "Add this text" << std::endl;
file.close();
return 0;
}
// data.txt
// original txt is here!
// Add this text
- 파일을 Read할 때, String을 하나 더 만들어서 기존 내용을 저장해놓고, Write할 때 이놈을 더해서 기존 DATA 유지
(백업 개념)
- 근데 file을 한 번에 read, write 목적으로 열고 닫을 때 file 이름을 동일하게 설정하면 error가 뜨네.. 그래서 그냥 variable 이름을 달리 해줌. 뭐 어려운 건 아니니까
String
- C에선 String은 Character array를 뜻했다.
- C++ STD Library는 string class를 지원하고, 이는 순차적으로 연결된 dynamic memory를 사용하는 array의 형태이다.
- String이 내포하고 있는 정보는 아래와 같다.
1) 기본적으로 text data를 포함하고 있는 주소 pointer의 data
2) 현재 text data의 size
3) Char array가 최대로 가질 수 있는 character 길이 : Capacity
- String은 header로 #include <string>이 필요하고, std::string WHATEVER <-- 형식으로 선언한다.
std::string str; //empty
std::string str1 = "hi";
std::string str1("hi");
String Concatenation
- '+' operator 를 이용해 String 간 결합이 가능하다.
// 간편하구만!
#include <iostream>
#include <string>
int main()
{
std::string one = "I";
std::string two = "Love";
std::string three = one + " " + two;
std::cout << three << std::endl;
return 0;
}
//I Love
- String에는 그리고 append 와 += 도 사용할 수 있다.
- 이 두가지 Case 모두 String이 자동으로 Update 된다.
#include <iostream>
#include <string>
int main()
{
std::string one = "I";
std::string two = "Love";
one += " Play";
two.append(" You");
std::cout << one <<std::endl<<two<<std::endl;
return 0;
}
// I Play
// Love You
// += , append 모두 string이 자동으로 update 된다.
String Comparison
- String도 " == , != , < , > Operator로 비교가 가능하다. ( Lexicographical order로! : 사전식 순서로!)
- 또는 Compare Method를 쓰는 법도 있다.
#include <iostream>
#include <string>
using namespace std;
int main()
{
string one = "ACE";
string two = "FIRE";
if(one == two)
{ cout << "'SAME'" <<endl;}
else if(one < two)
{ cout << "'TWO BIG'"<<endl;}
else
{ cout << "'ONE BIG'"<<endl;}
//'TWO BIG'
cout << one.compare(two) << endl;// one > two? --> -1
cout << one.compare(one) << endl;//0
cout << two.compare(one) << endl;// two > one?--> 1
return 0;
}
- if / else if / else 조건문을 쓸 때 compare operation 사용 가능!
Strings Finding Substrings
- Find를 통해 string 내에 substring의 위치가 어떻게 되는 지 알 수 있다.
- size_t 는 unsigned integer type이다. 보통 size 또는 count를 표현할 때 쓴다.
- string::npos 는 string class에 속하는 상수이며 size_t가 가질 수 있는 가장 큰 값을 의미한다.
(find () 가 substring을 찾는데 실패하면 string::npos를 반환한다.)
int main()
{
std::string str = "hello boy are you a girl?";
size_t pos = str.find("are");
if(pos != std::string::npos){
std::cout << "find : "<< pos <<std::endl;
}
// find : 10
size_t pos2 = str.find("ZZZ");
if(pos2 != std::string::npos){
std::cout<< "find : " <<pos2<<std::endl;
}
else{
std::cout << "ERROR" <<std::endl;
}
// ERROR
return 0;
}
- 궁금해서 해봤는데, 그냥 아래처럼 실행해도 위치 찾을 수 있다.
std::string str = "hello boy are you a girl?";
int a = str.find("boy");
std::cout << a << std::endl;
//6
- substr(position , length) 는 string에서 starting position(position) 기준 length만큼 substring을 반환한다.
#include <iostream>
#include <string>
#include "string"
int main(void)
{
std::string str = "DEATH NOTE";
std::cout << str.substr(1,3) << std::endl;
return 0;
//EAT
}
Strings Replacing Substrings
- replace( start , lengrh , replacement ) 는 string에서 start 기준 length만큼을 replacement로 바꿔준다.
#include <iostream>
#include <string>
#include "string"
using namespace std;
int main(void)
{
string str = "GOOD MORNING";
string replace = str.replace(5,3,"DAY");
cout << str << endl;
cout << replace << endl;
string replace2 = str.replace(5,3,"DAY~~~!");
cout << replace2 << endl;
cout << str << endl;
cout << replace << endl;
// GOOD DAYNING
// GOOD DAYNING
// GOOD DAY~~~!NING
// GOOD DAY~~~!NING
// GOOD DAYNING
return 0;
}
- Replace를 하는 순간 기존 string도 자동으로 replace Update가 진행된다.
Strgins - Conversion
- std::stoi , std::stod는 string을 integer나 double type으로 바꿔준다.(String 내용이 숫자여야 할 것이다.)
- 반대로 std::to_string은 숫자를 string으로 바꿔준다.
#include <iostream>
#include <string>
#include "string"
// using namespace std;
int main(void)
{
std::string num = "92";
int intnum = std::stoi(num);
double doublenum = std::stod(num);
std::cout << intnum+1<<std::endl;
std::cout << doublenum+1<<std::endl;
//93
//93
int var = 123;
std::string strvar = std::to_string(var);
std::cout << strvar << std::endl;
//123
return 0;
}
- 숫자가 아닌 String 형태를 숫자로 바꾸려고 한다면..
std::string num = "AA";
int intnum = std::stoi(num);
double doublenum = std::stod(num);
std::cout << intnum <<std::endl;
std::cout << doublenum <<std::endl;
// 에러를 마주하게 된다
/*terminate called after throwing an instance of 'std::invalid_argument'
what(): stoi*/
String - Memory
- ARRAY의 CAPA보다 큰 Szie data가 들어오면 array 주소가 reallocated 된다.
- ARRAY의 CAPA보다 큰 Szie data가 들어오면 array의 CAPA가 더 큰 사이즈로 재지정된다.
#include <iostream>
#include <string>
using namespace std;
int main()
{
string str = "Hi, I'm Marcus";
cout << "1st size: "<<str.size()<<endl;
cout << "1st capa: "<<str.capacity()<<endl;
cout << "1st address: "<<(void*)str.c_str()<<endl;
// 1st size: 14
// 1st capa: 15
// 1st address: 0x61fdf0
//쪼만한 length append
str.append("~!!");
cout << "2nd size: "<<str.size()<<endl;
cout << "2nd capa: "<<str.capacity()<<endl;
cout << "2nd address: "<<(void*)str.c_str()<<endl;
// 2nd size: 15
// 2nd capa: 15
// 2nd address: 0x61fdf0
//큰 length append
str.append("Nice to meet you ma luvey!");
cout << "1st size: "<<str.size()<<endl;
cout << "1st capa: "<<str.capacity()<<endl;
cout << "1st address: "<<(void*)str.c_str()<<endl;
// 1st size: 41
// 1st capa: 41 --> CAPA 변경!
// 1st address: 0xf66b40 --> 주소 자체가 변경!
return 1;
}
Stringstreams
- 한 stringstream에 대해 read / write를 동시에 하는 걸 방지한다. --> 무슨 말인지..? 암튼 이런 것도 있다.
#include <iostream>
#include <sstream>
int main()
{
std::stringstream test;
test<<123.456;
test<<"ABC";
test<<999;
std::cout << test.str() << std::endl;
//123.456ABC999
return 0;
}
뭐,, 이해하긴 쉬운데 외울 게 여전히 많아 보이는 C++의 세계!
계속 전진해보즈앙!
'SW 만학도 > C++' 카테고리의 다른 글
6. Out_of_class Definition & Operator Overloading (0) | 2024.04.10 |
---|---|
5. Classes (0) | 2024.04.09 |
4. Functions and Memory Management (1) | 2024.03.29 |
3. C++ Standard Library (3) (1) | 2024.03.24 |
1. C++ Standard Library (1) (0) | 2024.03.21 |