값들을 파일로 저장후 파일을 읽어 들여와 평균에 따라 내용을 출력하는 과제 문제에 대하여 무한 루프가 발생함 파일저장에는 문제가없지만 파일 읽기에서..
글쓴이: seanmf / 작성시간: 일, 2011/12/04 - 11:30오전
파일로 소스코드 올렸어요
Q) 다음 조건을 만족하는 프로그램을 작성하시오.
[점수 출력 프로그램 만들기]
조건 1. 이름, 수학 점수, 영어 점수, 컴퓨터 점수를 사용자가 ctrl + z(EOF)를 누를 때까지 입력 받는다.
조건 2. 받은 데이터를 파일로 저장한다. (input.dat)
조건 3. 저장 한 파일을 읽어서 원하는 점수 범위 내에 있는 사람들을 출력한다.
(1. 평균 100점
2. 평균 80점 이상 ~ 100점 미만
3. 평균 60점 이상 ~ 80점 미만
4. 평균 60점 미만
5. 종료)
getRequest()함수호출에서
무한 루프가 발생합니다.
파일출력부 를 주석처리하면
문제없지만
파일출력부를 주석처리 안할시
파일저장하 파일읽기하면
무한루프가 발생
해결좀 해주세요
File attachments:
| 첨부 | 파일 크기 |
|---|---|
| 4.08 KB |
Forums:


무한루프는 while에서 조건이 바뀌질 않으니까
무한루프는 while에서 조건이 바뀌질 않으니까 생기죠.
ONE과 END가 while에서 참조 가능한 범위 안에 없네요
그리고 함수 가장 앞에 보면 ONE과 END를 정해놓은 것 같은데 ONE < END 인 경우에 request < ONE이면서 request > END인 경우가 가능한가요?
피할 수 있을때 즐겨라! http://melotopia.net/b
do~ while 문이므로 1~4 밖에 범위시 반복이라는뜻입니다.
do~ while 에서 1 ~ 5 아닌다른입력값이 들어오면 예외처리로 무한반복시켰습니다.
do
{
cout << "\n? ";
cin >> request;
} while ( request < ONE && request > END );
파일이없다면 clients.txt 가없다면 생성하기를 /* */ 주석처리하면
파일읽기부터시작한다면
프로그램은 잘돌아가나
파일에 생성부분을 주석처리안하고 붙어서 쓰면
무한루프발생 합니다.
논리가 잘못된 듯 합니다. request < ONE
논리가 잘못된 듯 합니다.
request < ONE && request > END 를
request < ONE || request > END 로 바꿔서 해보세요.
바꿔봤는데 안되요
바꿨는데도 안되네요..같은 증상이네요
입력 받는 부분 오류 수정, 논리 오류 수정.
제가 C++을 몰라서 scanf 썼습니다.
#include <iostream> //표준입출력 #include <fstream> //파일 입출력 하기위해 ofstream,ifstream fstream 쓰기위해 #include <cstdlib> //exit 쓰기위해 #include <string> //string 쓰기위해 #include<iomanip> //setw 와 setprecision 함수 쓰기위하여 using namespace std; enum RequestType { ONE = 1, TWO, THREE, FOUR, END }; //열거형 데이타변수 ONE=1 TWO=2 THREE=3 FOUR =4 END =5 void outputLine (const string, int, int, int); //콘솔에 출력하기 int getRequest(); bool shouldDisplay (int, double); char name[30]; //이름 int math; //수학 int english; //영어 int computer; //컴퓨터 int main () { ofstream outClientFile ("clients.txt", ios::out); //파일에출력 객체생성후 파일이 없으면 만든다. 아규먼트 2개 파일이름과, 파일에 출력 if (!outClientFile) // 파일이 제대로 열려있는지 { cerr << "File could not be opened" << endl; //제대로 안열려지면 예외처리 에러메세지출력 exit (1); } cout << "Enter the Name, Math score, English score, Computer score." << endl << "Enter end-of-file to end input.\n? "; while (cin >> name >> math >> english >> computer) //파일에 입력받기 { outClientFile << name << ' ' << math << ' ' << english << ' ' << computer << ' ' << endl; cout << "? "; //콘솔에 입력하여 파일에 저장 eof까지 } //↑여기까지 파일 생성부분 //↓여기서 부터 파일생성된거 읽고 출력부분 ifstream inClientFile ("clients.txt", ios::in); //파일을 읽어들어옴 read 파일 open함 if (!inClientFile) //파일이 열리지않을시 에러메세지출력 { cerr << "File could not be opened" << endl; exit (1); } int request = getRequest (); //함수호출 while (request != END) { switch (request) { case ONE: cout << "평균이 100점:\n"; break; case TWO: cout << "평균이 80점 이상 ~ 100점 미만:\n"; break; case THREE: cout << "평균이 60점 이상 ~ 80점 미만:\n"; break; case FOUR: cout << "평균이 60점 미만:\n"; break; } //switch 종료 inClientFile >> name >> math >> english >> computer; //파일의 끝까지 데이타를 읽어들임 while (!inClientFile.eof ()) //파일의 끝이 아니라면 { int total = math + english + computer; //총합 double avg = total / 3.0; //평균 if (shouldDisplay (request, avg)) // outputLine (name, math, english, computer); inClientFile >> name >> math >> english >> computer; //파일의 끝까지 데이타를 읽어들임 } //안쪽와일종료 inClientFile.clear (); //파일이 EOF까지 같다면 초기화시킴 inClientFile.seekg (0); //파일의 포인터가 끝까지 이동된것을 맨처음으로 이동시킴 request = getRequest (); //함수호출 } //바깥쪽while 종료 cout << "End of run." << endl; return 0; } void outputLine (const string name, int math, int english, int computer) { int total = math + english + computer; //총합 double avg = total / 3.0; //평균 cout << left << setw (10) << "Name" << setw (10) //왼쪽정렬 10자리씩 할당 << "Math" << setw (10) << "English" << setw (10) << "Computer" << setw (10) << "Total" << setw (10) << "Average" << endl << fixed << showpoint; cout << left << setw (10) << name << setw (10) << math //10자리 할당 왼쪽정렬 출력 << setw (10) << english << setw (10) << computer << setw (10) << total << setw (10) << avg << endl; //파일에서 읽어온 DATA를 출력 총합과 평균과 같이 } int getRequest () { int request; cout << "\nEnter request" << endl << " 1 - 평균이 100점" << endl << " 2 - 평균이 80점 이상 ~ 100점 미만" << endl << " 3 - 평균이 60점 이상 ~ 80점 미만" << endl << " 4 - 평균이 60점 미만" << endl << " 5 - 평균이 End of run" << fixed << showpoint; do { //do~while부분 1~5아닌 다른값이 들어오면 무한루프발생시키는 예외처리 cout << "\n? "; scanf("%d", &request); // <<<<<<<<<<<<<<<<< 요 부분 } while (request < ONE || request > END); // <<<<<<<<<<<<<<<<<<<< 요 부분. return request; } bool shouldDisplay (int type, double avg) //평균의 범위시 그해당값 리턴하기 { if (type == ONE && avg == 100) return true; if (type == TWO && avg >= 80 && avg < 100) return true; if (type == THREE && avg >= 60 && avg < 80) return true; if (type == FOUR && avg < 60) return true; return false; }do { //do~while부분 1~5아닌
do { //do~while부분 1~5아닌 다른값이 들어오면 무한루프발생시키는 예외처리 cout << "\n? "; scanf("%d", &request); // <<<<<<<<<<<<<<<<< 요 부분 } while (request < ONE || request > END); // <<<<<<<<<<<<<<<<<<<< 요 부분.이부분은 개선해야할 소지가 있습니다. 알파벳 입력했을 경우 문제가 발생됩니다.
C 언어 손 놓은지가 굉장히 오래되어 기억이 잘 안나는데... getch, getchar, atoi 이런 걸 이용해서 1개 문자만 받아서 숫자로 만들면 좋습니다.
do ... while 로 처리할 것이 아니라...
아래처럼 작성하면 알아보기 한결 수월해집니다.
while( request = getch() ) { /* getch 인지 getchar 인지 기억이 안남 */ /* request 적절한 숫자로 가감 변환 작업 필요함 */ if(request >= 1 || request <= 5) break; } return request;올려주신 코드를 보면 주함수(main) 제어구조와 서브함수 부분의 제어구조가 중복이 됩니다.
그런 군더더기를 줄여 주면 한결 알아보기 쉬운 코드가 됩니다.
그 부분은 제가 숙제로 남겨드리겠습니다.
열공하세요.
if(request >= 1 && request <=
if(request >= 1 && request <= 5) 가 되어야 되는군요. 헷갈려.
cin 과 scanf 가 다르네요 .해결되었습니다.
논리문제가아니라
cin과 scanf문제같습니다.
cin으로 하니 무한루프가 발생하는데
scanf로 찍으니 무한루프없이 프로그램 잘돌아가네요
왜그럴지모르겠네요
cin이 객체라서 그런건지 ..
디버깅으로 돌리면 request 값이 -842398434 값이 들어오네요 입력을 받지도 못하고
리턴값이 쓰레기다보니
무한루프가 발생하는데
scanf로 찍으면 입력을 할수있으니 리턴값이 나와 무한루프가 안생기네요
이상하네....
해결되었습니다.
단지 cin과 scanf 의 차이로 ..
scanf로찍으니 ... 정상처리되네요
논리와는 관계 없는 댓글이라 딴지 거는 것 같아서
논리와는 관계 없는 댓글이라 딴지 거는 것 같아서 죄송합니다만, 조건1에서 CTRL+Z 가 아니라 CTRL+D 아닌가요?
윈도우에서는 CTRL+Z 가 EOF죠.
윈도우에서는 CTRL+Z 가 EOF죠.
댓글 달기