wrkbrs

문자열 입력 함수 fscanf(), fgets() 본문

C

문자열 입력 함수 fscanf(), fgets()

zcarc 2019. 10. 4. 01:26

fscanf()와 fgets()는 문자열 입력 함수입니다.
파일 포인터에 따라서 표준 입력도 가능하고, 파일 입력도 가능하지요...

그러나, 이 둘에는 미묘한 차이가 있습니다.

파일 입력을 예로 들어보지요...

input.txt 파일 안에 다음과 같은 내용이 있다고 가정합니다.
Computer science education
Some universities teach
computer science as a theoretical study of computation
and algorithmic reasoning

이때 다음과 같은 코드를 실행하면 주석처럼 입력됩니다.

char str[4][100];
fscanf(fp,"%s",str[0]);  // Compter
fscanf(fp,"%s",str[1]);  // science
fscanf(fp,"%s",str[2]);  // education
fscanf(fp,"%s",str[3]);  // Some


다음과 같은 코드를 실행하면 주석처럼 입력됩니다.

fgets(str[0],100,fp);  // Computer science education
fgets(str[1],100,fp);  // Some universities teach
fgets(str[2],100,fp);  // computer science as a theoretical study of computation
fgets(str[3],100,fp);  // and algorithmic reasoning



input.txt 파일 안에 다음과 같은 내용이 있다고 가정합니다.

abcdefgh
ijklmnopq

EOF


이때, 다음 두 줄의 코드라인으로 파일을 읽어올 때 어떤 문제가 발생할까요? str[0]의 배열 내부를 보면 그 차이점을 알 수 있는데요...

fscanf(fp,"%s",str[0]);  // 'a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' '\0'
fgets(str[0],100,fp);      // '\n' '\0'


fscanf() 함수의 경우, 파일 포인터는 그 줄의 맨 마지막 '\n'을 가리키게 됩니다. 바로 다음 줄에서 fscanf() 함수로 읽으면, 자동으로 다음 줄을 읽게 되지만, fgets() 함수로 읽기 위해서는 바로 직전에, fgetc(fp);를 한번 실행해서 파일 포인터를 그 다음 줄로 옮겨 놓아야 합니다. 그렇게 하지 않으면, 다음 줄에서 fgets()로 읽게 되는 문자열은 '\n' '\0' 이 됩니다. fscanf() 함수에서 '\n'을 읽지 않은 이유는 %s의 경우, 공백, 개행 문자, 탭 등을 문자열의 구분자로 인식하기 때문이지요...

fscanf() 함수를 연속으로 두 번쓰면, 두번째 fscanf() 함수는 첫번째 fscanf()가 남겨놓은 '\n'을 건너뛴 후 읽기 때문에 정상적으로 문자열을 읽어오지만, fscanf() 함수로 읽은 후에, 바로 그 다음 줄에서 fgets() 함수를 사용하게 되면, fscanf() 함수가 읽지 않고 남겨 놓은 '\n'을 fgets() 함수가 읽어 버리기 때문입니다.

 

input.txt 파일을 fgets()로만 읽어보면 이렇게 되겠지요..

 

fgets(str[0],100,fp);      // 'a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' '\n' '\0'
fgets(str[1],100,fp);      // 'i' 'j' 'k' 'l' 'm' 'n' 'o' 'p' 'q' '\n' '\0'

 

따라서, 곧바로 다음과 같은 코드로 문자열을 출력하면, \n이 없이도 한 라인씩 출력되는 것이지요...

 

printf(“%s%s”,str[0],str[1]);

 

 



출처: https://codingfun.tistory.com/106 [Coding is fun]