[C++] CSV 파일을 읽어, MFC 환경에서 ListControl을 이용하여 데이터 보여주는 방법

[C++] CSV 파일을 읽어, MFC 환경에서 ListControl을 이용하여 데이터 보여주는 방법


 

이번 포스팅에서는 지난번에 학습 하였던 C++ 기반으로 CSV파일을 읽어와 그 안의 내부 데이터를 STL 자료구조들을 이용하여 메모리에 저장 후, MFC 컨트롤 중 하나인 ListControl에 데이터를 보여주는 방법에 대해서 알아보도록 하겠습니다.

 

우선 대화 상자 기반으로 MFC 프로젝트를 생성하여 주시기 바랍니다.




위와 같이 MFC 대화상자 기반의 프로젝트가 생성된 것을 확인하실 수 있습니다


그러면 다이얼로그 위에 올려져 있는 확인, 취소 버튼과 static 컨트롤들을 삭제하여 주시고 아래와 같이 도구상자에서 ListControl을 검색하여 아래와 같이 배치하여 주시기 바랍니다.




그리고 오른쪽 속성창에서 ViewReport로 변경하여 주시기 바랍니다.


또한, 멤버변수 m_List를 아래와 같이 추가하여 주시기 바랍니다.





그리고 나서 지난번에 C++ 기반으로 CSV 파일을 읽었던 코드를 클래스화 하여 추가해줍니다


코드는 아래와 같이 추가하여 주시면 됩니다.


우선 클래스 마법사를 이용하여 CFileRead.cpp, CFileRead.h, CSingleton.cpp, CSingleton.h 파일들을 선언하여 주세요. 방법은 아래와 같이 추가해 주시면 됩니다.






그리고 CFileRead.cpp, CFileRead.h, CSingleton.cpp, CSingleton.h 파일들을 아래 코드처럼 똑같이 입력해 주시기 바랍니다.


CFileRead.h


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

#pragma once

 

#include <iostream>

#include <fstream>

#include <string>

#include <vector>

#include <hash_map>

#include <sstream>

#include <istream>

 

using namespace std;

 

class CFileRead : public CSingleton<CFileRead>

{

public:

    CFileRead(void);

    ~CFileRead(void);

 

    vector<string> csv_read_row(istream &file, char delimiter);

};

 

 

Colored by Color Scripter

cs

 

CFileRead.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

#include "stdafx.h"

#include "FileRead.h"

 

 

CFileRead::CFileRead(void)

{

}

 

 

CFileRead::~CFileRead(void)

{

}

 

//CSV 파일 읽는 함수

vector<string> CFileRead::csv_read_row(istream &file, char delimiter)

{

    stringstream ss;

    bool inquotes = false;

    vector<string> row;//relying on RVO

 

    while(file.good())

    {

        char c = file.get();

        if (!inquotes && c=='"'

        {

            inquotes=true;

        }

        else if (inquotes && c=='"'

        {

            if ( file.peek() == '"')

            {

                ss << (char)file.get();

            }

            else 

            {

                inquotes=false;

            }

        }

        else if (!inquotes && c==delimiter) 

        {

            row.push_back( ss.str() );

            ss.str("");

        }

        else if (!inquotes && (c=='\r' || c=='\n') )

        {

            if(file.peek()=='\n') { file.get(); }

            row.push_back( ss.str() );

            return row;

        }

        else

        {

            ss << c;

        }

    }

}

Colored by Color Scripter

cs

 

CSingleton.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

52

53

54

55

56

57

58

59

60

61

#pragma once

#include <memory>

 

template < typename T >

 

class CSingleton

{

public:

    CSingleton()

    {

 

    }

 

    virtual ~CSingleton()

    {

 

    }

 

    static void CreateClass()

    {

        if ( NULL == m_pMgr )

        {

            m_pMgr = new T;

        }

    }

 

    static void DestroyWnd()

    {

        if ( m_pMgr )

        {

            m_pMgr->DestroyWindow();

 

            delete m_pMgr;

 

            m_pMgr = NULL;

        }

    }

 

    static void DestroyClass()

    {

        if ( m_pMgr )

        {

            delete m_pMgr;

 

            m_pMgr = NULL;

        }

    }

 

    static T* GetMgr()

    {

        return m_pMgr;

    }

private:

    static T* m_pMgr;

 

};

 

template < typename T >

 

T* CSingleton< T >::m_pMgr = NULL;

 

Colored by Color Scripter

cs

 

CSingleton.cpp


1

2

3

4

#include "stdafx.h"

#include "Singleton.h"

 

 

cs

 

stdafx.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

52

53

54

55

 

// stdafx.h : 자주 사용하지만 자주 변경되지는 않는

// 표준 시스템 포함 파일  프로젝트 관련 포함 파일이 

// 들어 있는 포함 파일입니다.

 

#pragma once

 

#ifndef VC_EXTRALEAN

#define VC_EXTRALEAN            // 거의 사용되지 않는 내용은 Windows 헤더에서 제외합니다.

#endif

 

#include "targetver.h"

 

#define _ATL_CSTRING_EXPLICIT_CONSTRUCTORS      // 일부 CString 생성자는 명시적으로 선언됩니다.

 

// MFC 공통 부분과 무시 가능한 경고 메시지에 대한 숨기기를 해제합니다.

#define _AFX_ALL_WARNINGS

 

#include <afxwin.h>         // MFC 핵심  표준 구성 요소입니다.

#include <afxext.h>         // MFC 확장입니다.

 

 

#include <afxdisp.h>        // MFC 자동화 클래스입니다.

 

#include "Singleton.h"

 

#ifndef _AFX_NO_OLE_SUPPORT

#include <afxdtctl.h>           // Internet Explorer 4 공용 컨트롤에 대한 MFC 지원입니다.

#endif

#ifndef _AFX_NO_AFXCMN_SUPPORT

#include <afxcmn.h>             // Windows 공용 컨트롤에 대한 MFC 지원입니다.

#endif // _AFX_NO_AFXCMN_SUPPORT

 

#include <afxcontrolbars.h>     // MFC 리본  컨트롤 막대 지원

 

 

 

 

 

 

 

 

 

#ifdef _UNICODE

#if defined _M_IX86

#pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='x86' publicKeyToken='6595b64144ccf1df' language='*'\"")

#elif defined _M_X64

#pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='amd64' publicKeyToken='6595b64144ccf1df' language='*'\"")

#else

#pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'\"")

#endif

#endif

 

 

 

Colored by Color Scripter

cs

 

여기까지 작성을 완료하셨다면 이제 ListControltestDlg.cpp 코드에서 OnInitDialog 함수에 아래와 같은 코드를 추가하여 주시기 바랍니다.

 

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

84

85

86

87

88

89

90

91

92

93

94

95

// CListControlTestDlg 메시지 처리기

 

BOOL CListControlTestDlg::OnInitDialog()

{

    CDialogEx::OnInitDialog();

 

    // 시스템 메뉴에 "정보..." 메뉴 항목을 추가합니다.

 

    // IDM_ABOUTBOX 시스템 명령 범위에 있어야 합니다.

    ASSERT((IDM_ABOUTBOX & 0xFFF0== IDM_ABOUTBOX);

    ASSERT(IDM_ABOUTBOX < 0xF000);

 

    CMenu* pSysMenu = GetSystemMenu(FALSE);

    if (pSysMenu != NULL)

    {

        BOOL bNameValid;

        CString strAboutMenu;

        bNameValid = strAboutMenu.LoadString(IDS_ABOUTBOX);

        ASSERT(bNameValid);

        if (!strAboutMenu.IsEmpty())

        {

            pSysMenu->AppendMenu(MF_SEPARATOR);

            pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);

        }

    }

 

    //  대화 상자의 아이콘을 설정합니다응용 프로그램의  창이 대화 상자가 아닐 경우에는

    //  프레임워크가  작업을 자동으로 수행합니다.

    SetIcon(m_hIcon, TRUE);            //  아이콘을 설정합니다.

    SetIcon(m_hIcon, FALSE);        // 작은 아이콘을 설정합니다.

 

    // TODO: 여기에 추가 초기화 작업을 추가합니다.

    CRect rect;

    m_List.GetClientRect(&rect);

 

    //칼럼 추가

    m_List.InsertColumn(0, _T("이름"), LVCFMT_LEFT, 220); //ListControl 헤더 추가

    m_List.InsertColumn(1, _T("나이"), LVCFMT_LEFT, rect.Width());//ListControl 헤더 추가

 

 

    CFileRead::CreateClass(); //Singletone  이용하여 FileRead 클래스 생성

 

    CFileRead* fileRead = CFileRead::GetMgr();

 

    vector<string> name;

    vector<string> age;

    //hash_map<string, string> MesName; 

 

    //ifstream 파일을 읽게 해주는 함수로써 ifstream (파일명 or 경로)

    ifstream file("C:\\Users\\Desktop\\test.csv"); 

 

    if (file.fail())  //만약 bad() 함수가 실패 하면..

    {

        return MessageBox(_T("해당 경로에 위치하는 파일이 존재하지 않습니다."));

    }

 

 

    while(file.good()) //eof, bad, fail 함수가 거짓의 참을 반환할 때까지..

    {

        vector<string> row = fileRead->csv_read_row(file, ',');

 

        if(!row[0].find("#")) //만약 csv 파일 안에 # 문자가 있을경우

        {

            continue//그냥 건너 뛰어라

        }

        else //#문자가 없을 경우

        {

            for(int i=0, leng=row.size()-1; i<leng; i++)

            {

                name.push_back(row[0]);

                age.push_back(row[1]);

            }

        }

    }

 

    file.close(); //파일 입출력 완료  닫아준다.

 

    CString NAME = _T("");

    CString AGE = _T("");

 

 

    for(int i = 0; i < name.size(); i++)

    {

        NAME.Format(_T("%s"), name.at(i).c_str());

        NAME.Replace(_T(" "), NULL);

        m_List.InsertItem(i, NAME);

 

        AGE.Format(_T("%s"), age.at(i).c_str());

        AGE.Replace(_T(" "),NULL);

        m_List.SetItemText(i,1,AGE);            

    }

 

    return TRUE;  // 포커스를 컨트롤에 설정하지 않으면 TRUE 반환합니다.

}

 

Colored by Color Scripter

cs

 

그리고 엑셀에서 test.csv 파일을 생성해 주시고 저는 내용을 아래와 같이 입력하여 파일을 생성하였습니다.





 

마지막으로 MFC 프로제트를 실행 시키시면 아래와 같이 리스트컨트롤에 CSV파일의 내용을 그대로 가져와 보여주는 것을 확인하실 수 있습니다.




이로써 C++을 기반으로 CSV파일을 읽어와 MFC ListControl에 보여주는 방법에 대해서 학습을 마치도록 하겠습니다.


감사합니다.^^


728x90

이 글을 공유하기

댓글

Designed by JB FACTORY