[MFC] CSV 파일을 읽어 해당 데이터 파싱하여 CArray 배열에 저장하는 방법

[MFC] CSV 파일을 읽어 해당 데이터 파싱 및 배열에 저장하는 방법

 

이번 포스팅에서는 MFC 환경에서 CSV 파일을 읽어 그 안에 있는 해당 데이터들을 파싱하고, 또한 파싱된 데이터를 자료구조 중 하나인 배열에 저장해서 메모리 상에서 보관하는 방법에 대하여 알아보도록 하겠습니다.

 

실제 실무에서도 많이 사용되니까 알아두시면 유용하게 사용 및 응용이 가능 하실거라 생각합니다.


 

그러면 대화상자 기반의 MFC 프로젝트를 아래와 같이 생성하여 주시기 바랍니다.




 

MFC 프로젝트를 생성하셨다면 빈 폼에 Button 컨트롤 하나를 아래와 같이 배치하여 주시기 바랍니다.



 

여기까지 하셨다면 이제 엑셀을 실행시켜서 더미 .csv 파일을 생성해 주시기 바랍니다. 안에 데이터는 아무거나 입력해서 저장해도 상관 없습니다.


참고로 저는 아래와 같이 입력하여 범범조조.csv 파일을 저장하였습니다.




여기까지 진행을 모두 완료하였다면, 이제 버튼 클릭 이벤트 함수에 아래와 같이 코드를 작성해 주시기 바랍니다.

 

[testDlg.h]

 

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

 

// testDlg.h : 헤더 파일

//

 

#pragma once

#include "afxwin.h"

 

 

struct Human

{

    CString age;

    CString name;

 

    Human()

    {

        age.Empty();

        name.Empty();

    }

};

 

// CtestDlg 대화 상자

class CtestDlg : public CDialogEx

{

// 생성입니다.

public:

    CtestDlg(CWnd* pParent = NULL);    // 표준 생성자입니다.

public:

    CArray<Human*, Human*> m_arrHuman; //배열 변수 선언

 

// 대화 상자 데이터입니다.

    enum { IDD = IDD_TEST_DIALOG };

 

    protected:

    virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV 지원입니다.

    void    RemoveAll();

 

// 구현입니다.

protected:

    HICON m_hIcon;

 

    // 생성된 메시지  함수

    virtual BOOL OnInitDialog();

    afx_msg void OnSysCommand(UINT nID, LPARAM lParam);

    afx_msg void OnPaint();

    afx_msg HCURSOR OnQueryDragIcon();

    DECLARE_MESSAGE_MAP()

public:

    afx_msg void OnBnClickedButton1();

    CStatic m_static1;

};

 

Colored by Color Scripter

cs

 

[testDlg.cpp]


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

void    CtestDlg::RemoveAll() //배열 초기화  해제

{

    for ( int i = 0 ; i < m_arrHuman.GetSize() ; ++i ) //해당 배열의 사이즈 만큼 반복문 돌려서

    { 

        Human *pHuman = m_arrHuman.GetAt( i );   //해당 배열의 값을 매칭시켜준다.

 

        if ( NULL == pHuman ) //pHuman 객체가 Null이면 계속 진행하고

            continue;

 

        delete pHuman;    //그렇지 않을 경우 객체 삭제

 

        pHuman = NULL;

    }

 

    m_arrHuman.RemoveAll();  //배열 삭제

}

 

 

 

void CtestDlg::OnBnClickedButton1()

{

    // TODO: 여기에 컨트롤 알림 처리기 코드를 추가합니다.

    RemoveAll(); //배열 초기화  해제

 

    _tsetlocale( LC_ALL, "Korean" ); //한국 지역으로 설정

 

    CString strFilePath = _T(""); //.csv 파일 읽을 위치  파일명 저장할 변수 선언

    strFilePath.Format("C:\\Users\\범범조조\\Desktop\\범범조조.csv"); //해당 csv 파일이 저장되어 있는 경로 추가

 

    FILE *fp = NULL//파일 객체 선언

    fopen_s(&fp, strFilePath, "r"); //해당 경로에 파일을 읽어라

 

    if(fp) //해당 파일이 있고

    {

        char szContent[2048= {0, };

 

        memset(szContent, NULL2048);

 

        while(fgets(szContent, 2048, fp)) //파일을  라인씩 읽어라

        {

            CString strContent;

 

            strContent.Format("%s", szContent);

 

            memset(szContent, NULL2048);

 

            if(strContent.Find("#">= 0//만약 csv 파일 안의 데이터  # 있으면 건너 뛰어라

                continue;

 

            strContent.Remove('\r');

            strContent.Remove('\n');

 

            strContent = _T(strContent); //유니코드 변환하여 저장

 

            Human *pHuman = new Human;

 

            CString rString;

            int nSubString = 0;

              

              //AfxExtractSubString() 함수를 이용하여 해당 CSV 파일은 , 단위로 

            while(AfxExtractSubString(rString, strContent, nSubString++',')) 

            {

                switch(nSubString)

                {

                case 1: pHuman->age = _T( rString ); break;

                case 2: pHuman->name = _T( rString ); break;

                }

            }

            

            m_arrHuman.Add(pHuman);

        }

 

        fclose(fp); //파일 닫기

    }

 

 

    //CArray에서 현재 보관하고 있는 값을 출력 하고 싶을  사용하면 된다.

    //for(int i = 0; i < m_arrHuman.GetSize(); i++)

    //{

    //    Human *pHuman = m_arrHuman.GetAt(i);

 

    //    AfxMessageBox(pHuman->name); //이름 출력

    //}

}

Colored by Color Scripter

cs

 

위의 코드가 CSV 파일을 읽어 파싱한 후, CArray 배열에 저장하는 코드입니다.


실제 해당 배열의 값을 출력하고 싶으시다면 for(int i = 0; i < m_arrHuman.GetSize(); i++) 이와 같은 반복문 안에 Human 객체를 새롭게 선언하여 해당 객체에 m_arrHuman.GetAt(i) 값을 넣어줘서 Static 컨트롤로 출력을 하던지, 아니면 AfxMessageBox() 함수를 이용하여 출력을 하던지 해서 값이 제대로 들어 갔는지 확인을 하시면 됩니다.

 

또한, 문자열을 파싱해주는 AfxExtractSubstring 함수를 간단히 설명 드리자면, 위 함수는 .txt 파일 또는 .csv 파일을 읽어 구분자별로 정리하여야 할 경우에 유용하면서 실제 매개변수는 AfxExtractSubstring(“저장할 변수”, “파싱할 문자열”, “파싱할 구역”, “구분자”) 이렇게 매개변수를 알맞게 집어 넣으시면 됩니다.

 

이로써 MFC 에서 CSV 파일을 읽어서 내부 데이터는 CArray 배열 객체에 저장하는 방법에 대해서 알아봤습니다.


 

감사합니다.^^


728x90

'C++ > MFC' 카테고리의 다른 글

[MFC] UpdateData() 함수 사용 방법  (0) 2018.08.01
[MFC] 메시지 박스 사용 방법  (0) 2018.08.01
[MFC] CList 사용 방법  (0) 2018.07.23
[MFC] C++ 파일 라인 수 읽는 방법  (0) 2018.07.23
MFC 폴더 생성 방법  (0) 2018.07.10

이 글을 공유하기

댓글

Designed by JB FACTORY