Q&A

  • 텍스트화일을 읽어 스트링그리드에 뿌리는 방법좀..
내용a | 내용a |내용a |내용a

내용b | 내용b |내용b |내용b

내용c | 내용c |내용c |내용c

내용d | 내용d |내용d |내용d

내용e | 내용e |내용e |내용e



텍스트화일 : 은 위와 같이 구성되어 있고..이 내용을 읽어와서

스트링그리드에 뿌려야 합니다.

제 생각엔 파일을 읽어들이고 구조체배열을 만들어 내용들을 각각

구조체에 넣은뒤...스트링 그리드에 넣어야 한다고 생각되는데..

맞는 건지..



맞다면...코딩에서 어떻게 구현을 해야할지..

3  COMMENTS
  • Profile
    이재식 2000.02.10 00:48
    이상학 wrote:

    > 내용a | 내용a |내용a |내용a

    > 내용b | 내용b |내용b |내용b

    > 내용c | 내용c |내용c |내용c

    > 내용d | 내용d |내용d |내용d

    > 내용e | 내용e |내용e |내용e

    >

    > 텍스트화일 : 은 위와 같이 구성되어 있고..이 내용을 읽어와서

    > 스트링그리드에 뿌려야 합니다.

    > 제 생각엔 파일을 읽어들이고 구조체배열을 만들어 내용들을 각각

    > 구조체에 넣은뒤...스트링 그리드에 넣어야 한다고 생각되는데..

    > 맞는 건지..

    >

    > 맞다면...코딩에서 어떻게 구현을 해야할지..





    이재식 Wrote :

    안녕하세요?



    위처럼 고정된 포맷 데이터파일 읽기에서는

    구조체까지 쓰시지 않아도 될 것 같아요.

    사실 구조체라 아니라 델에서는 레코드라고 주로 그러더라구요.



    저는 주로 이렇게 하거든요.

    방법이 편한더라구요. 저한테는. ^^



    var

    FileH : TextFile ;

    Line : integer ;

    contA : string[크기1] ;

    contB : string[크기2] ;

    contC : string[크기3] ;

    contD : string[크기4] ;

    // 여기서 크기란 실제 숫자를 의미하는데요,

    파일형식을 보니까 각각의 내용이 고정길이를 가지고

    있는 것 같아요.

    가령, 크기 1이란 내용a의 시작 칼럼에서부터 내용b의 시작칼럼전까지의

    칼럼수가 되겠죠.

    즉, 이렇게 되면 뒤에 공백이 들어갈텐데 이것은 Trim으로 제거하면 됩니다.



    begin



    AssignFile (FileH, 'c:test.txt') ; // 가령 파일경로및 이름이

    이렇다고 합시다.

    Reset (FileH) ;



    while not Eof(Fileh) do

    begin

    line := StringGrid1.RowCount - 1 ;



    Read(FileH, contA) ;

    Read(FileH, contB) ;

    Read(FileH, contC) ;

    Read(FileH, contD) ;



    StrigGrid1.Cells[0, line] := Trim(ContA) ;

    StrigGrid1.Cells[1, line] := Trim(ContB) ;

    StrigGrid1.Cells[2, line] := Trim(ContC) ;

    StrigGrid1.Cells[3, line] := Trim(ContD) ;



    StringGrid1.RowCount := StrGrid1.RowCount + 1 ;



    ReadLn (FileH) ;

    end ;



    StrGrid1.RowCount := StrGrid1.RowCount - 1 ;



    end ;



    실제 실행시켜본 내용이 아니니까 한번 해보시고

    에러가 있으면 수정하세요.

    참, 폼위에 스트링 그리드를 올려놓으시고 fixcols의 개수는 0으로 합니다.

    그리고, rowcount개수는 2로 합니다.

    칼럼의 개수는 적당히 하시면 될것같아요(위에서는 4개로 하시면 됩니다.)

    strigGrid1.cells[열, 행]으로써, 둘 다 0부터 시작합니다.

    맨 위 [0, 0], [1,0], [2,0], [3,0]에는 제목이 있어야 겠죠.



  • Profile
    이상학 2000.02.10 02:56
    이재식 wrote:

    > 이상학 wrote:

    > > 내용a | 내용a |내용a |내용a

    > > 내용b | 내용b |내용b |내용b

    > > 내용c | 내용c |내용c |내용c

    > > 내용d | 내용d |내용d |내용d

    > > 내용e | 내용e |내용e |내용e

    > >

    > > 텍스트화일 : 은 위와 같이 구성되어 있고..이 내용을 읽어와서

    > > 스트링그리드에 뿌려야 합니다.

    > > 제 생각엔 파일을 읽어들이고 구조체배열을 만들어 내용들을 각각

    > > 구조체에 넣은뒤...스트링 그리드에 넣어야 한다고 생각되는데..

    > > 맞는 건지..

    > >

    > > 맞다면...코딩에서 어떻게 구현을 해야할지..

    >

    >

    > 이재식 Wrote :

    > 안녕하세요?

    >

    > 위처럼 고정된 포맷 데이터파일 읽기에서는

    > 구조체까지 쓰시지 않아도 될 것 같아요.

    > 사실 구조체라 아니라 델에서는 레코드라고 주로 그러더라구요.

    >

    > 저는 주로 이렇게 하거든요.

    > 방법이 편한더라구요. 저한테는. ^^

    >

    > var

    > FileH : TextFile ;

    > Line : integer ;

    > contA : string[크기1] ;

    > contB : string[크기2] ;

    > contC : string[크기3] ;

    > contD : string[크기4] ;

    > // 여기서 크기란 실제 숫자를 의미하는데요,

    > 파일형식을 보니까 각각의 내용이 고정길이를 가지고

    > 있는 것 같아요.

    > 가령, 크기 1이란 내용a의 시작 칼럼에서부터 내용b의 시작칼럼전까지의

    > 칼럼수가 되겠죠.

    > 즉, 이렇게 되면 뒤에 공백이 들어갈텐데 이것은 Trim으로 제거하면 됩니다.

    >

    > begin

    >

    > AssignFile (FileH, 'c:test.txt') ; // 가령 파일경로및 이름이

    > 이렇다고 합시다.

    > Reset (FileH) ;

    >

    > while not Eof(Fileh) do

    > begin

    > line := StringGrid1.RowCount - 1 ;

    >

    > Read(FileH, contA) ;

    > Read(FileH, contB) ;

    > Read(FileH, contC) ;

    > Read(FileH, contD) ;

    >

    > StrigGrid1.Cells[0, line] := Trim(ContA) ;

    > StrigGrid1.Cells[1, line] := Trim(ContB) ;

    > StrigGrid1.Cells[2, line] := Trim(ContC) ;

    > StrigGrid1.Cells[3, line] := Trim(ContD) ;

    >

    > StringGrid1.RowCount := StrGrid1.RowCount + 1 ;

    >

    > ReadLn (FileH) ;

    > end ;

    >

    > StrGrid1.RowCount := StrGrid1.RowCount - 1 ;

    >

    > end ;

    >

    > 실제 실행시켜본 내용이 아니니까 한번 해보시고

    > 에러가 있으면 수정하세요.

    > 참, 폼위에 스트링 그리드를 올려놓으시고 fixcols의 개수는 0으로 합니다.

    > 그리고, rowcount개수는 2로 합니다.

    > 칼럼의 개수는 적당히 하시면 될것같아요(위에서는 4개로 하시면 됩니다.)

    > strigGrid1.cells[열, 행]으로써, 둘 다 0부터 시작합니다.

    > 맨 위 [0, 0], [1,0], [2,0], [3,0]에는 제목이 있어야 겠죠.

    >



    [재질문..]

    내용a | 내용a |내용a |내용a

    내용b | 내용b |내용b |내용b

    내용c | 내용c |내용c |내용c

    내용d | 내용d |내용d |내용d

    내용e | 내용e |내용e |내용e

    에서 열의 갯수가 가변적으로 증가된다면..

    contA : string[크기1] ; <<-- 를 사용할 수 없다고 생각됩니다...

    이부분을 배열로 사용해야 할텐데..그럼..동적배열이 되거든요..

    전 일단 이렇게 코딩을 했는데...스트링에 동적배열이라면..배열의 갯수를 셀수 없네요..

    도와주세요..

    f: file; //핸들러

    moni_array : array of array of string;//배열선언..



    var

    i,j : integer;

    // g1,g2,g3,g4,g5,G6,G7 : String;



    begin

    assignfile(f,'monitor.dat'); //데이터 파일 read

    reset(f);

    while not eof(f) do

    begin

    { for j := 1 to moni_array do

    begin

    for i :=0 to 6 do

    begin

    readln(f,moni_array[i,j]);//파일의 한줄을 읽어서 moni_array[i,j]에 넣는다.



    g1 := copy( moni_array[i,j],0,14);//저장된 내용에서 필요한 문자열만큼 끊어서

    // 변수에 저장

    g2 := copy( moni_array[i,j],16,3);

    g3 := copy( moni_array[i,j],21,3);

    g4 := copy( moni_array[i,j],26,7);

    g5 := copy( moni_array[i,j],31,3);

    g6 := copy( moni_array[i,j],36,3);

    g7 := copy( moni_array[i,j],41,4);//필드별로 저장..



    //스트링그리드에 데이터 삽입..

    StringGrid1.Cells[i,j] := inttostr(g1);

    StringGrid1.Cells[i,j] := strtoint(g2);

    StringGrid1.Cells[i,j] := strtoint(g3);

    StringGrid1.Cells[i,j] := strtoint(g4);

    StringGrid1.Cells[i,j] := strtoint(g5);

    StringGrid1.Cells[i,j] := strtoint(g6);

    StringGrid1.Cells[i,j] := strtoint(g7);





    end;

    end;}

  • Profile
    이재식 2000.02.10 05:48
    이재식 Wrote :

    안녕하세요?



    잘 보았습니다.

    우선 소스를 보니까, 두가지에서 실수를 하신것 같습니다.

    스트링 그리드에 대입할때는 strToInt를 할수 없고요, 일반 기본형

    데이터들은 문자타입으로 전환되어야 합니다. 즉, IntToStr이 될 것입니다.

    그리고, moni_array를 동적배열로 잡으시고서 SetLength함수를 이용해서

    그 크기를 결정해야 되는데, 그런 문장이 없습니다.

    그러면 실행도중 운이 없으면 다운됩니다.



    그리고, 배열의 크기는 High, Low함수를 이용해서 그 크기를 알 수 있고요,

    sizeof함수를 통해서 우리는 메모리에 할당된 크기를 알 수 있습니다.



    그리고, for문을 두번 돌려서 코딩을 하셨는데요,

    제가 분석할때볼땐 의도에서 벗어난 반복문이라고 생각됩니다.



    길이가 가변적이라 동적배열을 생각하셨는데요,

    그러나, 밑에 코딩을 보면 한 라인을 읽은뒤 copy함수를 써서

    분리해 내고 있습니다.



    그렇다면, 사실 동적배열은 필요가 없습니다.

    왜냐하면, copy함수를 써서 분리해낼때 시작위치서부터 개수가 상수로

    고정되어 있습니다. (소스를 보니까요, 아래처럼)

    g1 := copy( moni_array[i,j],0,14);//저장된 내용에서 필요한 문자열만큼 끊어서

    // 변수에 저장

    g2 := copy( moni_array[i,j],16,3);

    g3 := copy( moni_array[i,j],21,3);

    g4 := copy( moni_array[i,j],26,7);

    g5 := copy( moni_array[i,j],31,3);

    g6 := copy( moni_array[i,j],36,3);

    g7 := copy( moni_array[i,j],41,4);//필드별로 저장..



    그리고, 곧바로 스트링 그리드에 저장을 했습니다.

    문제는 한라인을 읽어서 분리를 할 것이라면

    그냥 ReadLn함수를 쓰시면 되고요, 거기서 한 라인 읽은 데이터를

    copy함수로 분리해내는것이 바람직하다고 생각됩니다.



    제 생각에는 실제로 데이터 파일은 올려놓으신 형식과 많이 다른 것 같습니다.



    위에서 보니까, g1~~g7이 읽는 시작위치와 길이가 정해져 있는데요,

    분명히, copy(내용, 시작위치, 개수)에서

    시작위치와 개수가 각각 상수로 되어있잖아요?



    어떤것이 동적배열 특성을 갖기에 동적배열 선언해서 코딩을 하는것인지

    잘 모르겠습니다.



    물론 동적배열로 선언해서 코딩하는 방법 알려드리고 싶습니다만,

    제 생각에는 그럴 필요가 없거든요.

    쉬운 방법으로 해결하는 것이 좋을 듯 합니다.



    다시한번 데이터파일에대해서만이라도 설명을 추가해 주시거나

    아니면, 저에게 데이터 파일을 보내주셨으면 합니다.

    실제 데이터 파일과 님께서 코딩하신 내용을 같이 보면 님께서

    어떻게 생각을 하셨고, 위처럼 코딩하신 이유를 알 것 같습니다.

    괜찮다면, 제가 스트링그리드에 담아드릴 수도 있습니다.