Обробка файлів на C - Як відкрити, закрити та записати у файли

Якщо ви вже писали програму C helloworld, ви вже знаєте базовий файл вводу-виводу на мові C:

/* A simple hello world in C. */ #include  // Import IO functions. #include  int main() { // This printf is where all the file IO magic happens! // How exciting! printf("Hello, world!\n"); return EXIT_SUCCESS; }

Обробка файлів - одна з найважливіших частин програмування. У C ми використовуємо вказівник на структуру типу файлу для оголошення файлу:

FILE *fp;

C надає ряд вбудованих функцій для виконання основних файлових операцій:

  • fopen() - створити новий файл або відкрити існуючий файл
  • fclose() - закрити файл
  • getc() - зчитує символ із файлу
  • putc() - записує символ у файл
  • fscanf() - зчитує набір даних з файлу
  • fprintf() - записує набір даних у файл
  • getw() - зчитує ціле число з файлу
  • putw() - записує ціле число у файл
  • fseek() - встановіть позицію до точки бажання
  • ftell() - вказує поточну позицію у файлі
  • rewind() - встановити позицію на початкову точку

Відкриття файлу

fopen()Функція використовується для створення файлу або відкрити існуючий файл:

fp = fopen(const char filename,const char mode);

Існує багато режимів відкриття файлу:

  • r - відкрити файл у режимі читання
  • w - відкриває або створює текстовий файл у режимі запису
  • a - відкриває файл у режимі додавання
  • r+ - відкриває файл як у режимі читання, так і в режимі запису
  • a+ - відкриває файл як у режимі читання, так і в режимі запису
  • w+ - відкриває файл як у режимі читання, так і в режимі запису

Ось приклад читання даних із файлу та запису до нього:

#include #include main() { FILE *fp; char ch; fp = fopen("hello.txt", "w"); printf("Enter data"); while( (ch = getchar()) != EOF) { putc(ch,fp); } fclose(fp); fp = fopen("hello.txt", "r"); while( (ch = getc(fp)! = EOF) printf("%c",ch); fclose(fp); }

Зараз ви можете подумати: "Це просто друкує текст на екран. Як цей файл виконується введення-виведення?"

Відповідь спочатку не очевидна і потребує певного розуміння щодо системи UNIX. У системі UNIX все обробляється як файл, тобто ви можете читати з нього та писати в нього.

Це означає, що ваш принтер можна абстрагувати як файл, оскільки все, що ви робите з принтером, - це писати за допомогою нього. Також корисно вважати ці файли потоками, оскільки, як ви побачите пізніше, ви можете перенаправити їх за допомогою оболонки.

Отже, як це пов’язано з helloworldфайлом IO?

Коли ви телефонуєте printf, ви насправді просто пишете у спеціальний файл, що називається stdout, скорочення від стандартного виводу . stdoutпредставляє стандартний висновок за рішенням вашої оболонки, яка, як правило, є терміналом. Це пояснює, чому він надрукований на екрані.

Є ще два потоки (тобто файли), які доступні вам із зусиллям, stdinта stderr. stdinпредставляє стандартний вхід , який ваша оболонка зазвичай приєднує до клавіатури. stderrпредставляє стандартний вивід помилки , який ваша оболонка зазвичай приєднує до терміналу.

Рудиментарний файл IO, або Як я навчився прокладати труби

Досить теорії, давайте приступимо до справи, написавши якийсь код! Найпростіший спосіб для запису в файл, щоб перенаправити потік виведення , використовуючи інструмент перенаправлення виведення, >.

Якщо ви хочете додати, ви можете використовувати >>:

# This will output to the screen... ./helloworld # ...but this will write to a file! ./helloworld > hello.txt

Зміст hello.txtволі, як не дивно, буде

Hello, world!

Скажімо, у нас є інша програма, яка називається greet, подібна до такої helloworld, яка вітає вас із заданим name:

#include  #include  int main() { // Initialize an array to hold the name. char name[20]; // Read a string and save it to name. scanf("%s", name); // Print the greeting. printf("Hello, %s!", name); return EXIT_SUCCESS; }

Замість читання з клавіатури ми можемо перенаправити stdinчитання з файлу за допомогою <інструменту:

# Write a file containing a name. echo Kamala > name.txt # This will read the name from the file and print out the greeting to the screen. ./greet  Hello, Kamala! # If you wanted to also write the greeting to a file, you could do so using ">".

Примітка: ці оператори переспрямування знаходяться в bashта подібних оболонках.

Справжня угода

Вищевказані методи працювали лише в найосновніших випадках. Якщо ви хочете робити більші та кращі речі, вам, ймовірно, доведеться працювати з файлами всередині C, а не через оболонку.

Для цього ви скористаєтесь функцією, яка називається fopen. Ця функція приймає два рядкові параметри, перший - це ім’я файлу, а другий - режим.

Режим - це, в основному, дозволи, тому rдля читання, wзапису, aдодавання. Ви також можете їх комбінувати, rwщо означає, що ви можете читати та писати у файл. Існує більше режимів, але вони є найбільш часто використовуваними.

Після того, як у вас є FILEвказівник, ви можете використовувати в основному ті самі команди вводу-виводу, які ви б використовували, за винятком того, що вам потрібно fдодати їм префікс, і першим аргументом буде вказівник на файл. Наприклад, printf«s версія файлу fprintf.

Ось програма з назвою, greetingsяка читає файл із файлу, що містить список імен, і записує привітання в інший файл:

#include  #include  int main() { // Create file pointers. FILE *names = fopen("names.txt", "r"); FILE *greet = fopen("greet.txt", "w"); // Check that everything is OK. if (!names || !greet) { fprintf(stderr, "File opening failed!\n"); return EXIT_FAILURE; } // Greetings time! char name[20]; // Basically keep on reading untill there's nothing left. while (fscanf(names, "%s\n", name) > 0) { fprintf(greet, "Hello, %s!\n", name); } // When reached the end, print a message to the terminal to inform the user. if (feof(names)) { printf("Greetings are done!\n"); } return EXIT_SUCCESS; }

Припустимо, names.txtмістить наступне:

Kamala Logan Carol

Тоді після запуску greetingsфайл greet.txtбуде містити:

Hello, Kamala! Hello, Logan! Hello, Carol!