한 가지 방법은 아래의 거친 예제 코드를 추가했습니다. 그런 다음 strtok()
을 사용하여 입력 행을 토큰으로 분리하고 strtol()
을 사용하여 토큰을 숫자로 파싱 할 수 있습니다. scanf()
과 비교할 때 fgets
을 사용하면 구조화되지 않은 사용자 입력을 훨씬 쉽게 처리 할 수 있습니다.
아래 코드는이 작업을 수행합니다. 입력 행에 너무 많은 요소가 있거나 요소가 너무 적거나 요소 중 하나가 유효한 번호가 아니면 메시지가 인쇄되고 행을 다시 입력해야합니다.
사용자가 각 행을 입력하면 strtok()
을 사용하여 행을 토큰으로 분리합니다. 토큰 분리 문자 목록은 delims[]
에 저장됩니다. 토큰은 공백이나 탭으로 구분할 수 있습니다. 구분 기호 자체는 토큰의 일부가 아니므로 \r
및 \n
을 포함하면 이러한 문자가 줄의 마지막 토큰에 포함되지 않습니다.
토큰이 발견되면 가능한 경우 strtol()
을 사용하여이를 정수로 변환합니다. strtol()
호출 후 tail
포인터는 숫자의 일부가 아닌 토큰의 첫 번째 문자를 가리 킵니다. tail
이 종결자인 NUL
을 가리키는 경우 전체 문자열이 숫자로 분석됩니다. 그렇지 않으면 입력이 좋지 않은 것으로 간주되어 행을 다시 입력해야합니다.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define BUF_SIZE 1000
int main(void)
{
size_t r = 3;
size_t c = 5;
size_t i, j;
char buffer[BUF_SIZE];
char *token;
char *tail;
const char delims[] = " \t\r\n";
int arr[r][c];
int temp_val;
printf("Enter rows of %zu data elements:\n", c);
for(i = 0; i < r; i++){
j = 0;
if (fgets(buffer, BUF_SIZE, stdin) == NULL) {
perror("Error in fgets()");
exit(EXIT_FAILURE);
}
token = strtok(buffer, delims);
while (token != NULL) {
temp_val = strtol(token, &tail, 10);
if (*tail == '\0') {
arr[i][j] = temp_val;
++j;
} else { // token not a valid number
j = 0;
break;
}
if (j > c) { // too many input values
break;
}
token = strtok(NULL, delims);
}
if (j != c) {
printf("insufficient datapoints\n");
--i; // enter row again
}
}
for (i = 0; i < r; i++) {
for (j = 0; j < c; j++) {
printf("%5d", arr[i][j]);
}
putchar('\n');
}
return 0;
}
샘플 상호 작용 :
Enter rows of 5 data elements:
1 2 3 4
insufficient datapoints
1 2 3 4 5 6
insufficient datapoints
1 x 2 3 4
insufficient datapoints
1 2 3 4 x
insufficient datapoints
1 2 3 4 5 x
insufficient datapoints
1 2x 3 4 5
insufficient datapoints
1 2 3 4 5
2 3 4 5 6
3 4 5 6 7
1 2 3 4 5
2 3 4 5 6
3 4 5 6 7
경우'는 scanf()가'반환하지 않는'파이프 가까이하지 EOF'. – Stargateur
@ccpgh 어떻게해야합니까? –
'fgets'와'strtok'을 사용 하시겠습니까? – BLUEPIXY