Модификации режима в fopen() и freopen() могут быть одним из следующих значений:
- «r» : открыть файл в режиме только для чтения, при этом курсор установлен в начало файла.
- «r+» : открыть файл в режиме чтения-записи, при этом курсор установлен в начало файла.
- «w» : открыть или создать файл в режиме только для записи, при этом его содержимое обрезается до 0 байтов. Курсор установлен в начало файла.
- «w+» : открыть или создать файл в режиме чтения-записи, при этом его содержимое обрезается до 0 байтов. Курсор установлен в начало файла.
- «a» : открыть или создать файл в режиме только записи, при этом курсор установлен в конец файла.
- «a+» : открыть или создать файл в режиме чтения-записи, при этом указатель чтения установлен в начало файла. Выход, однако, всегда будет добавлен в конец файла.
Каждый из этих файловых режимов может иметь b добавленный после начальной буквы (например, «rb» или «a+b» или «ab+» ). b означает, что файл следует рассматривать как двоичный файл вместо текстового файла в тех системах, где есть разница. Это не влияет на Unix-подобные системы; это важно для систем Windows. (Кроме того, Windows fopen позволяет явному t вместо b указывать «текстовый файл» и множество других параметров для конкретной платформы.)
What is the Output | GUESS the OUTPUT of this C PROGRAM
- «wx» : создать текстовый файл в режиме только для записи. Файл может не существовать .
- «wbx» : создать двоичный файл в режиме только для записи. Файл может не существовать .
x , если присутствует, должен быть последним символом в строке режима.
Открыть и записать в файл
#include /* for perror(), fopen(), fputs() and fclose() */ #include /* 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 для output.txt если аргумент не указан. Если файл с тем же именем уже существует, его содержимое отбрасывается, и файл рассматривается как новый пустой файл. Если файлы еще не существуют, создается вызов fopen() .
Если по какой-либо причине вызов fopen() завершился с ошибкой, он возвращает значение NULL и устанавливает значение глобальной переменной errno . Это означает, что программа может проверить возвращаемое значение после вызова fopen() и использовать perror() если fopen() терпит неудачу.
What is the Output | C Programs & Answers | Video Tutorials for Beginners
Если вызов fopen() завершается успешно, он возвращает действительный указатель FILE . Этот указатель затем может использоваться для ссылки на этот файл до тех пор, пока на нем не будет fclose() .
Функция fputs() записывает данный текст в открытый файл, заменяя любое предыдущее содержимое файла. Аналогично функции fopen() функция fputs() также устанавливает значение errno если она терпит неудачу, хотя в этом случае функция возвращает EOF для указания отказа (иначе он возвращает неотрицательное значение).
Функция fclose() сбрасывает любые буферы, закрывает файл и освобождает память, на которую указывает FILE * . Возвращаемое значение указывает на завершение так же, как и fputs() (хотя при успешном завершении возвращает «0»), снова также устанавливая значение errno в случае сбоя.
fprintf
Вы можете использовать fprintf в файле так же, как на консоли с printf . Например, чтобы отслеживать выигрыши игр, потери и связи, которые вы могли бы написать
/* saves wins, losses and, ties */ void savewlt(FILE *fout, int wins, int losses, int ties)
Замечание: некоторые системы (печально, Windows) не используют то, что большинство программистов назвали бы «нормальными» окончаниями строк. Хотя UNIX-подобные системы используют n для завершения строк, Windows использует пару символов: r (возврат каретки) и n (строка). Эта последовательность обычно называется CRLF.
Однако при использовании C вам не нужно беспокоиться об этих деталях, зависящих от платформы. AC-компилятор необходим для преобразования каждого экземпляра n в правильную конечную строку платформы. Поэтому компилятор Windows будет конвертировать n в r n, но компилятор UNIX сохранит его как есть.
Выполнить процесс
#include 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; >
Эта программа запускает процесс ( netstat ) через popen() и считывает весь стандартный вывод процесса и выводит его на стандартный вывод.
Примечание: popen() не существует в стандартной библиотеке C , но это скорее часть POSIX C )
Получить строки из файла с помощью getline ()
Библиотека POSIX C определяет функцию getline() . Эта функция выделяет буфер для хранения содержимого строки и возвращает новую строку, количество символов в строке и размер буфера.
Пример программы, которая получает каждую строку из example.txt :
#include #include #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_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_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. getline() работает даже с текстовыми файлами Windows, потому что с завершением многобайтовой строки ( «rn») ‘ n’` по-прежнему остается последним символом в строке.
Пример реализации getline()
#include #include #include #include #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] = ‘