반응형
C++의 단어 쪼개기
#include <iostream>
#include <sstream>
#include <string>
#include <vector>
using namespace std;
int main()
{
string line;
while (getline(cin, line)) {
cout << line << ":" << line.length() << endl;
vector<string> tokens = split_line(line, ' ');
for (string str : tokens)
cout << str << endl;
}
return 0;
}
vector<string> split_line(string& line, char delimiter) {
vector<string> tokens;
stringstream sstream(line);
string str;
while (getline(sstream, str, delimiter))
tokens.push_back(str);
return tokens;
}
string vector를 만들어서 저장을 한 다음에 vector 자체를 return 해주는 것이 간명한 인터페이스라고 볼 수 있습니다 .이렇게 동작하도록 만들어진 함수입니다.
tokens를 저장할 벡터 즉 split_line을 선언하고 stringstream을 사용함으로써 stringstream sstream(line)을 하면 일렬로 나열된 line을 읽으며 getline(sstream, str, delimiter)를 하면 string_stream으로부터 delimiter가 나올때까지 읽어줍니다.
C의 단어 쪼개기
int main()
{
char cstr[] = " hello world! ";
string str = " hello world! ";
char* t = strtok(cstr, " ");
for (int i = 0; t != NULL; i++) {
printf("%d:%s\n", i, t);
t = strtok(NULL, " ");
}
cout << endl;
vector<string> tokens = split_line(str, ' ');
for (int i = 0; i < tokens.size(); i++) {
cout << i << ":" << tokens[i] << endl;
}
}
vector<string> split_line(string& line, char delimiter) {
vector<string> tokens;
stringstream sstream(line);
string str;
while (getline(sstream, str, delimiter))
tokens.push_back(str);
return tokens;
}
C++단어 쪼개기
#include <iostream>
#include <fstream>
#include <sstream>
#include <string>
#include <cctype>
#include <cassert>
#include <vector>
using namespace std;
struct Person {
string name, address;
string phone, email, web;
};
vector<Person> directory;
vector<string> split_line(string& line, char delimiter) {
vector<string> tokens;
stringstream sstream(line);
string str;
while (getline(sstream, str, delimiter))
tokens.push_back(str);
return tokens;
}
string trim(string str) {
int s = 0, t = str.length() - 1;
while (s < str.length() && isspace(str[s]))
s++;
while (t >= 0 && isspace(str[t]))
t--;
if (s <= t)
return str.substr(s, t - s + 1);
else
return "";
}
substr(pos, len)은 string에서 위치 pos에서 시작하여 길이가 len인 substring을 생성하는 것입니다. 그 문자열을 return해주는 것입니다. 그러면 trim이 완료가 된 것입니다.
#include <iostream>
#include <fstream>
#include <sstream>
#include <string>
#include <cctype>
#include <cassert>
#include <vector>
using namespace std;
struct Person {
string name, address;
string phone, email, web;
};
vector<Person> directory;
vector<string> split_line(string& line, char delimiter) {
vector<string> tokens;
stringstream sstream(line);
string str;
while (getline(sstream, str, delimiter))
tokens.push_back(str);
return tokens;
}
string trim(string str) {
int s = 0, t = str.length() - 1;
while (s < str.length() && isspace(str[s]))
s++;
while (t >= 0 && isspace(str[t]))
t--;
if (s <= t)
return str.substr(s, t - s + 1);
else
return "";
}
void load_data(string file_name) {
string line;
ifstream infile(file_name);
while (getline(infile, line)) {
vector<string> tokens = split_line(line, '\t');
assert(tokens.size() >= 4 && tokens.size() <= 5);
Person p;
p.name = tokens.at(0);
p.address = tokens.at(1);
p.phone = tokens.at(2);
p.email = tokens.at(3);
if (tokens.size() == 5)
p.web = tokens.at(4);
directory.push_back(p);
}
infile.close();
}
void print_person(Person& p) {
cout << p.name << ":" << endl;
cout << " Address: " << p.address << ":" << endl;
cout << " Phone: " << p.phone << ":" << endl;
cout << " Email: " << p.email << ":" << endl;
cout << " Web: " << p.web << ":" << endl;
}
void list_directory() {
for (auto& person : directory) {
print_person(person);
}
}
void search_directory(string& prefix) {
for (auto& p : directory) {
if (p.name.compare(0, prefix.size(), prefix) == 0)
print_person(p);
else if (p.name.compare(0, prefix.size(), prefix) > 0)
break;
}
}
Person get_person_info(string name) {
Person p;
string line;
p.name = name;
cout << " Address: ";
getline(cin, line);
p.address = trim(line);
cout << " Phone: ";
getline(cin, line);
p.phone = trim(line);
cout << " Email: ";
getline(cin, line);
p.email = trim(line);
cout << " Web ";
getline(cin, line);
p.web = trim(line);
return p;
}
void add_person(string name) {
Person p = get_person_info(name);
auto it = directory.begin();
while (it != directory.end() && it->name <= name)
it++;
it = directory.insert(it, p);
}
void delete_person(string name) {
string answer;
for (auto it = directory.begin(); it != directory.end(); ) {
if (it->name.compare(0, name.size(), name) == 0) {
cout << "Want to delete '" << it->name << "'?";
cin >> answer;
if (answer == "yes" || answer == "y")
it = directory.erase(it);
else
it++;
}
else if (it->name.compare(0, name.size(), name) > 0)
break;
else
it++;
}
}
void save_directory() {
ofstream outfile("address.tsv");
for (auto& p : directory)
outfile << p.name << '\t' << p.address << '\t' << p.phone
<< '\t' << p.email << '\t' << p.web << endl;
outfile.close();
}
int main() {
load_data("address.tsv");
string command, arguments;
while (1) {
cout << "$ ";
cin >> command;
if (command == "exit")
break;
if (command == "list")
list_directory();
else if (command == "find") {
getline(cin, arguments);
string name = trim(arguments);
if (name.length() <= 0)
continue;
search_directory(name);
}
else if (command == "add") {
getline(cin, arguments);
string name = trim(arguments);
if (name.length() <= 0)
continue;
add_person(name);
}
else if (command == "delete") {
getline(cin, arguments);
string name = trim(arguments);
if (name.length() <= 0)
continue;
delete_person(name);
}
else if (command == "save") {
save_directory();
}
}
return 0;
}
이렇게 c++ string은 c의 문자열보다 다루기 쉬우며 vector는 배열보다 편리합니다. 특히 참조변수는 프로그램의 성능에 도움이 되는데요. 주소 정보 중에 만약 누락된 항목이 있으면 split_line은 empty string을 생성해주기 때문에 이러한 문제도 없습니다.
반응형
'IT 프로그래밍 > 자료구조' 카테고리의 다른 글
[자료구조] 다항식의 표현 (0) | 2024.10.01 |
---|---|
[자료구조] 연결리스트 (0) | 2024.09.26 |
vector에서 원소의 삽입과 삭제 (1) | 2024.09.20 |
[C언어] 주소록 프로그램 strtok에 대한 설명 (0) | 2024.09.06 |
[C++] string 클래스와 getline 사용법 (0) | 2024.09.06 |