[질문]fgets 이상하네요 누가 설명좀 부탁드립니다.

boardholic의 이미지

제가 파일에서 한줄씩 읽어들이려고 하는데

예를들어 test.txt란 파일에

hello kldp bbs
i love you

이런 문장이 있다고 치면

1.fgets(buf,16,fp)
printf("%s",buf)

2.fgets(buf,1,fp)
printf("%s",buf)

이런식으로 출력해보니 (참고로 ftell로 포인터 위치를 확인)
첫번째 포인터가 16이고 두번째 포인터도 16이었습니다.
예상대로라면 두번째가 17이되고 i문자가 찍혀야 하는데
도저히 감이 안잡힙니다.

또한 첫번재에서 갯수를 16이 아닌 16이상을 넣어도 포인터 위치
는 16이었습니다. 결국 '\0'과 '\n'문자가 포함된다고 생각했는데
다음 읽어들일때 갯술를 1을 주니까 그대로 16이었는데 2를 주면
물론 i가 찍혔습니다. 이해가 않가네요.

전문가님들 이해하기 쉽게 fgets() 함수에 대해 설명 부탁드립니다.

정태영의 이미지

stdio 의 f계열 함수가... 따로 버퍼링을 하기 때문에 생기는 현상이 아닐까요 :)

오랫동안 꿈을 그리는 사람은 그 꿈을 닮아간다...

http://mytears.org ~(~_~)~
나 한줄기 바람처럼..

ez8의 이미지

전문가는 아니지만...

메뉴얼 페이지에는

Quote:
The fgets() function reads at most one less than the number of characters specified by size from the given stream and stores them in the string str.

라고 나와있네요. "두번째 인자 - 1" 만큼만 읽어드린다는 것 같습니다.

따라서 fgets(buf,1,fp) 는 의미가 없어보입니다.

doldori의 이미지

1바이트는 널 문자 '\0'을 위해 남겨놓는 것입니다.

IsExist의 이미지

char *fgets(char *s, int n, FILE *stream); 는 스트림 stream 에서
n-1 바이트를 읽어 오는 함수. n-1 바이트 읽어 오기전에 newline을 만나거나
파일 끝을 만난 경우 거기 까지만 읽어 옴. newline을 만난경우 newline까지 포함
됨. 문자열을 다 읽은 경우 끝은 '\0' 으로 채워짐.

보통 fgets 함수는 텍스트 파일의 내용을 한줄씩 읽을 경우에 사용하는데
s는 가장 큰 한줄을 커버할 만큼의 충분한 공간을 할당한뒤 사용.

fgets 를 사용할시 feof 함수도 함께 사용하세요.

대략 다음의 유형으로 많이 쓰입니다.

char buf[512], *p;
int    len;
...
while (!feof(fp)) {
    fgets (buf, sizeof buf, fp);
    p = strrchr (buf, '\n');
    if (p) *p = 0;   
    len = strlen (buf);
    ...

   /* 이후 buf 내용을 가지고 처리, 때에 buf 가지고 링크드
   리스트를 구성하여 전체 텍스트 처리시 이용하기도 함.  */
}

---------
간디가 말한 우리를 파괴시키는 7가지 요소

첫째, 노동 없는 부(富)/둘째, 양심 없는 쾌락
셋째, 인격 없는 지! 식/넷째, 윤리 없는 비지니스

이익추구를 위해서라면..

다섯째, 인성(人性)없는 과학
여섯째, 희생 없는 종교/일곱째, 신념 없는 정치

doldori의 이미지

IsExist wrote:
fgets 를 사용할시 feof 함수도 함께 사용하세요.

대략 다음의 유형으로 많이 쓰입니다.

char buf[512], *p;
int    len;
...
while (!feof(fp)) {
    fgets (buf, sizeof buf, fp);
    p = strrchr (buf, '\n');
    if (p) *p = 0;   
    len = strlen (buf);
    ...

   /* 이후 buf 내용을 가지고 처리, 때에 buf 가지고 링크드
   리스트를 구성하여 전체 텍스트 처리시 이용하기도 함.  */
}

feof()를 이렇게 쓰는 것은 잘못입니다.
C Programming FAQ의 Q12.2를 참고하십시오.
IsExist의 이미지

FAQ를 참조하면 아래와 같이 수정하는게 좋겠군요

char buf[512], *p;
int    len;
...
while (NULL != fgets (buf, sizeof buf, fp)) {
    p = strrchr (buf, '\n');
    if (p) *p = 0;   
    len = strlen (buf);
    ...

   /* 이후 buf 내용을 가지고 처리, 때에 buf 가지고 링크드
   리스트를 구성하여 전체 텍스트 처리시 이용하기도 함.  */
}

---------
간디가 말한 우리를 파괴시키는 7가지 요소

첫째, 노동 없는 부(富)/둘째, 양심 없는 쾌락
셋째, 인격 없는 지! 식/넷째, 윤리 없는 비지니스

이익추구를 위해서라면..

다섯째, 인성(人性)없는 과학
여섯째, 희생 없는 종교/일곱째, 신념 없는 정치

댓글 달기

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
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.