일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- CS
- 알고리즘
- Direct2D
- 백준
- Tips프로그래밍강좌
- 연산자
- VS ERROR
- Kotlin
- 티스토리
- Windows
- 김성엽
- c
- Programming
- 지식나눔강좌
- doit코틀린프로그래밍
- 프로그래밍
- 배열
- c#
- 이지스퍼블리싱
- Win32
- 함수
- 포인터
- Javascript
- Tips강좌
- Visual Studio
- tipssoft
- 리뷰
- c++
- Desktop
- 문법
- Yesterday
- Today
- Total
F.R.I.D.A.Y.
지식인 : 성적을 xls(엑셀)로 출력하기 본문
Q.성적을 xls 파일로 출력하기
https://kin.naver.com/qna/detail.nhn?d1id=1&dirId=1040101&docId=318998069
※ xls 파일은 현대의 xlsx 포맷과 달리 바이트 코드로 이루어져 있기 때문에 탭문자와 줄바꿈 문자를 통해 만들 수 있다고 한다.
A.
일단 문제 확인을 위해 빌드를 진행한 결과 아래와 같은 12개의 경고와 2개의 오류가 발생했습니다.
경고의 경우 빌드하는데 있어 큰 문제가 없지만 잠재적인 위협/문제가 될 수 있으니 가급적이면 경고도 없애는 편이 좋겠군요.
경고와 달리 오류는 존재하면 빌드를 진행하지 못합니다. 프로그램 실행에 있어 문법적인 문제가 발생한것이기 때문이죠.
오류 두 개가 존재하는 모습. 경고는 간편성을 위해 해제 해놓은 상태.
확인 해보니 print_subject_output() 함수는 사용되는 위치보다 아래에 위치합니다. 따라서 원패스 컴파일러인 MSVC에서는 문제가 발생합니다. 따라서 사용되는 부분보다 위에 선언을 하던지, 아니면 함수 원형을 소스코드 상단에 작성하는 방법으로 문제를 해결할 수 있습니다. 1
void print_subject_output(float* Kor, float * Eng, float* Math, int Sum[], FILE* fp);
두번째 오류 역시 마찬가지의 이유로 발생한 오류이고 같은 방법으로 해결할 수 있습니다.
다음으로 subject_output() 함수입니다. 함수네임으로 유추해보았을 때, 이곳을 통해 관련 데이터를 처리하는 듯 싶습니다.
이렇게 작성하신 분께는 구조를 잘못 세웠다고 말씀드리고 싶습니다. 최대크기는 최대 크기대로, 최소크기는 최소크기대로 묶어 처리하는 것이 좋고, 과목별로 처리하면 굉장히 불필요한 코드가 늘어나게 됩니다.
void subject_output(student Student[], int cnt, FILE*fp) {
const int KOREAN = 0;
const int ENGLISH = 1;
const int MATH = 2;
float max[3], min[3], total[3];
for (int i = 0; i < 3; ++i) {
max[i] = 0.0f;
total[i] = 0.0f;
min[i] = 1000.0f; // 1000 이상인 점수가 나올 수는 없기 때문에 값 비교를 위해 1,000 넣음.
}
for (int i = 0; i < cnt; ++i) {
// 각 subject의 최대 값 구하기
if (Student[i].Kor > max[KOREAN]) max[KOREAN] = Student[i].Kor;
if (Student[i].Eng > max[ENGLISH]) max[ENGLISH] = Student[i].Eng;
if (Student[i].Math > max[MATH]) max[MATH] = Student[i].Math;
// 각 subject의 최소 값 구하기
if (Student[i].Kor < min[KOREAN]) min[KOREAN] = Student[i].Kor;
if (Student[i].Eng < min[ENGLISH]) min[ENGLISH] = Student[i].Eng;
if (Student[i].Math < min[MATH]) min[MATH] = Student[i].Math;
total[KOREAN] += Student[i].Kor;
total[ENGLISH] += Student[i].Eng;
total[MATH] += Student[i].Math;
}
print_subject_output(KOR, ENG, MATH, SUM, fp);
}
수정 결과는 위와 같습니다. 그런데 이젠 print_subject_output() 함수와 호환이 되지 않는군요. 이젠 이 print_subject_output() 함수를 건드려봅시다. 기존 코드는 다음과 같습니다.
void print_subject_output(float* Kor, float * Eng, float* Math, int Sum[], FILE* fp)// 전달받은 과목별 최대, 최소, 합계 배열을 이용하여 결과를 화면과 파일에 출력
{
fprintf(fp,"과목\t최고\tw최저\t평균\n");
fprintf(fp, "국어\t%d\t%d\t%.1f\n", Kor[0], Kor[1], Sum[0] / 3.0);
fprintf(fp, "영어\t%d\t%d\t%.1f\n", Eng[0], Eng[1], Sum[1] / 3.0);
fprintf(fp, "국어\t%d\t%d\t%.1f\n", Math[0], Math[1], Sum[2] / 3.0);
}
이렇게 작성이 되어있으니 호환에 맞도록 print_subject_output() 함수를 고쳐봅니다.
void print_subject_output(float* max, float *min, float* total,FILE* fp)// 전달받은 과목별 최대, 최소, 합계 배열을 이용하여 결과를 화면과 파일에 출력
{
// 0 : 국어
// 1 : 영어
// 2 : 수학
fprintf(fp, "과목\t최고\tw최저\t평균\n");
fprintf(fp, "국어\t%d\t%d\t%.1f\n", max[0], min[0], total[0] / 3.0);
fprintf(fp, "영어\t%d\t%d\t%.1f\n", max[1], min[1], total[1] / 3.0);
fprintf(fp, "수학\t%d\t%d\t%.1f\n", max[2], min[2], total[2] / 3.0);
}
인자의 형태가 변경되었으니 함수 원형도 따라서 바꿔줘야겠죠?
위 작업을 모두 했다면 정상적으로 출력이 되어야 합니다. 테스트를 진행한 후 파일을 열어보니 다음과 같이 엉망이 되어있습니다.
어째서일까요?
처음 오류 목록을 볼까요? 12개의 경고 항목이 있습니다. 해당 경고 항목들을 보면 전부 C4477 오류들입니다. 이 오류들은 간단히 출력하는 대상과 출력방식의 차이, 즉 자료형의 차이로 인해 발생합니다. 코드들을 보면 데이터는 float 자료형으로 이루어진데 반해 출력할 때는 %d, int 정수 자료형으로 출력하라고 합니다. 그래서 발생하는 문제들입니다. 이제 이 문제를 해결하기 위해 잘못된 부분을 고칩니다.
그런데 이상합니다. 다 잘 나오는데 평균 부분이 말이 안됩니다. 그래서 평균을 구하는 코드를 봤습니다.
이제보니 (float)cnt. 즉 사람 수로 나누고 있던겁니다. 평균이라 함은 과목수로 나누어야 하는데 귀여운 실수를 했군요. 과목 수 3으로 나누어줍니다.
이제 잘 만들어졌군요.
프로그램을 배우며 여러 시도를 하는 것은 좋은 습관입니다. 그러나 기본기가 갖춰지지 않은 상황에서 무작정 만들려고 하면 좋은 습관을 들일 수 없을 뿐더러 문제를 야기하고 새로운 것을 배우는 데도 힘이 듭니다. 배울 때는 힘들겠지만 하나하나 제대로 배워야합니다. 어떻게 사용해야하는지를 꼭 참고하고 문법을 꼭 숙지하는 것이 좋습니다. 문법을 피해서 프로그램을 짜는 것은 문법을 모두 알고 능수능란하게 다룬 뒤의 일입니다.
아래는 모든 수정을 거친 완성된 코드입니다.
- 현존하는 대부분의 컴파일러가 성능 문제로 원패스 컴파일을 진행합니다. [본문으로]
'외부활동 > 지식in' 카테고리의 다른 글
지식인 질문하기 (0) | 2019.04.02 |
---|---|
지식인 : 리스트 자료구조 포인터 (0) | 2019.03.06 |
지식인 : 시간 문자열을 숫자(초)로 변환하기 (0) | 2018.11.13 |
지식인 : 두번 째로 큰 수, 두번 째로 작은 수 (0) | 2018.11.12 |
지식인 : if없이 가까운 수 찾기 (0) | 2018.09.25 |