수색…


통사론

  • #include <stdio.h> / * 다음 섹션을 사용하려면 이것을 포함 시키십시오. * /
  • FILE * fopen (const char * path, const char * mode); / * 지정된 모드경로 의 파일에서 스트림 열기 * /
  • FILE * freopen (const char * path, const char * 모드, FILE * stream); / * 지정된 모드경로 에있는 파일의 기존 스트림을 다시여십시오 * /
  • int fclose (FILE * stream); / * 열린 스트림 닫기 * /
  • size_t fread (void * ptr, size_t size, size_t nmemb, FILE * stream); / * 스트림 에서 각각 size 바이트의 nmemb 요소를 대부분 읽고 ptr에 씁니다. read 요소의 수를 돌려줍니다. * /
  • size_t fwrite (const void * ptr, size_t size, size_t nmemb, FILE * stream); / * size 바이트의 nmemb 요소를 ptr 에서 스트림으로 씁니다. 기입해진 요소의 수를 돌려줍니다. * /
  • int fseek (FILE * stream, long offset, int whence); / * 스트림의 커서를 whence가 말한 오프셋 에 상대적으로 오프셋 으로 설정하고, 성공하면 0을 반환합니다. * /
  • long ftell (FILE * 스트림); / * 스트림의 선두로부터 현재의 커서 위치의 오프셋 (offset)를 돌려줍니다. * /
  • void rewind (FILE * stream); / * 커서 위치를 파일의 시작 부분으로 설정하십시오. * /
  • int fprintf (FILE * fout, const char * fmt, ...); / * fout에 printf 형식 문자열을 기록합니다 * /
  • FILE * stdin; / * 표준 입력 스트림 * /
  • FILE * stdout; / * 표준 출력 스트림 * /
  • FILE * stderr; / * 표준 오류 스트림 * /

매개 변수

매개 변수 세부
const char * 모드 파일 지원 스트림의 열기 모드를 설명하는 문자열. 가능한 값에 대한 설명을보십시오.
int where 파일의 처음부터 SEEK_SET , SEEK_END 의 끝에서부터 설정, SEEK_CUR 을 사용하여 현재 커서 값을 기준으로 설정할 수 있습니다. 참고 : SEEK_END 는 휴대 할 수 없습니다.

비고

모드 문자열 :

fopen()freopen() 모드 문자열은 다음 값 중 하나 일 수 있습니다.

  • "r" : 커서를 파일의 시작 부분으로 설정하고 읽기 전용 모드로 파일을 엽니 다.
  • "r+" : 커서를 파일의 시작 부분으로 설정하고 읽기 - 쓰기 모드로 파일을 엽니 다.
  • "w" : 쓰기 전용 모드로 파일을 열거 나 만듭니다. 내용은 0 바이트로 잘립니다. 커서는 파일의 시작 부분으로 설정됩니다.
  • "w+" : 내용을 0 바이트로 절단하여 읽기 / 쓰기 모드로 파일을 열거 나 작성하십시오. 커서는 파일의 시작 부분으로 설정됩니다.
  • "a" : 커서를 파일 끝으로 설정하고 쓰기 전용 모드로 파일을 열거 나 작성하십시오.
  • "a+" : 읽기 - 쓰기 모드로 파일을 열거 나 작성하십시오. 이때 읽기 - 커서는 파일의 시작 부분으로 설정하십시오. 그러나 출력은 항상 파일의 끝에 추가됩니다.

이러한 각 파일 모드는 초기 문자 다음에 b 추가 될 수 있습니다 (예 : "rb" 또는 "a+b" 또는 "ab+" ). b 는 차이가있는 시스템에서 파일을 텍스트 파일 대신 2 진 파일로 처리해야 함을의 L합니다. 유닉스 계열 시스템에는 차이가 없다. 그것은 Windows 시스템에서 중요합니다. (또한 Windows fopen 사용하면 '텍스트 파일'을 나타내는 b 대신 명시적인 t 를 사용할 수 있으며 기타 플랫폼 별 옵션도 있습니다.)

C11
  • "wx" : 쓰기 전용 모드로 텍스트 파일을 만듭니다. 파일이 존재하지 않을 수 있습니다 .
  • "wbx" : 쓰기 전용 모드로 이진 파일을 만듭니다. 파일이 존재하지 않을 수 있습니다 .

x 가있는 경우 x 는 모드 문자열의 마지막 문자 여야합니다.

파일 열기 및 쓰기

#include <stdio.h>   /* for perror(), fopen(), fputs() and fclose() */
#include <stdlib.h>  /* for the EXIT_* macros */
 
int main(int argc, char **argv)
{
    int e = EXIT_SUCCESS;

    /* Get path from argument to main else default to output.txt */
    char *path = (argc > 1) ? argv[1] : "output.txt";

    /* Open file for writing and obtain file pointer */
    FILE *file = fopen(path, "w");
    
    /* Print error message and exit if fopen() failed */
    if (!file) 
    {
        perror(path);
        return EXIT_FAILURE;
    }

    /* Writes text to file. Unlike puts(), fputs() does not add a new-line. */
    if (fputs("Output in file.\n", file) == EOF)
    {
        perror(path);
        e = EXIT_FAILURE;
    }

    /* Close file */
    if (fclose(file)) 
    {
        perror(path);
        return EXIT_FAILURE;
    }
    return e;
}

이 프로그램은 main에 대한 인수에 주어진 이름으로 파일을 열고, 인수가 주어지지 않으면 output.txt 기본값으로 사용합니다. 같은 이름의 파일이 이미 존재하면 그 내용은 삭제되고 파일은 새로운 빈 파일로 취급됩니다. 파일이 아직 존재하지 않으면 fopen() 호출로 파일이 작성됩니다.

어떤 이유로 fopen() 호출이 실패하면 NULL 값을 반환하고 전역 errno 변수 값을 errno 합니다. 이것은 프로그램이 fopen() 호출 후에 반환 된 값을 테스트하고 fopen() 이 실패하면 perror() 사용할 수 있음을 의미합니다.

fopen() 호출이 성공하면 유효한 FILE 포인터를 반환합니다. fclose() 가 호출 될 때까지이 포인터를 사용하여이 파일을 참조 할 수 있습니다.

fputs() 함수는 주어진 텍스트를 열린 파일에 기록하여 파일의 이전 내용을 대체합니다. fopen() 과 마찬가지로 fputs() 함수도 실패 할 경우 errno 값을 설정합니다.이 경우 함수는 실패를 나타내는 EOF 를 반환하지만 그렇지 않은 경우 음수가 아닌 값을 반환합니다.

fclose() 함수는 모든 버퍼를 비우고 파일을 닫은 다음 FILE * 가리키는 메모리를 해제합니다. 반환 값은 fputs() 가 수행하는 것처럼 완료를 나타내며 fputs() 성공하면 '0'을 반환하지만) 실패한 경우 errno 값도 다시 설정합니다.

fprintf

printf 있는 콘솔 에서처럼 fprintf 를 파일에 사용할 수 있습니다. 예를 들어 게임의 승률, 손실 및 동점을 기록하기 위해

/* saves wins, losses and, ties */
void savewlt(FILE *fout, int wins, int losses, int ties)
{
    fprintf(fout, "Wins: %d\nTies: %d\nLosses: %d\n", wins, ties, losses);
}

참고 사항 : 일부 시스템 (악의적으로는 Windows)은 대부분의 프로그래머가 "정상"줄 끝이라고 부르는 것을 사용하지 않습니다. UNIX 계열 시스템은 \ n을 사용하여 행을 종료하지만 Windows에서는 \ r (캐리지 리턴) 및 \ n (줄 바꿈) 문자 쌍을 사용합니다. 이 순서는 일반적으로 CRLF라고합니다. 그러나 C를 사용할 때마다 이러한 고도의 플랫폼 종속적 인 세부 사항에 대해 걱정할 필요가 없습니다. \ n의 모든 인스턴스를 올바른 플랫폼 행 끝으로 변환하려면 AC 컴파일러가 필요합니다. 따라서 Windows 컴파일러는 \ n을 \ r \ n으로 변환하지만 UNIX 컴파일러는 그대로 유지합니다.

프로세스 실행

#include <stdio.h>

void print_all(FILE *stream)
{
    int c;
    while ((c = getc(stream)) != EOF)
        putchar(c);
}
int main(void)
{
    FILE *stream;

    /* call netstat command. netstat is available for Windows and Linux */
    if ((stream = popen("netstat", "r")) == NULL)
        return 1;
  
    print_all(stream);
    pclose(stream);
    return 0;
}

이 프로그램은 popen() )을 통해 프로세스 ( netstat )를 실행하고 프로세스의 모든 표준 출력을 읽고이를 표준 출력에 반영합니다.

참고 : popen()표준 C 라이브러리 에는 없지만 POSIX C 의 일부입니다.

getline ()을 사용하여 파일에서 행 가져 오기

POSIX C 라이브러리는 getline() 함수를 정의합니다. 이 함수는 라인 내용을 담을 버퍼를 할당하고 새로운 라인, 라인의 문자 수 및 버퍼의 크기를 반환합니다.

example.txt 에서 각 행을 가져 오는 예제 프로그램 :

#include <stdlib.h>
#include <stdio.h>  


#define FILENAME "example.txt"

int main(void)
{
  /* Open the file for reading */
  char *line_buf = NULL;
  size_t line_buf_size = 0;
  int line_count = 0;
  ssize_t line_size;
  FILE *fp = fopen(FILENAME, "r");
  if (!fp)
  {
    fprintf(stderr, "Error opening file '%s'\n", FILENAME);
    return EXIT_FAILURE;
  }

  /* Get the first line of the file. */
  line_size = getline(&line_buf, &line_buf_size, fp);

  /* Loop through until we are done with the file. */
  while (line_size >= 0)
  {
    /* Increment our line count */
    line_count++;

    /* Show the line details */
    printf("line[%06d]: chars=%06zd, buf size=%06zu, contents: %s", line_count,
        line_size, line_buf_size, line_buf);

    /* Get the next line */
    line_size = getline(&line_buf, &line_buf_size, fp);
  }

  /* Free the allocated line buffer */
  free(line_buf);
  line_buf = NULL;

  /* Close the file now that we are done with it */
  fclose(fp);

  return EXIT_SUCCESS;
}

입력 파일 example.txt

This is a file
  which has
multiple lines
    with various indentation,
blank lines



a really long line to show that getline() will reallocate the line buffer if the length of a line is too long to fit in the buffer it has been given,
  and punctuation at the end of the lines.

산출

line[000001]: chars=000015, buf size=000016, contents: This is a file
line[000002]: chars=000012, buf size=000016, contents:   which has
line[000003]: chars=000015, buf size=000016, contents: multiple lines
line[000004]: chars=000030, buf size=000032, contents:     with various indentation,
line[000005]: chars=000012, buf size=000032, contents: blank lines
line[000006]: chars=000001, buf size=000032, contents: 
line[000007]: chars=000001, buf size=000032, contents: 
line[000008]: chars=000001, buf size=000032, contents: 
line[000009]: chars=000150, buf size=000160, contents: a really long line to show that getline() will reallocate the line buffer if the length of a line is too long to fit in the buffer it has been given,
line[000010]: chars=000042, buf size=000160, contents:  and punctuation at the end of the lines.
line[000011]: chars=000001, buf size=000160, contents: 

이 예에서 getline() 은 처음에는 아무런 버퍼도 할당하지 않고 호출됩니다. 이 첫 번째 호출 중에 getline() 은 버퍼를 할당하고 첫 번째 행을 읽고 그 행의 내용을 새 버퍼에 저장합니다. 후속 호출에서 getline() 은 동일한 버퍼를 업데이트하고 더 이상 전체 행에 적합하지 않을 때만 버퍼를 재 할당합니다. 그런 다음 임시 버퍼는 파일을 완료하면 해제됩니다.

또 다른 옵션은 getdelim() 입니다. 줄 끝 문자를 지정한다는 점을 제외하면 getline() 과 같습니다. 이것은 파일 유형에 대한 행의 마지막 문자가 '\ n'이 아닌 경우에만 필요합니다. 끝나는 멀티 바이트 행 ( "\r\n") '\ "\r\n") 은 (는) 줄의 마지막 문자이기 때문에 getline() 은 Windows 텍스트 파일에서도 작동합니다.

getline() 구현 예

#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <stdint.h>


#if !(defined _POSIX_C_SOURCE)
typedef long int ssize_t;
#endif

/* Only include our version of getline() if the POSIX version isn't available. */

#if !(defined _POSIX_C_SOURCE) || _POSIX_C_SOURCE < 200809L

#if !(defined SSIZE_MAX)
#define SSIZE_MAX (SIZE_MAX >> 1)
#endif

ssize_t getline(char **pline_buf, size_t *pn, FILE *fin)
{
  const size_t INITALLOC = 16;
  const size_t ALLOCSTEP = 16;
  size_t num_read = 0;

  /* First check that none of our input pointers are NULL. */
  if ((NULL == pline_buf) || (NULL == pn) || (NULL == fin))
  {
    errno = EINVAL;
    return -1;
  }

  /* If output buffer is NULL, then allocate a buffer. */
  if (NULL == *pline_buf)
  {
    *pline_buf = malloc(INITALLOC);
    if (NULL == *pline_buf)
    {
      /* Can't allocate memory. */
      return -1;
    }
    else
    {
      /* Note how big the buffer is at this time. */
      *pn = INITALLOC;
    }
  }

  /* Step through the file, pulling characters until either a newline or EOF. */

  {
    int c;
    while (EOF != (c = getc(fin)))
    {
      /* Note we read a character. */
      num_read++;

      /* Reallocate the buffer if we need more room */
      if (num_read >= *pn)
      {
        size_t n_realloc = *pn + ALLOCSTEP;
        char * tmp = realloc(*pline_buf, n_realloc + 1); /* +1 for the trailing NUL. */
        if (NULL != tmp)
        {
          /* Use the new buffer and note the new buffer size. */
          *pline_buf = tmp;
          *pn = n_realloc;
        }
        else
        {
          /* Exit with error and let the caller free the buffer. */
          return -1;
        }

        /* Test for overflow. */
        if (SSIZE_MAX < *pn)
        {
          errno = ERANGE;
          return -1;
        }
      }

      /* Add the character to the buffer. */
      (*pline_buf)[num_read - 1] = (char) c;

      /* Break from the loop if we hit the ending character. */
      if (c == '\n')
      {
        break;
      }
    }

    /* Note if we hit EOF. */
    if (EOF == c)
    {
      errno = 0;
      return -1;
    }
  }

  /* Terminate the string by suffixing NUL. */
  (*pline_buf)[num_read] = '\0';

  return (ssize_t) num_read;
}

#endif

바이너리 파일 열기 및 쓰기

#include <stdlib.h>
#include <stdio.h>


int main(void)
{
   result = EXIT_SUCCESS;

   char file_name[] = "outbut.bin";
   char str[] = "This is a binary file example";
   FILE * fp = fopen(file_name, "wb");
   
   if (fp == NULL)  /* If an error occurs during the file creation */
   {
     result = EXIT_FAILURE;
     fprintf(stderr, "fopen() failed for '%s'\n", file_name);
   }
   else
   {
     size_t element_size = sizeof *str;
     size_t elements_to_write = sizeof str;

     /* Writes str (_including_ the NUL-terminator) to the binary file. */
     size_t elements_written = fwrite(str, element_size, elements_to_write, fp); 
     if (elements_written != elements_to_write)
     {
       result = EXIT_FAILURE;
       /* This works for >=c99 only, else the z length modifier is unknown. */
       fprintf(stderr, "fwrite() failed: wrote only %zu out of %zu elements.\n", 
         elements_written, elements_to_write);
       /* Use this for <c99: *
       fprintf(stderr, "fwrite() failed: wrote only %lu out of %lu elements.\n", 
         (unsigned long) elements_written, (unsigned long) elements_to_write);
        */
     }

     fclose(fp);
   }

   return result;
}

이 프로그램은 fwrite 함수를 통해 이진 형식의 텍스트를 작성하여 output.bin 파일에 output.bin 합니다.

같은 이름의 파일이 이미 존재하면 그 내용은 삭제되고 파일은 새로운 빈 파일로 취급됩니다.

이진 스트림은 내부 데이터를 투명하게 기록 할 수있는 정렬 된 문자 시퀀스입니다. 이 모드에서는 해석없이 프로그램과 파일 사이에 바이트가 기록됩니다.

정수를 이식성있게 작성하려면 파일 형식이 크거나 리틀 엔디안 형식인지, 크기 (일반적으로 16, 32 또는 64 비트)가 필요한지 여부를 알아야합니다. 그런 다음 비트 시프 팅 및 마스킹을 사용하여 올바른 순서로 바이트를 쓸 수 있습니다. C의 정수는 2의 보수 표현을 가질 수는 없습니다 (거의 모든 구현이 그렇지만). 다행히도 unsigned 로의 변환 2의 보수를 사용하도록 보장됩니다. 따라서 부호있는 정수를 이진 파일에 쓰는 코드는 약간 놀랍습니다.

/* write a 16-bit little endian integer */
int fput16le(int x, FILE *fp)
{
    unsigned int rep = x;
    int e1, e2;

    e1 = fputc(rep & 0xFF, fp);
    e2 = fputc((rep >> 8) & 0xFF, fp);

    if(e1 == EOF || e2 == EOF)
        return EOF;
    return 0;  
}

다른 함수는 크기와 바이트 순서를 약간 수정하여 동일한 패턴을 따릅니다.

fscanf ()

우리가 텍스트 파일을 가지고 있다고 가정 해보고 몇 가지 요구 사항을 수행하기 위해 그 파일의 모든 단어를 읽고 싶습니다.

file.txt :

This is just
a test file
to be used by fscanf()

이것이 주요 기능입니다.

#include <stdlib.h>
#include <stdio.h>

void printAllWords(FILE *);

int main(void)
{
  FILE *fp;

  if ((fp = fopen("file.txt", "r")) == NULL) {
      perror("Error opening file");
      exit(EXIT_FAILURE);
  }

  printAllWords(fp);

  fclose(fp);
  
  return EXIT_SUCCESS;
}

void printAllWords(FILE * fp)
{
    char tmp[20];
    int i = 1;

    while (fscanf(fp, "%19s", tmp) != EOF) {
        printf("Word %d: %s\n", i, tmp);
        i++;
    }
}

출력은 다음과 같습니다.

Word 1: This 
Word 2: is 
Word 3: just
Word 4: a 
Word 5: test
Word 6: file
Word 7: to
Word 8: be 
Word 9: used
Word 10: by
Word 11: fscanf()

파일에서 행 읽기

stdio.h 헤더는 fgets() 함수를 정의합니다. 이 함수는 스트림에서 행을 읽고 지정된 문자열에 저장합니다. 이 함수는 n - 1 자 중 하나를 읽거나 개행 문자 ( '\n' )를 읽거나 파일 끝 (EOF)에 도달하면 스트림에서 텍스트 읽기를 중지합니다.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define MAX_LINE_LENGTH 80

int main(int argc, char **argv)
{
    char *path;
    char line[MAX_LINE_LENGTH] = {0};
    unsigned int line_count = 0;
    
    if (argc < 1)
        return EXIT_FAILURE;
    path = argv[1];
    
    /* Open file */
    FILE *file = fopen(path, "r");
    
    if (!file)
    {
        perror(path);
        return EXIT_FAILURE;
    }
    
    /* Get each line until there are none left */
    while (fgets(line, MAX_LINE_LENGTH, file))
    {
        /* Print each line */
        printf("line[%06d]: %s", ++line_count, line);
        
        /* Add a trailing newline to lines that don't already have one */
        if (line[strlen(line) - 1] != '\n')
            printf("\n");
    }
    
    /* Close file */
    if (fclose(file))
    {
        return EXIT_FAILURE;
        perror(path);
    }
}

다음 텍스트가 들어있는 파일의 경로 인 인수를 사용하여 프로그램을 호출합니다.

This is a file
  which has
multiple lines
    with various indentation,
blank lines



a really long line to show that the line will be counted as two lines if the length of a line is too long to fit in the buffer it has been given,
  and punctuation at the end of the lines.

결과는 다음과 같습니다.

line[000001]: This is a file
line[000002]:   which has
line[000003]: multiple lines
line[000004]:     with various indentation,
line[000005]: blank lines
line[000006]: 
line[000007]: 
line[000008]: 
line[000009]: a really long line to show that the line will be counted as two lines if the le
line[000010]: ngth of a line is too long to fit in the buffer it has been given,
line[000011]:  and punctuation at the end of the lines.
line[000012]: 

이 아주 간단한 예제는 길이가 고정 된 최대 줄 길이를 허용하므로 긴 줄이 실제로 두 줄로 계산됩니다. fgets() 함수는 호출 된 코드가 읽을 줄의 대상으로 사용할 메모리를 제공해야합니다.

POSIX는 getline() 함수를 사용할 수 있도록 해준다. 대신 충분한 메모리가있는 한, 길이에 상관없이 버퍼를 확장하기 위해 내부적으로 메모리를 할당한다.



Modified text is an extract of the original Stack Overflow Documentation
아래 라이선스 CC BY-SA 3.0
와 제휴하지 않음 Stack Overflow