본문 바로가기
프로그래밍/C++

C++ ] 2021 교통사고 통계자료 필터 프로그램 (1) + 파일 입출력

by eteo 2022. 6. 28.

 

 

부분합 기능까지 구현하였다.

 

main.h

#pragma once

#define COLUMN_NUMBER 13
#define ROW_NUMBER 229

enum
{
	PRINTLIST=1,
	SUBTOTAL,
	EXIT
};

 

 

 

main.cpp

#include <iostream>
#include "AccidenData.h"
#include "AccidentList.h"
#include "main.h"
#include <Windows.h>

using namespace std;

int main()
{
	AccidentList list;

	list.readListFromFile();

	while(1)
	{	
		system("cls");
		int select;
		list.DispMenu();
		cin >> select;

		switch(select)
		{
		case PRINTLIST:
			list.searchList();
			break;
		case SUBTOTAL:
			list.SearchSubTotal();
			break;
		case EXIT:
			return 0;
		default:
			cin.clear();
			cin.ignore(1000, '\n');
			cout << endl << "잘못 누르셨습니다. 다시 선택해 주세요." << endl;
			Sleep(300);
			break;
		}

	}

	return 0;
}

 

 

 

 

 

AccidentList.h

#pragma once
#include "AccidenData.h"
#include "main.h"
#include <sstream>
#include <fstream>
#include <string>

class AccidentList
{
private:
	AccidentData** list;

public:
	AccidentList();

	void DispMenu();
	void printTitle();
	void printSubject();
	void readListFromFile();
	void printRow(int i);
	void printAll();
	void searchList();
	void SearchSubTotal();

	~AccidentList(){};
};

 

원래 AccidentData를 포인터 배열로 했었는데 이중포인터로 바꿨다. 아래 생성자에서 동적할당한다. AccdentData 포인터를 담을 수 있는 길이가 ROW_NUMBER 인 배열을 할당하고 그 시작 주소를 list 에 대입해 배열처럼 사용한다.

 

 

 

AccidentList.cpp

#include "AccidentList.h"
#include "AccidenData.h"
#include <stdio.h>
#include <Windows.h>
#include "AccidenData.h"

AccidentList::AccidentList()
{
	list = new AccidentData* [ROW_NUMBER];
	for(int i=0; i< ROW_NUMBER; i++)
	{
		list[i] = NULL;
	}
}

void AccidentList::printTitle()
{
	cout << "=================== 교통사고 통계 검색 프로그램 ===================" << endl << endl;
}

void AccidentList::DispMenu()
{
	cout << "=================== 교통사고 통계 검색 프로그램 ===================" << endl << endl;
	cout << "키워드 검색 후 실행할 메뉴를 선택해주세요." << endl<< endl;
	cout << " 1. 리스트 보기" << endl << endl;
	cout << " 2. 부분합 보기" << endl << endl;
	cout << " 3. 종료" << endl << endl;
	cout << "선택: [_]\b\b";
}

void AccidentList::readListFromFile()
{
	ifstream data("ANSIData.csv");
	string line;

	int i = 0;

	while (getline(data, line))
	{
		stringstream linestream(line);
		string cell[13];
		for (int j = 0; j < COLUMN_NUMBER; j++)
		{
			getline(linestream, cell[j], ',');
		}
		list[i] = new AccidentData(cell[0], cell[1], &cell[2]);
		i++;
	}
}

void AccidentList::printSubject()
{
	printf("시도,시군구,터널안,교량위,고가도로위,지하차도(도로)내,기타단일로,교차로내,교차로횡단보도,교차로부근,철길건널목,기타,불명\n");
}

void AccidentList::printRow(int i)
{
	cout << list[i]->GetSiDo() << "," << list[i]->GetSiGunGoo() << ",";

	for (int j = 0; j < LOCATION_NUMBER; j++)
	{
		cout << *(list[i]->GetAccidentCount() + j);
		if (j != LOCATION_NUMBER - 1)
		{
			cout << ",";
		}
	}
	cout << endl;
}

void AccidentList::printAll()
{
	printSubject();
	for(int i=0; i<ROW_NUMBER;i++)
	{		
		printRow(i);
	}
}

void AccidentList::searchList()
{
	system("cls");
	printTitle();
	string keyword;
	cout << "검색어를 입력하세요 (시도 또는 시군구) ..... [                        ]\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b";	
	cin >> keyword;
	int chk=0;
	cout << endl;

	for(int i=0; i<ROW_NUMBER;i++)
	{
		if(keyword.compare(list[i]->GetSiDo())==0)
		{
			printRow(i);
			chk++;
		}
	}

	if(chk==0)
	{
		for (int i = 0; i < ROW_NUMBER; i++)
		{
			if (keyword.compare(list[i]->GetSiGunGoo()) == 0)
			{
				printRow(i);
				
			}
		}
	}

	cout << endl;
	system("pause");

}

void AccidentList::SearchSubTotal()
{
	system("cls");
	printTitle();
	string keyword;
	cout << "검색어를 입력하세요 (시도 또는 시군구) ..... [                   ]\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b";
	cin >> keyword;
	int chk = 0;
	cout << endl;
	int subTotal[LOCATION_NUMBER];

	for (int i = 0; i < LOCATION_NUMBER; i++)
	{
		subTotal[i] = 0;
	}

	for (int i = 0; i < ROW_NUMBER; i++)
	{
		if (keyword.compare(list[i]->GetSiDo()) == 0)
		{
			for(int j=0; j< LOCATION_NUMBER;j++)
			{
				subTotal[j] += *(list[i]->GetAccidentCount() + j);
			}
			chk++;
		}
	}

	if (chk == 0)
	{
		for (int i = 0; i < ROW_NUMBER; i++)
		{
			if (keyword.compare(list[i]->GetSiGunGoo()) == 0)
			{
				for (int j = 0; j < LOCATION_NUMBER; j++)
				{
					subTotal[j] += *(list[i]->GetAccidentCount() + j);
				}
			}
		}
	}

	cout << keyword << "의 부분합 : ";
	for (int i = 0; i < LOCATION_NUMBER; i++)
	{
		cout << subTotal[i] << " ";
	}

	cout << endl<< endl;
	system("pause");
}

 

부분합을 누적하는 int subTotal[LOCATION_NUMBER] 는 지역변수로 만들었다 나중에 함수 밑부분에 파일 출력 부분을 추가할 예정이다.

 

 

 

 

 

 

AccidentData.h

#pragma once
#include <iostream>
#include <string>
#define LOCATION_NUMBER 11

using namespace std;

class AccidentData
{
private:
	string siDo;
	string siGunGoo;
	int accidentCount[LOCATION_NUMBER];

public:
	AccidentData(string _siDo, string _siGunGoo, string* _accidentCount);

	string GetSiDo() const;
	string GetSiGunGoo() const;
	int* GetAccidentCount();

	~AccidentData();
};

 

 

 

 

 

AccidentData.cpp

#include "AccidenData.h"
#include <iostream>
#include <string>

#include "AccidenData.h"

AccidentData::AccidentData(string _siDo, string _siGunGoo, string* _accidentCount)
{
	siDo = _siDo;
	siGunGoo = _siGunGoo;
	for (int i = 0; i < LOCATION_NUMBER; i++)
	{
		if (*(_accidentCount + i) == "-")
		{
			accidentCount[i] = 0;
		}else
		{
			accidentCount[i] = stoi(*(_accidentCount + i));
		}		
	}
}

string AccidentData::GetSiDo() const
{
	return siDo;
}

string AccidentData::GetSiGunGoo() const
{
	return siGunGoo;
}

int* AccidentData::GetAccidentCount()
{
	return accidentCount;
}