|
어제 집에 툴이 없는지라 테스틀 못해서 지금 올리네요ㅎㅎ
기존 소스에다 그리드 출력을 짜집기 하느라 엉망이지만 대충 보시고 이해용도로 쓰세요.
1. 파일을 통째로 읽고
2. CR+LF(줄바꿈)단위로 자릅니다. 즉, 한줄마다 AnsiString에 넣습니다.
3. 그 내용을 TStringList에 넣어서 Delimiter를 Tab(char(9))으로 구분하면 나뉘어 집니다.
4. 총 분할개수가 4개(날짜, 데이터1, 데이터2, 데이터3)일때만 데이터를 읽어 그리드에 출력합니다.
4개일때만 읽으므로 헤더부분이나 잘못된 행은 읽지 않습니다.
//////////////////////////////////////////////////////////////
bool TForm1::LoadFromFile(AnsiString pFileName)
{
int iFileHandle, iFileLength;
int iRow, iBegin, iEnd;
int iRowIndex;
AnsiString asDateTime, asBuffer, asString;
double dData01, dData02, dData03;
char *cBuffer;
TStringList *slTemp;
iRowIndex = 1;
if(pFileName == "")
pFileName = "data.dat";
try{
// 파일 검사후 파일이 있으면 읽고 아니면 실패
if(FileExists(pFileName)){
// 파일이 있으므로 읽는다.
iFileHandle = FileOpen(pFileName, fmOpenReadWrite);
// 파일의 끝으로 이동하여 총 길이를 구한다.
iFileLength = FileSeek(iFileHandle, 0, 2);
// 다시 처음으로 이동한다.
FileSeek(iFileHandle, 0, 0);
// 버퍼를 읽을 크기만큼 초기화한다.
cBuffer = new char[iFileLength + 1];
// 파일에서 크기만큼 데이터를 읽고 바이트수를 저장한다.
FileRead(iFileHandle, cBuffer, iFileLength);
// 파일을 닫는다.
FileClose(iFileHandle);
// 버퍼를 cr + lf까지 읽고 ,(comma)로 구분하여 구조체에 저장한다.
iRow = 1;
asDateTime = "";
dData01 = 0;
dData02 = 0;
dData03 = 0;
iBegin = iRow;
iEnd = iBegin;
asBuffer = (AnsiString)cBuffer;
while(iRow <= asBuffer.Length()){
// cr과 lf를 찾는다.
if((asBuffer[iRow] == char(13)) & (iRow + 1) <= asBuffer.Length()){
if(asBuffer[iRow + 1] == char(10)){
// cr+lf전까지 한줄을 읽는다.
iEnd = iRow - 1;
if(iBegin > 0 & iEnd > 0 & iBegin < iEnd){
asString = asBuffer.SubString(iBegin, iEnd - iBegin + 1);
// StringList에 넣은 후, comma로 구분한다.
slTemp = new TStringList;
slTemp->Clear();
slTemp->Delimiter = char(9);
slTemp->DelimitedText = asString;
// comma 구분시 나눠진 데이터가 4개일때만 추가한다.
if(slTemp->Count == 4){
asDateTime = slTemp->Strings[0];
dData01 = StrToFloat(slTemp->Strings[1]);
dData02 = StrToFloat(slTemp->Strings[2]);
dData03 = StrToFloat(slTemp->Strings[3]);
// Grid 출력
GridData->RowCount = GridData->RowCount + 1;
GridData->Cells[0][iRowIndex] = asDateTime;
GridData->Cells[1][iRowIndex] = FloatToStr(dData01);
GridData->Cells[2][iRowIndex] = FloatToStr(dData02);
GridData->Cells[3][iRowIndex] = FloatToStr(dData03);
iRowIndex++;
}
delete slTemp;
slTemp = NULL;
}
// lf는 건너뛴다.
iRow++;
// 새로운 Begin과 End를 설정한다.
iBegin = iRow;
iEnd - iBegin;
}
}
iRow++;
}
// 버퍼는 클리어 한다.
delete [] cBuffer;
}
else{
return false;
}
}
catch(...){
if(!iFileHandle){
FileClose(iFileHandle);
iFileHandle = NULL;
}
return false;
}
return true;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
GridData->RowCount = 1;
GridData->ColCount = 4;
LoadFromFile(ExtractFilePath(Application->ExeName) + "data.dat");
}
//---------------------------------------------------------------------------
///////////////////////////////////////////////////
네버 님이 쓰신 글 :
: 알려주신데로 하는데
: while(!feof(sfp)) {
: : if(fgets(buffer, sizeof(buffer), sfp) == NULL) break;
: 여기에서 buffer를 설정할때 AnsiString 로하는건가요?
:
: 근데 AnsiString 로 설정하고 할 경우
: a = buffer.pos(char(9)); // 9번 ASCII코드가 TAB문자에요.
: : RecodeTime = buffer.SubString(1, a); // 처음부터 탭문자까지 날짜로 읽음
: : buffer = buffer.SubString(a, buffer.Length() - a); // 읽은 글자는 지웁니다.
: :
: : b = buffer.pos(char(9));
: : Data01 = FormatFloat("0,00", buffer.SubString(a, b)); // 첫번째 탭문자부터 다음 탭문자까지 데이터 읽음
: : buffer = buffer.SubString(b, buffer.Length() - b); // 읽은 글자는 지웁니다.
: :
: : c = buffer.pos(char(9));
: : Data02 = FormatFloat("0,00", buffer.SubString(b, c));
: [C++ Error] uComm.cpp(1642): E2342 Type mismatch in parameter 'index' (wanted 'int', got 'AnsiString')
: 이러한 에러들이 발생합니다.
:
: [C++ Error] uComm.cpp(1636): E2034 Cannot convert 'AnsiString' to 'char *'
: 이런 메세지도요.
:
: 그래서 TStringList *data=new TStringList();
: data->LoadFromFile(File_Open.c_str());
:
: 이런식으로 사용하게 되면 data->string.pos는 가능하나
: Data01 = FormatFloat("0,00", buffer.SubString(a, b)); // 첫번째 탭문자부터 다음 탭문자까지 데이터 읽음
: 이것처럼 첫번째 탭에서 다음 탭사이의 데이타를 읽어 주는게 나타나질 않습니다.
:
: 답변 다시 한번 부탁드릴게요
:
|