IT 과학/C언어

C언어 | 표준 라이브러리 함수

곰뚱 2020. 2. 24.

 

 

 

 

표준 라이브러리 함수는 300 종류 이상 제공되어 있다. 이번 주 강의에서는 그 중에서 수치 연산, 문자열 처리 함수, 버퍼 파일 입출력 함수의 기본적인 것만을 설명한다.

 

 

1. 수치 연산

수치 연산에 사용되는 기본 함수는 표 1과 같다.

 

표 1 기본적인 수치 연산

 

abs, rand, srand는 stdlib.h 내에서 형이 선언되어 있지만 이들 이외의 함수는 math.h 내에서 형이 선언된다. 이 함수를 사용하려면 math.h를 include해야 한다. 만약 include를 하지 않으면 각각 함수의 형을 선언해야 한다. sin(x), cos(x), tan(x)의 인수 x의 단위는 라디안이다. π(3.1415927)라디안이 180℃이다. rand( )를 실행시키려면 0∼32767의 범위에 해당하는 정수의 난수 하나가 리턴된다.

 

0∼1.0의 실수의 난수를 만드는 것은 다음과 같다.

          (double) rand( )/32767.0

 srand(seed)는 seed로 난수열의 시작점을 설정한다. seed는 0∼65535 사이의 임의의 정수이다.

 

예제 1. log, sqrt, exp, pow의 값을 계산하는 프로그램을 작성하여라.

● 프로그램

#include <stdio.h>
#include <math.h>
main()
{
        double x;
        printf("%10s%10s%10s%15s%20s\n",
                    "x", "log(x)", "sqrt(x)", "exp(x)", "pow(10.0,x)");
        for (x=1; x<=10; x++)
        printf("%10.5f%10.5f%10.5f%15.5f%20.5f\n",
                  x, log(x), sqrt(x), exp(x), pow(10.0,x));
}

 

● 결과
      x     log(x)   sqrt(x)       exp(x)        pow(10.0, x)   
 1.00000   0.00000   1.00000       2.71828            10.00000
 2.00000   0.69315   1.41421       7.38906           100.00000
 3.00000   1.09861   1.73205      20.08554          1000.00000
 4.00000   1.38692   2.00000      54.59815         10000.00000
 5.00000   1.60944   2.23607     148.41316        100000.00000
 6.00000   1.79176   2.44949     403.42879       1000000.00000
 7.00000   1.94591   2.64575    1096.63316      10000000.00000
 8.00000   2.07944   2.82843    2980.95799     100000000.00000
 9.00000   2.19722   3.00000    8103.08393    1000000000.00000
10.00000   2.30259   3.16228   22026.46579   10000000000.00000

728x90

 

 

2. 문자열 처리

문자열의 복사, 비교, 결합을 하는 함수와 문자의 종류(알파벳이나 숫자)를 조사하는 문자 검사 매크로에 대해 설명하기로 한다. strcpy, strcat, strcmp, strlen 함수는 string.h에, is∼매크로, to∼함수는 ctype.h에 각각 선언되어 있으므로 사용할 때에는 이 함수들의 헤더 파일을 포함시켜야 한다. 이후의 함수로 자주 나오는 char* 형의 인수로는 구체적으로 다음과 같은 것이 사용된다.

 

  ·Turbo 등의 문자열 상수

  ·char s[20]; 등이라고 선언되어 있는 배열명 s

  ·char *str; 등이라고 선언되어 있는 포인터 str

 

(1) strcpy(문자열의 복사)

형식

        strcpy(s, t)         
        s는 복사를 표시하는 포인터(char *형)
        t는 복사하는 문자열을 지정하는 포인터(char *형)

 

기능

포인터 s로 표시되는 영역에 t로 표시되는 문자열의 실체를 복사한다. 예를 들어 문자열   s[ ]에 Turbo의 실체를 복사하는데는 단순히 s="Turbo"로 할 수 없고 한 문자 단위로 복사해야 한다(이것은 앞에서 설명했다). strcpy을 사용하면 다음과 같이 간단히 할 수 있다.

   char s[20];
   strcpy(s, "Turbo");

전송되는 문자열의 끝은 반드시 '\0'으로 해야 한다. strcpy는 '\0'도 포함해서 복사한다. 따라서 복사 전의 영역은 복사되는 문자열의 길이보다 +1 이상의 크기가 확보되어야 한다. 위에서 배열 s[  ]로 복사한 문자열을 다시 char p[20]; 이라는 배열로 복사하려면
     
   strcpy(p, s);

라고 하면 된다.

 

예제 2. sin 곡선과 cos 곡선을 합성하여 표시하여라.

 ● 프로그램
#include <stdio.h>
#include <math.h>
#include <string.h>
 main( )
{
       char p[30];
       int ts=0, tc=0, n, a;
       double rd=3.1415927/180;
       for (a=0; a<30; a++) p[a]=0;
       printf("         -1         0        1\n");
       printf("         I    +    I    +    I\n");
       for (n=0; n<=360; n=n+15) {
          strcpy(p, "       I       ");          
          ts = (int)(10+10*sin(n*rd));
          tc = (int)(10+10*cos(n*rd));
          if (ts==tc)
              p[ts]='+';
          else {
              p[ts]='*'; p[tc]='o';
          }
          printf("%5d       %s\n", n, p);
       }
}

 

 ● 결과                
        -1         0        1  
        I    +    I    +    I
  0                 *           
 15                 I  *       
 30                 I     *   
 45                 I       +
 60                 I        *
 75                 I          *
 90                I           *
105                I           *
120                I          *
135                I        *
150                I      *
165                I  *
180              * I
195             *  I
210            *   I
225          +     I
240         *      I
255        *       I
270        *        
285        *        I  
300         *       I     
315          *      I        
330             *   I         
345               * I           
360                 *             

 

(2) strcat(문자열의 연결)

형식

strcat(s, t)

s는 연결을 표시하는 포인터(char *형)

t는 연결하는 문자열의 포인터(char *형)

 

기능

포인터 s로 표시된 영역에 있는 문자열 뒤에 t로 표시된 문자열을 복사한다. s로 표시된 영역은 문자열 t만 연결할 수 있는 크기만큼 확보해야 한다. 예로

    char s[50], t[20];
    strcpy(s, "good");
    strcpy(t, "morning");

라고 표시된다. 배열 s에 good, 배열 t에 morning이 저장되어 있을 때, s에 t의 내용을 연결하려면 다음과 같다.

    strcat(s, t);

 

(3) strcmp(문자열의 비교)

형식

strcmp(s1,s2)

비교 결과가 리턴된다.(int형)

s1과 s2는 비교하는 문자열을 지정하는 포인터(char *형)

 

기능

문자열 s1과 s2를 비교하고, 그 결과로 다음의 값(int형)을 리턴한다.

         s1>s2 이면 양(+)
         s1=s2 이면 0
         s1<s2 이면 음(-)

문자열의 비교는 여러 가지 사전 형식 순서에 따라서 대소 관계가 결정된다. 예룰 들면

         "a"<"ab"<"b"…

라는 순서대로 대소 관계가 결정된다.

         strcmp("Ann", "Candy")……음의 값을 리턴한다.
         if(strcmp(s, t) <0)……문자열 s 가 문자열 t보다 작은가를 판정한다.

 

예제 3. 이름의 데이터를 알파벳순으로 변환하여 나열하여라.

● 프로그램
  #include <stdio.h>
  #include <string.h>
  #define N 8
  main( )
  {
         char *nam[ ]={"candy", "eluza", "nancy", "emy",
                              "rolla", "ann", "catherine", "kity"};
         char *dumy, *min;
         int j, k, s;
         for (k=0; k<N-1; k++){
             min = nam[k];
             s = k;
             for (j=k+1; j<N; j++){
                 if (strcmp(nam[j], min)<0){
                    min = nam[j];
                    s = j;
                 }
             }
             dumy=nam[k]; nam[k]=nam[s]; nam[s]=dumy;
         }
         for (k=0; k<N; k++)
             printf("%s\n", nam[k]);
  }  

 

● 결과
 ann
 candy
 catherine
 eluza
 emy
 kity
 nancy
 rolla

 

(4) strlen(문자열의 길이를 탐색)

형식

strlen(s)  

문자열의 길이가 리턴된다(unsigned형)

s는 문자열로의 포인터(char *형)

 

기능

문자열 s의 길이(\0은 포함하지 않음)을 리턴한다. 함수형은 unsigned형이다.

         strlen("Candy")……5를 리턴한다.

 

(5) is∼(문자 검사 매크로)

형식

is∼(c)     

검사 결과 참/거짓이 리턴된다(int형)

∼에는 구체적인 검사명이 들어간다

c는 검사하는 문자(int형)

 

기능

문자 c가 ∼로 기술되는 검사 항목을 채우면 참(1), 채우지 못하면 (0)을 리턴한다. is∼(c)매크로로서 다음과 같은 것들이 있다. 이 매크로를 사용할 때에는 반드시 ctype.h을 포함시켜야 한다.

      isalpha(c)……문자 c 가 영문자('A'∼'Z', 'a'∼'z')이면 참
      isalnum(c)……문자 c 가 영문 숫자('A'∼'Z', 'a'∼'z', '0'∼'9')이면 참
      isascii(c)……문자 c 가 ASCII 코드(0∼0×7F)이면 참
      iscntri(c)……문자 c 가 제어 문자 코드(0∼0×1f, 0×7f0이면 참
      isdigit(c)……문자 c 가 숫자 문자('0'∼'9')이면 참
      isgraph(c)……문자 c 가 0×21∼0×7e 이면 참
      islower(c)……문자 c 가 소문자( a     z )이면 참
      ispunct(c)……문자 c가 구두점(0×21∼0×40, 0×5b∼0×60, 0×7b∼0×7e)이면 참
      isspace(c)……문자 c가 공백 문자(0×09∼0×0d, 0×20)이면 참
      isupper(c)……문자 c가 대문자('A'∼'f')이면 참
      isxdigit(c)……문자 c가 16진 문자('0'∼'9', 'A'∼'F', 'a'∼'z')이면 참
     
is∼(c)매크로는 참/거짓을 리턴하므로 다음과 같이 if문으로 할 수 있다.

        if (isalpha(c))  {
              c가 알파벳인 때의 처리
        }

 

확인 문제 1

/* 문자 검사 함수  is∼(c); 형식의 함수들의 사용의 예 */
#include <stdio.h>
#include <ctype.h>
int main(void)
{
      int i = 1;
      char ch;

      do
      {
        printf("Input a character : ");
        ch = getche( );
        putchar('\n');
        if(isalnum(ch))
            printf("%c is alnum charcter.\n", ch);
        else
            printf("%c is not alnum charcter.\n", ch);
        if(isalpha(ch))
            printf("%c is alpha charcter.\n", ch);
        else
            printf("%c is not alpha charcter.\n", ch);
        if(isascii(ch))
            printf("%c is ascii charcter.\n", ch);
        else
            printf("%c is not ascii charcter.\n", ch);
        if(iscntrl(ch))
            printf("%c is cntrl charcter.\n", ch);
        else
            printf("%c is not cntrl charcter.\n", ch);
        if(isdigit(ch))
            printf("%c is digit charcter.\n", ch);
        else
            printf("%c is not digit charcter.\n", ch);
        if(isgraph(ch))
            printf("%c is graph charcter.\n", ch);
        else
            printf("%c is not graph charcter.\n", ch);
        if(islower(ch))
            printf("%c is lower charcter.\n", ch);
        else
            printf("%c is not lower charcter.\n", ch);
        if(isprint(ch))
            printf("%c is print charcter.\n", ch);
        else
            printf("%c is not print charcter.\n", ch);
        if(ispunct(ch))
            printf("%c is punct charcter.\n", ch);
        else
            printf("%c is not punct charcter.\n", ch);
        if(isspace(ch))
            printf("%c is space charcter.\n", ch);
        else
            printf("%c is not space charcter.\n", ch);
        if(isupper(ch))
            printf("%c is upper charcter.\n", ch);
        else
            printf("%c is not upper charcter.\n", ch);
        if(isxdigit(ch))
            printf("%c is xdigit charcter.\n", ch);
        else
            printf("%c is not xdigit charcter.\n", ch);
        putchar('\n');
      } while( i++ < 3 );
      return(0);
}

 

(6) to∼(문자 변환 함수)

형식

to∼(c)     

변환된 문자(int형)

∼에는 구체적인 변환명이 들어간다.

c는 변환하는 문자(int형)

 

기능

문자 c에 ∼으로 표시된 문자를 변환한다. to∼(c)함수로서 다음과 같은 것이 있다.

       tolower(c)…문자 c가 대문자이면 소문자로 변환하고 그 값을 리턴한다.
       toupper(c)…문자 c가 소문자이면 대문자로 변환하고 그 값을 리턴한다.

       tolower('A')는 'a'를 리턴하고 toupper('a')는 'A'를 리턴한다.

 

확인 문제 2

/* 문자 검사 함수  to∼(c); 형식의 함수들의 사용의 예 */
#include <stdio.h>
#include <ctype.h>
int main(void)
{
      int code, length, i;
      char ch = 'A';
      char *spt1 = "CAPITAL CHARCTER";
      char *spt2 = "non-capital character";

      code = toascii(ch);
      printf("ch = %c, ASCII = %d\n", ch, code);

      puts(spt1);
      length = strlen(spt1);
      for(i = 0; i < length; i++)
        spt1[i] = tolower(spt1[i]);
      puts(spt1);

      puts(spt2);
      length = strlen(spt2);
      for(i = 0; i < length; i++)
        spt2[i] = toupper(spt2[i]);
      puts(spt2);
}

 

 

3. 파일 입출력

파일 입출력 함수에는 저차원 파일 입출력과 버퍼/파일(스트림) 입출력이 있다. 전자는 바이트 단위의 파일 액세스가 사용자 버퍼와의 사이에서 실행되는데 대해, 후자는 시스템 버퍼를 이용하여 한 문자 단위 혹은 1행 단위의 파일 액세스가 이루어지는 것으로, 텍스트 파일의 처리를 하는데 편리하게 설계되어 있다.

 

■ 파일 포인터와 파일의 오픈

파일은 파일명에 의해 식별되지만 그 파일을 액세스하기 위해서는 파일 포인터로 파일을 오픈 해야 한다. 파일 포인터는 파일을 조작하기 위한 특별한 식별자로 구조체 FILE형의 포인터 변수로 다음과 같이 선언된다.
        
        FILE *fp;

이렇게 선언한 후 파일 abc.txt 를 read mode로 오픈 하려면 파일 오픈 함수 fopen을 사용해서 다음과 같이 한다.

      fp=fopen("abc. txt", "r");

위와 같이 한 후 파일 포인터 fp를 사용하여 abc.txt에 파일 액세스가 되도록 한다.

일반적으로 fopen 함수는 파일 오픈에 실패할 경우 NULL(0)이라는 값을 리턴하기 때문에 파일 오픈은 아래 예와 같이 하는 것이 안전하다. 그 이유는 파일 오픈에 실패한 상태로 정상이 아닌 파일 포인터 fp를 사용해서 파일 액세스를 하면 파일이 파괴될 위험이 있기 때문이다.
       
      if ((fp=fopen(“abc. txt”,“r”))  NULL){
         printf(“File not open\n”);
         exit( );

NULL은 stdio. h 내에서 0으로 정의된다.

이상의 파일 오픈의 형식을 정리하면 다음과 같다.
   
     #include <stdio.h>
     main( )
     {
        FILE *fp;
        if ((fp=fopen("abc.txt", "r"))==NULL) {
           printf("File not open\n");
           exit( );
        }

구조체형 FILE은 stdio.h 내에서 정의되어 있으므로 반드시 stdio.h를 포함시켜야 한다.

 

■ 버퍼/파일 입출력의 개념

버퍼 파일 입출력 함수 getc/putc이나 fgets/fputs는 1문자 단위, 1행 단위의 파일 액세스를 하지만 이들 함수가 직접 디스크에서 데이터를 read/write하는 것이 아니고 시스템이 설정한 버퍼간에 이루어진다. 그리고 시스템 버퍼의 데이터가 없든지 꽉 찼을 때 시스템이 자동적으로(저차원 파일 입출력 함수를 이용해서) 디스크간에 read/write를 한다. 이런 과정을 버퍼/파일이라고 한다.

파일 오픈(file open)에 의하여 오픈 되어진 fp를 사용해서 파일에서 1문자를 read하려면

      getc(fp);

라고 한다. getc( ) 함수는 파일 끝으로 EOF(-1)을 리턴하므로 파일에서 1문자를 read해서 그것을 화면으로 출력해 가는 프로그램은 다음과 같다.
       
       while ((c getc(fp)) != EOF)
           putchar(c);

 

■ 파일의 close

파일 처리가 종료되면 파일을 close해야 한다. 이것은 fclose( ) 함수를 사용해서 다음과 같이 한다
 
       fclose(fp);

write mode에서 오픈한 파일은 반드시 파일을 close해야 되지만 read mode오픈한 파일은 파일을 close하지 않아도 된다.

 

(1) fopen(파일 오픈)

형식

        fopen(path, mode)
        파일 포인터가 리턴된다(FILE *형)
        path는 파일명을 가리키는 포인터(char *형)
        mode는 오픈 모드를 가리키는 문자열(char *형)

기능

path로  지시되는 파일을 mode로 지시되는 모드에서 파일 오픈 한다. 정상적으로 오픈 되면 그 파일로 파일 포인터가 리턴된다. 에러이면 NULL(0)이 리턴된다. 파일명은 직접"abc.txt"이나, 커맨드 라인 인수 argv[1]을 써도 된다.

mode에는 다음과 같은 것이 지정된다.

"r"...... read모드. 파일이 이미 존재하고 있다.
"w"……write 모드. 파일이 없으면 새로 생성시키고 있으면 비게 된다.
"a"…… 추가 모드. 파일이 없으면 새로 생성시키고 있으면 파일의 현재 위치를 파일 끝으로 위치한다.
"r+"…… 파일 생성용으로 r/w 모드에서 오픈. 파일이 이미 존재하고 있다.
"w+"……파일 생성용으로 r/w 모드에서 오픈. 파일이 없으면 새로 생성시키고 있으면 비게 된다.
"a+"…… 파일 생성용으로 r/w 모드에서 오픈. 파일이 없으면 새로 생성시키고 있으면 추가된다.

 

(2) fclose(파일의 close)

형식

fclose(fp)

정상이면 0, 에러이면 -1을 리턴한다(int형)

fp는 오픈된 파일 포인터(FILE *형)

 

기능

파일 포인터 fp에서 open되어 있는 파일을 close 한다. 정상적인 close가 되면 0, 에러이면 -1을 리턴한다.

 

(3) getc(파일에서 한 문자 입력)

형식

getc(fp)

파일에서 입력한 한 문자(int형)를 리턴한다.

fp는 오픈된 파일 포인터(FILE *형)

 

기능

파일 포인터 fp 로 지시된 파일에 한 문자를 read 하고 그 문자를 리턴한다. 파일이 끝나면 -1을 리턴한다.

 

(4) putc(파일에서 한 문자 출력)

형식

putc(c, fp)

출력한 문자(int형)를 리턴한다.

c는 출력하는 문자(int형)

fp는 오픈된 파일 포인터(FILE *형)

 

기능

파일 포인터 fp로 지시된 파일에 문자 c를 출력한다. 정상으로 출력되면 출력된 문자, 에러이면 -1을 리턴한다.

 

확인 문제 3

/* getc( )와 putc( ) 매크로 함수의 사용 */
#include <stdio.h>
int main(int argc, char *argv[ ])
{
    int ch, count, flag, white, word;
    FILE *in, *out;

    count = white = word = 0;
    flag = 1;
    if(argc != 3)
    {
          printf("Format: C:\>list11-3 file1 file2\n");
          exit(0);
    }
    if((in = fopen(argv[argc-2], "rt")) == NULL)
    {
          printf("Can't open file %s\n", argv[argc-1]);
        exit(0);
    }

    if((out = fopen(argv[argc-1], "wt")) == NULL)
    {
          printf("Can't open file %s\n", argv[argc-1]);
        exit(0);
    }
    while((ch = getc(in)) != EOF)
    {
          count++;
          putc(ch, out);
          switch(ch)
          {
              case ' ' :
              case '\t':
              case '\n':
                  {
                     flag = 1;
                     white++;
                  }
                  break;
            default :
                  if(flag)
                  {
                     flag = 0;
                     word++;
                  }
          }/* end of switch */
    }/* end of while */
    fclose(in);
    fclose(out);
    printf("Total characters = %d, white_space = %d, words = %d\n",
            count, white, word);
    return 0;
}

 

(5) fgets(파일에서 한 행 입력)

형식

fgets(but, n, fp)

buf의 포인터(char *형)를 리턴한다.

buf는 문자열 버터(char *형)

fp는 오픈된 파일 포인터(FILE *형)

n은 read 할 수 있는 최대수(int 형)

 

기능

파일 포인터 fp로 지시된 파일에서 버퍼 buf에 한 행을 read한다. 한 행의 끝은 \n 코드로 한다. fgets가 정상으로 되면 buf로 포인터가 지정되지만 파일 종결 또는 에러가 발생하면 NULL(0)이 리턴된다. MS-DOS에서 한 행의 끝은  CR/LF의 두 가지 문자로 실행되지만 fgets는 CR/LF을 C의 끝 기호('\n')로 변환해서 문자열의 끝으로 '\0'을 추가시킨다.

파일 fp에서 한 행 단위로 read하고 화면에 출력시키는 프로그램은 다음과 같다.

     while(fgets(buf, 256, fp) != NULL)
         printf("%s",buf);

 

확인 문제 4

/* fgets( ) 함수의 사용의 예 */
#include <stdio.h>
#define MAX 5
int main(void)
{
    int i;
    char string[MAX];

    for(i = 1; i <= 3; i++)
    {
        printf("[%d]. Input a string: ", i);
        fgets(string, MAX, stdin);
        printf("    result ==> %s\n", string);
        fflush(stdin);
    }
    return 0;
}

 

(6) fputs(파일의 한 행 출력)

형식

fputs(buf, fp)

최종 출력 문자(int형)를 리턴

buf는 문자열 버퍼(char *형)

fp는 오픈된 파일 포인터(FILE *형)

 

기능

버퍼 buf의 문자열('\0'으로 종료)을 파일 포인터 fp로 지시된 파일에 write한다. ' 0'은 write되지 않는다. fgets와는 반대로 '\n'은 CR/ LF코드로 변환되어 write된다. fputs은 최종 출력한 문자를 리턴하지만 에러이면 -1을 리턴한다.

 

확인 문제 5

/* fgets( ) 함수와 fputs( ) 함수를 이용한 문자열 입/출력의 예 */
#include <stdio.h>
int main(int argc, char *argv[ ])
{
    FILE *fptr1, *fptr2;
    char array[81];

    if(argc != 3)
    {
        printf("Format: C:\>list11-6 filename filename\n");
        exit(1);
    }
    if((fptr1 = fopen(argv[argc-2], "rt")) == NULL)
    {
        printf("Can't open file %s\n", argv[argc-2]);
        exit(1);
    }
    if((fptr2 = fopen(argv[argc-1], "wt")) == NULL)
    {
        printf("Can't open file %s\n", argv[argc-1]);
        exit(1);
    }
    while(fgets(array, 80, fptr1) != NULL)
        fputs(array, fptr2);
    fclose(fptr1);
    fclose(fptr2);
    return 0;
}

 

(7) fprintf(형식 있는 파일 출력)

형식

fprinttf(fp, format[,arg1, arg2 ])

출력한 바이트 수를 리턴한다(int형)

fp는 오픈된 파일 포인터(FILE *형)

arg1과 arg2는 인수

format은 형식 제어 문자열(char *형)

 

기능

파일 fp로 형식 format에 따라 인수 arg1, arg2 의 데이터를 출력한다. 형식 제어의 방법은 printf와 같다. fprintf로 출력한 데이터를 fscanf로 입력할 때, 데이터 분류를 필드폭으로 실행시킬 것인지 분류 기호(space, tab, 개행)로 실행시킬 것인지를 지정해야 한다.

 

(8) fscanf(형식 있는 파일 입력)

형식

fscanf(fp, format, arg1, arg2 )

입력된 항목수를 리턴한다(int형)

fp는 오픈된 파일 포인터(FILE *형)

format은 형식 제어 문자열(char *형)

arg1과 arg2는 인수로서 포인터

 

기능

파일 fp에서 형식 format에 따라 인수 arg1, arg2 로 데이터를 입력한다. 형식 제어 방법은 scanf와 같다. fscanf는 입력된 항목 수를 리턴하지만 파일 끝 또는 에러 때에는 -1을 리턴한다.

 

확인 문제 6

/* fscanf( ) 함수와 fprintf( ) 함수를 사용한 입/출력의 예제 */
#include <stdio.h>
int main(int argc, char *argv[ ])
{
    FILE *fptr1, *fptr2;
    char name[10];
    int cobol, fort, basic, total;
    float average;

    if(argc != 3)
    {
          fprintf(stdout, "Format: C:\>list11-7 filename filename\n");
          exit(1);
    }
    if((fptr1 = fopen(argv[argc-2], "rt")) == NULL)
    {
          fprintf(stdout, "Can't open file %s\n", argv[argc-1]);
          exit(1);
    }
    if((fptr2 = fopen(argv[argc-1], "wt")) == NULL)
    {
          fprintf(stdout,"Can't open file %s\n", argv[argc-1]);
          exit(1);
    }
    fprintf(fptr2,"name  cobol  fort  basic  total    ave\n");
    fprintf(fptr2,"----------------------------------------\n");
    while(fscanf(fptr1,"%s %d %d %d",name,&cobol,&fort,&basic)!= EOF)
    {
          total = cobol + fort + basic;
          average = total / 3.0;
          fprintf(fptr2,"%4s %5d %5d %5d %7d %8.2f\n",
                 name, cobol, fort, basic, total, average);
    }
    fclose(fptr1);
    fclose(fptr2);
    return 0;
}

 

(9) fseek(파일 위치의 이동)

형식

fseek(fp, pos, mode)

정상 ;0, 에러가 발생하면 0 이외의 값을 리턴한다(int형)

fp는 오픈된 파일 포인터(FILE *형)

pos는 이동크기(long형)

mode는 이동 기점 모드. 0/1/2/(int형)

 

기능

파일의 현재 위치는 파일 오픈 때에 파일의 선두에 초기 설정되며 그 후에 입출력 (getc/putc, fgets/fputs 등)을 할 때마다 자동적으로 다음 데이터로 이동된다. fseek을 사용하면 파일의 현재 위치를 임의의 위치에 이동시킬 수 있다.pos는 이동시키는 바이트수(long형)이며, 이동 방향은 mode의 지정에 의하여 다음과 같이 된다.

       mode - 0 파일의 선두에서
                   1 파일의 현재 위치에서
                   2 파일의 끝에서부터

fseek(fp,16L,0)파일 선두에서 16바이트 앞으로 파일 현재 위치를 이동시킨다. fseek(fp,0L,2)은 파일의 끝으로 파일의 현재 위치를 이동시킨다.

 

확인 문제 7

/* fseek( ) 함수와 ftell( ) 함수의 사용의 예제, 화일을 역으로 출력 */
#include <stdio.h>
#include <stdlib.h>
#define CNTL_Z '\032'
int main(int argc, char *argv[ ])
{
   char ch;
   FILE *fp;
   long count, last;

   if (argc != 2)
   {
          printf("Format: C:\>list11-11 file_name\n");
          exit(1);
   }
   if ((fp = fopen(argv[1], "rb")) == NULL)
   {
           printf("Can't open %s\n", argv[1]);
           exit(1);
   }
   fseek(fp, 0L, SEEK_END);
   last = ftell(fp);
   for (count = 1L; count <= last; count++)
   {
          fseek(fp, -count, SEEK_END);
          ch = getc(fp);
          if (ch != CNTL_Z && ch != '\r' && ch != '\n')
                  putchar(ch);
   }
   fclose(fp);
   return 0;
}

 

 

 

그리드형

댓글