#include <stdio.h> <wchar.h> for wide-character versions.size_tsizeof operator, an
unsigned integerFILEfpos_tNULLstdin, stdout, stderr _IOFBF,
_IOLBF,
_IONBF fopen()SEEK_CUR, SEEK_END, SEEK_SET L_tmpnam, TMP_MAX FILE *fopen(const char * restrict filename, const char *
restrict mode);NULLmode is one of"r" |
open text file for reading |
"w" |
open text file for writing; truncate to zero length or create |
"a" |
open or create text file for writing at
end-of-file; append |
"rb" |
open binary file for reading |
"wb" |
open binary file for
writing; truncate to zero length or create |
"ab" |
open or create binary file for writing at end-of-file; append |
"r+" |
open text file for update (reading and writing) |
"w+" |
open text file for update; truncate to zero length or create |
"a+" |
open or create text file for update, writing
at end-of-file; append |
"r+b" or "rb+" |
open binary file for update (reading and writing) |
"w+b" or "wb+" |
open binary file for update; truncate to zero length or create |
"a+b" or "ab+" |
open or create binary file for update, writing
at end-of-file; append |
OPEN_MAX, defined by Posix, in <limits.h>char large
enough
to hold the
longest file name string that the implementation guarantees
can be
openedint fclose(FILE *stream);int fflush(FILE *stream);FILE *freopen(const char * restrict filename, const char
*
restrict mode, FILE * restrict stream);void setbuf(FILE * restrict stream, char * restrict
buf);setvbuf() insteadint setvbuf(FILE * restrict stream, char * restrict buf,
int
mode, size_t size);_IOFBF, _IOLBF, _IONBF are used as mode
values for setvbuf() to indicate the buffering
style
(fully-buffered, line-buffered, unbuffered)int fprintf(FILE * restrict stream, const char *
restrict
format,
...); int fscanf(FILE * restrict stream, const char * restrict
format,
...);int printf(const char * restrict format, ...); int scanf(const char * restrict format, ...);int snprintf(char * restrict s, size_t n, const char *
restrict
format, ...); int sprintf(char * restrict s, const char * restrict
format,
...); int sscanf(const char * restrict s, const char *
restrict
format,
...);int vfprintf(FILE * restrict stream, const char *
restrict
format, va_list arg); int vfscanf(FILE * restrict stream, const char *
restrict
format,
va_list arg); int vprintf(const char * restrict format, va_list arg);
int vscanf(const char * restrict format, va_list arg); int vsnprintf(char * restrict s, size_t n, const char *
restrict
format, va_list arg); int vsprintf(char * restrict s, const char * restrict
format,
va_list arg); int vsscanf(const char * restrict s, const char *
restrict
format, va_list arg);int fgetc(FILE *stream); char *fgets(char * restrict s, int n, FILE * restrict
stream);fgets function reads at most one less than
the number of characters specified by n from the
stream
pointed to by stream into the array pointed to
by s.
No
additional
characters
are
read
after a new-line character (which is
retained) or after end-of-file. A null character is
written
immediately after the last character read into the array. fgets function returns s if
successful. If end-of-file is encountered and no
characters have
been read into the array, the contents of the array remain
unchanged
and a null pointer is returned. If a read error occurs
during the
operation, the array contents are indeterminate and a null
pointer is
returned. feof() and ferror() functions.
int fputc(int c, FILE *stream); int fputs(const char * restrict s, FILE * restrict
stream); int getc(FILE *stream); getc() is probably a macro. fgetc()
is definitely a function.int getchar(void); getchar() is the same as getc(stdin)char *gets(char *s);int putc(int c, FILE *stream); putc() is probably a macro. fputc()
is definitely a function.int putchar(int c); putchar(c) is the same as putc((c),
stdout)int puts(const char *s); int ungetc(int c, FILE *stream);c back to the stream's buffer, and clear
the
end-of-file indicator.size_t fread(void * restrict ptr, size_t size, size_t
nmemb, FILE
* restrict stream); size_t fwrite(const void * restrict ptr, size_t size,
size_t
nmemb, FILE * restrict stream);s is an object of struct
type, for example, fwrite(&s, sizeof(s), 1,
fp);int fseek(FILE *stream, long int offset, int whence);offset
bytes
from the beginning of the file (whence = SEEK_SET),
from
the current position (whence
=
SEEK_CUR), from the end of the file (whence =
SEEK_END),
or
from
elsewhere
(whence = any value obtained from ftell())long int ftell(FILE *stream);void rewind(FILE *stream);(void) fseek(stream, 0L,
SEEK_SET)int fgetpos(FILE * restrict stream, fpos_t * restrict
pos);int fsetpos(FILE *stream, const fpos_t *pos);ftell(),
fseek()fpos_t file_position;
fgetpos(fp, &file_position); // save current
position
// do some reads and writes
fsetpos(fp, &file_position); // return to previous
positionint fseeko(FILE *stream, off_t offset, int whence);off_t ftello(FILE *stream);off_t
may
be 32 or 64 bitsint feof(FILE *stream); int ferror(FILE *stream); void clearerr(FILE *stream); void perror(const char *s);errnoint remove(const char *filename); int rename(const char *old, const char *new); FILE *tmpfile(void);"wb+"
mode); will be removed when
closedchar *tmpnam(char *s);TMP_MAX L_tmpnam char large
enough
to hold a
temporary file name string generated by tmpnam()#include <stdio.h>
FILE *infile;
char *infile_name;
if (... should
take
input from stdin ...)
{ infile = stdin; infile_name = "[stdin]"; }
else
{ infile_name = argv[...
something
...]; /* also use strdup()? */
infile = fopen(infile_name,
"r"); /* read-only */
if (infile == NULL)
{
fprintf(stderr,
"%s: cannot open file %s: %s\n",
program_name, infile_name, strerror(errno));
exit(EXIT_FAILURE);
/* or something less brutal */
}
}
char buffer[128];
while (fgets(buffer, sizeof(buffer), infile) != NULL)
{
/* Note that buffer has a newline at the
end
if the input line
* was short enough to
fit.
* NULL indicates end-of-file or
error.
* Is line-too-long an error?
*/
if (verbose) printf("%s: have: %s",
program_name,
buffer);
/* do the work */
}
/* No more input. Was it an input error or just
end-of-file?
*/
if (feof(infile))
{ printf("%s: end of input\n", program_name);
}
if (ferror(infile))
{ printf("%s: error reading input\n",
program_name);
}
if (fclose(infile) != 0)
{
fprintf(stderr, "%s: cannot close
file %s: %s\n",
program_name,
infile_name,
strerror(errno));
exit(EXIT_FAILURE);
/* or something less brutal */
}
int read_file(char *file);
int read_line(FILE *fileptr);
// return 0 for success, -1 for failure
if (read_file(input_file_name) == -1)
{
printf("read_file() failed: %s\n",
input_file_name);
}
int read_file(char *file)
{
if (file == NULL)
{
printf("read_file()
failed: NULL arg\n");
return -1;
}
FILE *input = fopen(file, "r");
if (input == NULL)
{
printf("read_file() failed: %s not
opened:
%s\n",
file,
strerror(errno));
return -1;
}
while (read_line(input) == 0) ;
fclose(input);
return 0;
}
int read_line(FILE *fileptr)
{
if (fileptr == NULL)
{ return -1; }
char buffer[1024];
if (fgets(buffer, sizeof(buffer),
fileptr) ==
NULL)
{
return -1; // EOF or error
}
... do something with buffer
return 0;
}
What should you do if there is an input line longer than 1024
characters?
typedef struct {
unsigned char _flag; /* state of the stream */
int _file; /* file descriptor */
ssize_t _len; /* total len of file */
ssize_t _offset; /* offset within the file */
char _name[256]; /* name of the file (for debugging) */
} FILE;
#define BUFSIZ 1024
#define _SBFSIZ 8
extern struct _iobuf {
int _cnt;
unsigned char *_ptr;
unsigned char *_base;
int _bufsiz;
short _flag;
char _file; /* should be short */
} _iob[];
#define _IOFBF 0
#define _IOREAD 01
#define _IOWRT 02
#define _IONBF 04
#define _IOMYBUF 010
#define _IOEOF 020
#define _IOERR 040
#define _IOSTRG 0100
#define _IOLBF 0200
#define _IORW 0400
#define NULL 0
#define FILE struct _iobuf
#define EOF (-1)
#define stdin (&_iob[0])
#define stdout (&_iob[1])
#define stderr (&_iob[2])
#define getc(p) (--(p)->_cnt >= 0 ? ((int)*(p)->_ptr++) : _filbuf(p))Elsewhere,
#define putc(x, p) (--(p)->_cnt >= 0 ?\
(int)(*(p)->_ptr++ = (unsigned char)(x)) :\
(((p)->_flag & _IOLBF) && -(p)->_cnt < (p)->_bufsiz ?\
((*(p)->_ptr = (unsigned char)(x)) != '\n' ?\
(int)(*(p)->_ptr++) :\
_flsbuf(*(unsigned char *)(p)->_ptr, p)) :\
_flsbuf((unsigned char)(x), p)))
/* The routine _flsbuf may or may not actually flush the output buffer. If
* the file is line-buffered, the fact that iop->_cnt has run below zero
* is meaningless: it is always kept below zero so that invocations of putc
* will consistently give control to _flsbuf, even if the buffer is far from
* full. _flsbuf, on seeing the "line-buffered" flag, determines whether the
* buffer is actually full by comparing iop->_ptr to the end of the buffer
* iop->_base + iop->_bufsiz. If it is full, or if an output line is
* completed (with a newline), the buffer is flushed. (Note: the character
* argument to _flsbuf is not flushed with the current buffer if the buffer
* is actually full -- it goes into the buffer after flushing.)
*/
extern int _flsbuf(unsigned char c, FILE *iop);
int putc(int x, FILE *p)
{
unsigned char xx = (unsigned char)(x);
if (--p->_cnt >= 0)
{ return (int)(*p->_ptr++ = xx); }
else
{
if ((p->_flag & _IOLBF) && -p->_cnt < p->_bufsiz)
{
if ((*p->_ptr = xx) != '\n')
{ return (int)(*p->_ptr++); }
else
{ return _flsbuf(*(unsigned char *)p->_ptr, p); }
}
else
{ return _flsbuf(xx, p); }
}
}
<stdio.h>
/* stdio buffers */
struct __sbuf {
unsigned
char
*_base;
int
_size;
};
/* hold a buncha junk that would grow the ABI */
struct __sFILEX;
typedef struct __sFILE {
unsigned char *_p; /* current
position in (some) buffer */
int
_r;
/*
read
space
left
for getc() */
int
_w;
/*
write
space
left
for putc() */
short
_flags; /* flags,
below; this FILE is free if 0 */
short
_file; /*
fileno,
if Unix descriptor, else -1 */
struct __sbuf _bf; /* the
buffer
(at least 1 byte, if !NULL) */
int
_lbfsize; /* 0 or -_bf._size,
for
inline putc */
/* operations */
void
*_cookie; /* cookie passed to
io
functions */
int (*_close)(void *);
int (*_read) (void *, char *, int);
fpos_t (*_seek) (void *, fpos_t, int);
int (*_write)(void *, const char *,
int);
/* separate buffer for long sequences of ungetc() */
struct __sbuf _ub; /* ungetc
buffer */
struct __sFILEX *_extra; /* additions to FILE to not break
ABI */
int
_ur;
/*
saved _r when _r is counting ungetc data */
/* tricks to meet minimum requirements even when malloc()
fails
*/
unsigned char _ubuf[3]; /* guarantee an ungetc() buffer */
unsigned char _nbuf[1]; /* guarantee a getc() buffer */
/* separate buffer for fgetln() when line crosses buffer
boundary */
struct __sbuf _lb; /* buffer
for
fgetln() */
/* Unix stdio files get aligned to block boundaries on
fseek() */
int
_blksize; /* stat.st_blksize
(may
be != _bf._size) */
fpos_t
_offset;
/* current lseek offset (see WARNING) */
} FILE;/* Functions internal to the implementation. */
int __srget(FILE *);
int __swbuf(int, FILE *);
#define __sgetc(p) (--(p)->_r < 0 ? __srget(p) :
(int)(*(p)->_p++))
static __inline int __sputc(int _c, FILE *_p)
{
if (--_p->_w >= 0 || (_p->_w >= _p->_lbfsize
&& (char)_c != '\n'))
return (*_p->_p++ = _c);
else
return (__swbuf(_c, _p));
}