값들을 파일로 저장후 파일을 읽어 들여와 평균에 따라 내용을 출력하는 과제 문제에 대하여 무한 루프가 발생함 파일저장에는 문제가없지만 파일 읽기에서..

seanmf의 이미지

파일로 소스코드 올렸어요

Q) 다음 조건을 만족하는 프로그램을 작성하시오.
[점수 출력 프로그램 만들기]

조건 1. 이름, 수학 점수, 영어 점수, 컴퓨터 점수를 사용자가 ctrl + z(EOF)를 누를 때까지 입력 받는다.

조건 2. 받은 데이터를 파일로 저장한다. (input.dat)

조건 3. 저장 한 파일을 읽어서 원하는 점수 범위 내에 있는 사람들을 출력한다.
(1. 평균 100점
2. 평균 80점 이상 ~ 100점 미만
3. 평균 60점 이상 ~ 80점 미만
4. 평균 60점 미만
5. 종료)

getRequest()함수호출에서

무한 루프가 발생합니다.

파일출력부 를 주석처리하면

문제없지만

파일출력부를 주석처리 안할시

파일저장하 파일읽기하면

무한루프가 발생

해결좀 해주세요

File attachments: 
첨부파일 크기
Plain text icon 14_파일입출력.txt4.08 KB
snowall의 이미지

무한루프는 while에서 조건이 바뀌질 않으니까 생기죠.

ONE과 END가 while에서 참조 가능한 범위 안에 없네요

그리고 함수 가장 앞에 보면 ONE과 END를 정해놓은 것 같은데 ONE < END 인 경우에 request < ONE이면서 request > END인 경우가 가능한가요?

피할 수 있을때 즐겨라! http://melotopia.net/b

seanmf의 이미지

do~ while 에서 1 ~ 5 아닌다른입력값이 들어오면 예외처리로 무한반복시켰습니다.

do
{
cout << "\n? ";
cin >> request;
} while ( request < ONE && request > END );

파일이없다면 clients.txt 가없다면 생성하기를 /* */ 주석처리하면

파일읽기부터시작한다면
프로그램은 잘돌아가나

파일에 생성부분을 주석처리안하고 붙어서 쓰면
무한루프발생 합니다.

익명 사용자의 이미지

논리가 잘못된 듯 합니다.

request < ONE && request > END 를

request < ONE || request > END 로 바꿔서 해보세요.

seanmf의 이미지

바꿨는데도 안되네요..같은 증상이네요

익명 사용자의 이미지

제가 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아닌 다른값이 들어오면 무한루프발생시키는 예외처리
      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 <= 5) 가 되어야 되는군요. 헷갈려.

seanmf의 이미지

논리문제가아니라

cin과 scanf문제같습니다.

cin으로 하니 무한루프가 발생하는데

scanf로 찍으니 무한루프없이 프로그램 잘돌아가네요

왜그럴지모르겠네요

cin이 객체라서 그런건지 ..

디버깅으로 돌리면 request 값이 -842398434 값이 들어오네요 입력을 받지도 못하고

리턴값이 쓰레기다보니

무한루프가 발생하는데

scanf로 찍으면 입력을 할수있으니 리턴값이 나와 무한루프가 안생기네요

이상하네....

seanmf의 이미지

단지 cin과 scanf 의 차이로 ..

scanf로찍으니 ... 정상처리되네요

익명 사용자의 이미지

논리와는 관계 없는 댓글이라 딴지 거는 것 같아서 죄송합니다만, 조건1에서 CTRL+Z 가 아니라 CTRL+D 아닌가요?

planetarium의 이미지

윈도우에서는 CTRL+Z 가 EOF죠.

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

BBCode

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param>
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

Textile

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • You can use Textile markup to format text.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Markdown

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • Quick Tips:
    • Two or more spaces at a line's end = Line break
    • Double returns = Paragraph
    • *Single asterisks* or _single underscores_ = Emphasis
    • **Double** or __double__ = Strong
    • This is [a link](http://the.link.example.com "The optional title text")
    For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Plain text

  • HTML 태그를 사용할 수 없습니다.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 줄과 단락은 자동으로 분리됩니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.