Conway의 Game of Life에 대한 C 구현을 마치고 있는데 잘못된 네팅 파일을 구문 분석 할 때 오류 처리에 문제가 있습니다.
파일 형식은 다음과 같습니다.
rows cols
x1 y1
x2 y2
읽기 기능 :
net_t *file_to_net( net_t *n, char *filename )
{
assert( n != NULL );
FILE *f = fopen( filename, "r" );
if( f == NULL )
print_error_file( filename );
if( fscanf( f, "%d %d", &(n->rows), &(n->cols) ) != 2 )
print_error("net");
n->vec = calloc( n->rows * n->cols, sizeof(unsigned char) );
if( n->vec == NULL )
print_error("alloc");
int i, x, y;
while( fscanf( f, "%d %d", &x, &y ) == 2 )
{
if( x > n->rows || y > n->cols )
{
fprintf( stderr, "%sERROR:%s Coordinates of living cell in net file is bigger then net dimensions.\n", COLOR_RED, COLOR_RESET );
exit(EXIT_FAILURE);
}
i = ( n->cols * (x - 1) ) + (y - 1);
n->vec[i] = 1;
}
if( !feof(f) )
print_error("net");
fclose(f);
return n;
}
오류 처리는 숫자 대신 문자 (루프가 끝나지만 EOF는 아님)가있을 때 작동하지만 좌표 중 하나가 없으면 (홀수 숫자가 있음) 작동하지 않습니다. 예를 들면 다음과 같습니다.
50 50
2 3
3 4
4
4 3
4 4
오류로 끝나지 않습니다. 나는 그것을 구현하려고 노력했지만 3 가지 경우 모두에서 작동하도록 만들 수 없습니다 (좋은 파일, 내부 숫자가 아닌 숫자 및 홀수 숫자).
편집하다
좋습니다. 도움을 주셔서 대단히 감사합니다. 다음 세 가지 경우를 모두 포함하는 루프 코드로 끝났습니다.
int i, x, y;
int pos;
while( fgets( line, MAXL, f ) != NULL )
{
if( sscanf( line, "%d %d %n", &x, &y, &pos ) != 2 )
{
print_error("net");
}
else if( line[pos] != '\0' )
{
print_error("net");
}
if( x > n->rows || y > n->cols )
{
fprintf( stderr, "%sERROR:%s Coordinates of living cell in net file is bigger then net dimensions.\n", COLOR_RED, COLOR_RESET );
exit(EXIT_FAILURE);
}
i = ( n->cols * (x - 1) ) + (y - 1);
n->vec[i] = 1;
}
다음을 바꿀 수 있습니다.
while( fscanf( f, "%d %d", &x, &y ) == 2 )
와:
int rc;
while ((rc = fscanf(f, "%d %d", &x, &y)) == 2)
{
…
}
if (rc == EOF)
…report EOF…
else
…report format error…
else
절 때문에 파일의 숫자가 아닌 데이터의 트리거, 또는이 있었기 때문에 숫자가 어딘가를 누락 될 수 있습니다. 참고 scanf()
한 줄에 50 공간 구분 번호가 있으며, 각 좌표 나 별도 또는 레이아웃 중 하이브리드 혼란 20 개 내지 빈 행이 있는지해도 상관 없다.
줄 단위로 읽고보고하려면 user3386109 의 답변 에서 나온 아이디어 와 추가 조정 을 사용 하는 것이 좋습니다 .
char line[4096];
int rc;
int pos;
while (fgets(line, sizeof(line), stdin) != NULL)
{
if ((rc = sscanf(line, "%d %d %n", &x, &y, &pos)) != 2)
{
…analyze for EOF or format error…
}
else if (line[pos] != '\0')
{
…trailing non-blank junk on line…
}
else
{
…all clean and tidy…
}
}
참고 %n
변환 스펙은 (따라서 검사가 아직 3이 아니다) 결과에서 계산되지 않는다. 또한에서 앞에있는 공백 %n
은 괜찮지 sscanf()
만 대화 형 입력에는 끔찍합니다 (사용자가 공백이 아닌 문자를 입력 할 때까지 입력이 끝나지 않음). 이러한 종류의 미묘한 세부 사항은 scanf()
함수 패밀리가 초보자에게 악몽 같은 이유 입니다 (이것이 숙련 된 프로그래머에게도 쉽지 않습니다).
이 기사는 인터넷에서 수집됩니다. 재 인쇄 할 때 출처를 알려주십시오.
침해가 발생한 경우 연락 주시기 바랍니다[email protected] 삭제
몇 마디 만하겠습니다