량이 님이 쓰신 글 :
: void __fastcall TForm1::LoginClick(TObject *Sender)
: {
: char inputString[3];
: String ID;
: ifstream inFile("c:\\C++ Builder\\LogIn.txt", ios::app);
: while(!inFile.getline(inputString,sizeof(inputString)).eof()){
: ID = inputString[1]; -----------//문제점
: inFile.seekg(0,inFile.beg);
: ShowMessage(ID);
: if(strcmp(InputID->Text.c_str(),ID.c_str()) == 0){
: Form1->Hide();
: LoginModuel->Show();
: Form1->Hide();
: inFile.close();
:
: }
: else{
: ShowMessage("Could not find a match for ID or Password");
: break;
: }
: }
: }
: 문제점에 있는녀석이 메모장에 이름 아이디 비밀번호순으로 읽어들이게 만들려고하는데 자꾸 아이디부분의 문자순서를 읽어들여요
: ex)STRING <-- STRING 전체를 받아와야하는데 두번째인 T만 받아오네요 ㅠ.ㅠ
답변:
편의상 <test.txt> 파일에 아래와 같은 3줄의 라인이 있다고 합시다.
<test.txt>
c++ builder
visual studio 2017
delphi 10.2
첫번째 방법으로...
여러 라인을 갖고있는 텍스트 파일로 부터 한 라인씩 순차적으로 읽어서 처리하려면...
void checkLine()
{
std::ifstream inFile("c:/test/test.txt");
for (std::string s; std::getline( inFile, s ); ) {
if ( String(s.c_str()) == Edit1->Text ) { // Edit1->Text = "visual studio 2017"
ShowMessage("found: visual studio 2017...");
return;
}
}
ShowMessage("not found");
}
두번째 방법으로...
한 라인씩 읽어들이는 방법 말고, 전체 라인을 한번에 읽어 들여놓고 나중에 후처리 하려면...
std::vector<std::string> inputArray;
// template specialization 이용
namespace std
{
template<> istream &operator>>(std::istream &istr, std::string &str)
{
return getline(istr, str);
}
}
void loadLines()
{
std::ifstream inFile("c:/test/test.txt");
std::copy( std::istream_iterator<std::string>(inFile),
std::istream_iterator<std::string>(),
std::back_inserter(inputArray) );
}
void checkLine()
{
for ( int i=0; i < inputArray.size(); ++i ) {
if ( String(inputArray[i].c_str()) == Edit1->Text ) { // Edit1->Text = "visual studio 2017"
ShowMessage("found: visual studio 2017...");
return;
}
}
ShowMessage("not found");
}
위와 같이 std::copy를 이용해서 라인별로 vector에 전체라인을 미리 로드할 수 있습니다.
그런데 istream의 >> 오퍼레이터는 디폴트로 라인 단위가 아닌, 워드 단위로 동작하기 때문에 처리가 필요한데...
이걸 위해 클래스 만든다고 수선 떨 필요 없이, 위와 같이 간단하게 template specialization 기능을 이용해서 처리하면 됩니다.
template 테크닉을 잘 써먹으면 몇 줄 안되는 코드만으로도 간단한 에디터를 쉽게 만들 수 있죠.
|