File input/output
Sometimes devices/directories and other are files
Text stream - sequence of symbols, separated by
\n(like string literals)
Binary stream - sequence of bytes (like numbers)
#include <stdio.h>
Open File
- FILE - Structure, stores current state of file work
- Position in file
- Work mode (r/w and etc.)
fopen()FILE *fopen(const char *fname, const char *mode)- returns pointer to
FILEstructure mode’s:r- read onlyw- write only (it creates if not exists, or overwrites)a- appendrbwbab- same with binaryr+- read and writew+- empty file and write/reada+-set pointer to end and append/read
- may set the
errno:- if
fp = fopen("my-file.txt", "w") - file not found
- rejected by rights (OS)
- if
#include <errno.h>
errno = 0;
fp = fopen("file.txt", "w");
perror("fopen");
// or strerror from <str.h>
printf("%s", strerror(errno));Read\Write
fprintf()int fprintf(FILE *fp, const char *format_string, ...)- returns count of success wrote symbols
fscanf()int fscanf(FILE *fp, const char *format_string, ...)
Single Char In
int fgetc(FILE *fp)- computes its arg single time
- may be slower (function call uses resources)
- it uses local variables
int getc(FILE *fp)- may be implemented like macros
- may be cases with incorrect work (arg computes >1 time)
- dangerous with side effect like
x=y++ - example:
- dangerous with side effect like
FILE *streams[100];
int i = 3;
getc(streams[i++]);Assume, gets() implementation is:
getc(streams[i++])
streams[i++] -> buf = ...
streams[i++] -> sz = ...
// we have multiple increasing `i` in one iteration.It can use arg multiple time
int getchar(void)-
fgetc(stdin)
-
int ungetc(int c, FILE *fp)
Write in
stdin-UB(undefined behavior)
fgets(char buf[], int sz, FILE *fp)- reads until
\nor untilszsymbols
- reads until
Single Char Out
int fputc(int c, FILE *fp)int putc(int c, FILE *fp)int putchar(int c)int fputs(const char *s, FILE *fp)int puts(const char *s)
Write buffer
stdlibI/O is buffed (with disable possibility)
-> write (fputs) -> buffer in memory -> file on disk
We need buffer because it’s way more fast, than writing on disk
int fflush(FILE *fp)- resetting the buffer to disk (slow operation)
- returns error code
Use
flushorfseekbehind read and write.
Check EOF
- Stream stores:
- position
- end indicator
- error indicator
int feof(FILE *fp)EOF->1- else ->
0
int ferror(FILE *fp)fclear(?)- reset indicators
Change Pointer Position
int fseek(FILE *fp, long offset, int whence)offset-whence- start offset point
SEEK_CUR- current position constant (it changes with position)SEEK_SET- file start constantSEEK_END- file end constantlong ftell(FILE *fp)- returns current position
long fgetpos(FILE *fp)long fsetpos(FILE *fp)
Close File
Simultaneously we can open limited number of files.
By default we have openedstdin,stdout,stderr.
fclose(FILE *fp);
Example
Replace substring to .
- Simple way:
- With additional file
src.txt->dst.txt
- With additional file
- Harder way (in-place):
- It’s possible if and lengths are same
”a” -> “b”
do it at home
FILE *f = fopen("txt.txt", "r+");
while (!feof(f)) {
c = getchar
}