fgetc와 getc의 차이점을 가르쳐 주세요..

Fe.head의 이미지

사용법

#include <stdio.h>

int fgetc(FILE *stream);
int getc(FILE *stream);
 
설명
fgetc()는 stream이 가리키는 바로 다음 문자를 읽어서 원래 데이터형인 unsigned char를 int로 변환한 다음 반환값으로 돌려준다. 만약 파일의 끝에 도달했을 경우에는 EOF를 반환하고 문제가 발생하면 에러를 반환한다.

getc()는 stream을 여러 번 검사하는 매크로 함수로 구현되어 있다는 점을 제외하고는 fgetc()와 동일하다. 

이게 man page( http://man.kldp.org )에 있는 내용인데요..

getc가 무엇이 다른지 잘 모르겠어서..

매크로함수로 구현 되어 있다라고 되어 있어.. 한번 따라가 보니..

#define	getc(fp)	__sgetc(fp)

static __inline__ int __sgetc(FILE *__p)
  {
    int __c = __sgetc_raw(__p);
    if ((__p->_flags & __SCLE) && (__c == '\r'))
      {
      int __c2 = __sgetc_raw(__p);
      if (__c2 == '\n')
        __c = __c2;
      else
        ungetc(__c2, __p);
      }
    return __c;
  }

이런 소스가 있더군요..

소스보면.. \r\n이 있으면 \n 만 리턴하라는 뜻으로만 보이는데..
어떤 차이가 있는거죠?

소스만들어서.. 실행시켜봐도 똑같네요.

#include <stdio.h>

int
main()
{
    FILE *pFile;
    int ch;

    pFile = fopen("test.txt", "r");
    if(pFile == NULL)
    {
        perror("fopen:");
        exit(1);
    }

    printf("fgetc\n");
    while((ch = fgetc(pFile)) != EOF)
    {
        printf("%c", (char)ch);
    }

    fseek(pFile, 0, SEEK_SET);
    printf("\ngetc\n");
    while((ch = getc(pFile)) != EOF)
    {
        printf("%c", (char)ch);
    }

    fclose(pFile);
    return 0;
}

결과 :
fgetc
0000000000
1111111111

2222222222


3333333333
4444444444

getc
0000000000
1111111111

2222222222


3333333333
4444444444

버려진의 이미지

목적도 동작도 같습니다. (They are for all intents and purposes the same!)

아래는 http://crasseux.com/books/ctutorial/getc-and-fgetc.html 에서...

Quote:
There is another function in the GNU C Library called fgetc. It is identical to getc in most respects, except that getc is usually implemented as a macro function and is highly optimised, so is preferable in most situations. (In situations where you are reading from standard input, getc is about as fast as fgetc, since humans type slowly compared to how fast computers can read their input, but when you are reading from a stream that is not interactively produced by a human, fgetc is probably better.)

생각해보니 이 이야기도 언젠가 나왔던것 같군요. 검색해 보시면 퍼포먼스에 대한 비교 논쟁(?)을 찾으실 수 있으실 겁니다.

지금 찾아보려 했는데 못찾겠네요 ^^;

Fe.head의 이미지

답장 감사합니다.. PYJ200님.

결국.. getc는 fgetc의 매크로일뿐이라는 내용이군요..

영어에서(옆에 있는 동료분께서 해석하셨지만.^^) "getc 보다는 fgetc를 써라"라고 하였으니 fgetc를 써야 겠네요..

고작 블로킹 하나, 고작 25점 중에 1점, 고작 부활동
"만약 그 순간이 온다면 그때가 네가 배구에 빠지는 순간이야"

cdpark의 이미지

fehead wrote:
답장 감사합니다.. PYJ200님.

결국.. getc는 fgetc의 매크로일뿐이라는 내용이군요..

영어에서(옆에 있는 동료분께서 해석하셨지만.^^) "getc 보다는 fgetc를 써라"라고 하였으니 fgetc를 써야 겠네요..

gets 대신에 fgets를 써야 한다고 되어있긴 하지만 getc 대신에 fgetc를 써야 한다고 써 있지는 않을텐데요?

fgetc를 써야 할 이유는 function pointer가 필요할 때 뿐입니다. getc는 macro (혹은 경우에 따라 inline, 아니면 정상적 함수)로 구현되어 있기에 getc에 대한 function pointer를 얻을 수 없으니깐요.

Fe.head의 이미지

제가 영어에 무식해서리..

감사합니다.. cdpark님..

더 확실히 알것 같습니다..

함수포인터를 인자로 넘길수 있느냐 없느냐가(결국 매크로 함수냐 아니냐) 결정적으로 틀리는군요..

cdpark wrote:

gets 대신에 fgets를 써야 한다고 되어있긴 하지만 getc 대신에 fgetc를 써야 한다고 써 있지는 않을텐데요?

이말이 무지 햇갈립니다.
앞말하고 뒷말이 똑같은데.. ?!?

고작 블로킹 하나, 고작 25점 중에 1점, 고작 부활동
"만약 그 순간이 온다면 그때가 네가 배구에 빠지는 순간이야"

d3m3vilurr의 이미지

fehead wrote:

cdpark wrote:

gets 대신에 fgets를 써야 한다고 되어있긴 하지만 getc 대신에 fgetc를 써야 한다고 써 있지는 않을텐데요?

이말이 무지 햇갈립니다.
앞말하고 뒷말이 똑같은데.. ?!?

getc와 fgetc / gets와 fgets는 다릅니다.
gets와 fgets는 문자가 아닌 문자열을 가져옵니다.

둘사이에 큰차이점은 없지만
gets와는 다르게 fgets는 문자열의 수를 지정할수 있습니다.

gets로 입력시 배열을 초과하는 문자를 입력시킬수 있는 버그가 있기때문에
fgets를 이용하시는것이 좋습니다
(세그폴트를 야기하여 BOF의 문제가 될수 있습니다.)

cdpark의 이미지

get"c"와 get"s"는 전혀 다른 함수입니다. :(

댓글 달기

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