Menulis data ke file teks c. Bekerja dengan file dalam bahasa C

File teks

Mari kita lihat bekerja dengan file teks di C menggunakan sebuah contoh. Buat file teks di drive C bernama TextFile.txt. Ketik baris berikut dalam file ini:

Tali_1 123 Tali_11, 456
Tali_2
Tali_3

Simpan berkasnya.

Dan ini adalah kode untuk program C yang membuka file kita dan membaca baris-baris darinya:

/* *Penulis: @penulis Subbotin B.P..h> #include #define LEN 50 int main(void) ( puts("Operasi file teks"); char cArray; FILE *pTextFile = fopen("C:\\TextFile.txt", "r"); if(pTextFile == NULL) ( puts("Masalah"); return EXIT_FAILURE; ) while(fgets(cArray, LEN, pTextFile) != NULL) ( printf("%s", cArray); ) fclose(pTextFile);

Untuk membuka file teks di C, gunakan fungsi fopen:

FILE *pTextFile = fopen("C:\\TextFile.txt", "r");

Argumen pertama pada fungsi fopen menunjuk ke suatu file, dan argumen kedua mengatakan bahwa file tersebut terbuka untuk dibaca darinya.

Kami membaca baris menggunakan fungsi fgets:

fgets(cArray, LEN, pTextFile);

Argumen pertama dari fungsi fgets menunjuk ke array karakter di mana string yang diterima akan disimpan, argumen kedua adalah jumlah karakter maksimum yang harus dibaca, dan argumen ketiga adalah file kita.

Setelah selesai mengerjakan file, Anda harus menutupnya:

fclose(pTextFile);

Kami mendapatkan:

Huruf Rusia juga muncul di baris.

Omong-omong, saya membuat program ini di Eclipse. Anda dapat melihat cara bekerja dengan C/C++ di Eclipse.

Jadi, kami membuka dan membaca data dari file teks.

Sekarang mari kita pelajari cara membuat file teks secara terprogram dan menulis data ke dalamnya.

/* Penulis: @author Subbotin B.P..h> #include int main(void) ( FILE *pTextFile = fopen("C:\\TextFileW.txt", "w"); char *cString = "Ini adalah string"; char cNewLine = "\n"; int nVal = 123 ; if(pTextFile == NULL) ( puts("Masalah"); return EXIT_FAILURE; ) fprintf(pTextFile, "%s%c", cString, cNewLine ;

Buat file teks untuk menulis data ke:

FILE *pTextFile = fopen("C:\\TextFileW.txt", "w");

jika file sudah ada, maka akan dibuka dan semua data di dalamnya akan dihapus.

C-string cString dan nomor nVal ditulis oleh program ke file teks. cNewLine hanyalah sebuah baris baru.

Kami menulis data ke file teks menggunakan fungsi fprintf:

fprintf(pTextFile, "%s%c", cString, cNewLine);

argumen pertama di sini adalah file kita, argumen kedua adalah string format, argumen ketiga atau lebih adalah jumlah argumen yang diperlukan untuk format ini.

Terakhir diperbarui: 31/10/2015

Kelas Aliran File mewakili kemampuan membaca dari file dan menulis ke file. Ini memungkinkan Anda untuk bekerja dengan file teks dan file biner.

Mari pertimbangkan properti dan metode terpentingnya:

    Properti panjang: mengembalikan panjang aliran dalam byte

    Properti posisi: mengembalikan posisi saat ini di aliran

    Metode baca: Membaca data dari file ke dalam array byte. Mengambil tiga parameter: int Read(byte array, int offset, int count) dan mengembalikan jumlah byte yang berhasil dibaca. Parameter berikut digunakan di sini:

    • array - array byte tempat data yang dibaca dari file akan ditempatkan

      offset mewakili offset dalam byte dalam array tempat byte baca akan ditempatkan

      count - jumlah byte maksimum yang akan dibaca. Jika jumlah byte dalam file lebih sedikit, maka semuanya akan dibaca.

    Metode Pencarian panjang (offset panjang, asal SeekOrigin): mengatur posisi dalam aliran dengan offset dengan jumlah byte yang ditentukan dalam parameter offset.

    Metode penulisan: Menulis data dari array byte ke file. Mengambil tiga parameter: Write(byte array, int offset, int count)

    • array - array byte dari mana data akan ditulis ke file

      offset - offset dalam byte dalam array tempat byte mulai ditulis ke aliran

      count - jumlah byte maksimum yang akan ditulis

FileStream mewakili akses file pada tingkat byte, jadi, misalnya, jika Anda perlu membaca atau menulis satu atau lebih baris ke dalam file teks, maka array byte harus dikonversi ke string menggunakan metode khusus. Oleh karena itu, kelas lain digunakan untuk bekerja dengan file teks.

Pada saat yang sama, ketika bekerja dengan berbagai file biner yang memiliki struktur tertentu, FileStream bisa sangat berguna untuk mengekstraksi informasi tertentu dan memprosesnya.

Mari kita lihat contoh membaca dan menulis ke file teks:

Console.WriteLine("Masukkan baris yang akan ditulis ke file:"); string teks = Konsol.ReadLine(); // menulis ke file menggunakan (FileStream fstream = new FileStream(@"C:\SomeDir\noname\note.txt", FileMode.OpenOrCreate)) ( // mengonversi string menjadi byte byte array = System.Text.Encoding. Default.GetBytes(text); // menulis array byte ke file fstream.Write(array, 0, array.Length); fstream = File.OpenRead(@"C:\SomeDir\noname\note.txt")) ( // mengubah string menjadi byte byte array = byte baru; // membaca data fstream.Read(array, 0, array. Panjang); // mendekode byte ke string string textFromFile = System.Text.Encoding.Default.GetString(array); Console.WriteLine("Teks dari file: (0)", textFromFile ) Console.ReadLine();

Mari kita lihat contoh ini. Baik membaca maupun menulis menggunakan pernyataan penggunaan. Pernyataan ini berbeda dengan direktif penggunaan, yang menyertakan ruang nama di awal berkas kode. Pernyataan penggunaan memungkinkan Anda membuat objek dalam blok kode, yang setelah selesai memanggil metode Buang objek tersebut, dan dengan demikian objek tersebut dimusnahkan. Dalam hal ini, variabel fstream berfungsi sebagai objek tersebut.

Objek fstream dibuat dengan dua cara berbeda: melalui konstruktor dan melalui salah satu metode statis kelas File.

Di sini dua parameter diteruskan ke konstruktor: jalur file dan enumerasi FileMode. Pencacahan ini menunjukkan mode akses file dan dapat mengambil nilai berikut:

    Tambahkan: jika file ada, teks ditambahkan ke akhir file. Jika file tidak ada, maka file tersebut dibuat. File dibuka untuk menulis saja.

    Buat : File baru dibuat. Jika file seperti itu sudah ada, maka akan ditimpa

    CreateNew: File baru dibuat. Jika file seperti itu sudah ada, maka aplikasi akan menimbulkan kesalahan

    Buka: Membuka file. Jika file tidak ada, pengecualian akan diberikan

    OpenOrCreate : jika file ada, dibuka, jika tidak, dibuat baru

    Truncate: Jika file ada, maka akan ditimpa. File dibuka untuk menulis saja.

Metode OpenRead statis dari kelas File membuka file untuk dibaca dan mengembalikan objek FileStream.

Konstruktor kelas FileStream juga memiliki sejumlah kelebihan yang memungkinkan Anda menyesuaikan objek yang dibuat dengan lebih tepat. Semua versi ini dapat dilihat di msdn.

Menulis dan membaca menggunakan objek pengkodean Encoding.Default dari namespace System.Text. Dalam hal ini, kami menggunakan dua metodenya: GetBytes untuk mendapatkan array byte dari sebuah string dan GetString untuk mendapatkan string dari array byte.

Hasilnya, string yang kita masukkan ditulis ke file catatan.txt. Pada dasarnya, ini adalah file biner (bukan file teks), meskipun jika kita hanya menulis satu baris ke dalamnya, kita dapat melihat file ini dalam bentuk yang dapat dibaca dengan membukanya di editor teks. Namun, jika kita menulis byte acak ke dalamnya, misalnya:

Fstream.WriteByte(13); fstream.WriteByte(103);

Maka kita mungkin mengalami kesulitan dalam memahaminya. Oleh karena itu, kelas terpisah dirancang untuk bekerja secara langsung dengan file teks - StreamReader dan StreamWriter.

Akses acak ke file

Seringkali file biner mewakili struktur tertentu. Dan, dengan mengetahui struktur ini, kita dapat mengambil informasi yang diperlukan dari file atau, sebaliknya, menulis sekumpulan byte tertentu di tempat tertentu dalam file. Misalnya, dalam file wav, data audio itu sendiri dimulai pada 44 byte, dan hingga 44 byte terdapat berbagai metadata - jumlah saluran audio, frekuensi pengambilan sampel, dll.

Dengan menggunakan metode Seek(), kita dapat mengontrol posisi kursor aliran, mulai dari mana file dibaca atau ditulis. Metode ini mengambil dua parameter: offset dan posisi dalam file. Posisi dalam file dijelaskan oleh tiga nilai:

    SeekOrigin.Begin : awal file

    SeekOrigin.End : akhir file

    SeekOrigin.Current : posisi saat ini dalam file

Kursor aliran tempat pembacaan atau penulisan dimulai digeser ke depan dengan offset relatif terhadap posisi yang ditentukan sebagai parameter kedua. Offsetnya bisa negatif, lalu kursor bergerak mundur, jika positif maka maju.

Mari kita lihat sebuah contoh:

Menggunakan System.IO; menggunakan Sistem.Teks; Program kelas ( static void Main(string args) ( string text = "hello world"; // menulis ke file menggunakan (FileStream fstream = new FileStream(@"D:\note.dat", FileMode.OpenOrCreate)) ( / / mengonversi string menjadi byte input = Encoding.Default.GetBytes(text); // menulis array byte ke file fstream.Write(input, 0, input.Length Console.WriteLine("Teks ditulis ke file" ); pindahkan penunjuk ke akhir file, lima byte ke akhir file fstream.Seek(-5, SeekOrigin.End); // dikurangi 5 karakter dari akhir aliran // membaca empat karakter dari posisi saat ini byte output = new byte( output, 0, output.Length); // mendekode byte menjadi string string textFromFile = Encoding.Default.GetString(output Console.WriteLine); , textFromFile); dalam file kata world ke kata house string replaceText = "house"; fstream.Seek(-5, SeekOrigin.End); // dikurangi 5 karakter dari akhir aliran input = Encoding.Default. GetBytes(replaceText); , 0, masukan.Panjang);

// membaca keseluruhan file // mengembalikan pointer ke awal file fstream.Seek(0, SeekOrigin.Begin);

keluaran = byte baru;

fstream.Baca(keluaran, 0, keluaran.Panjang);

// memecahkan kode byte menjadi string textFromFile = Encoding.Default.GetString(output);

Console.WriteLine("Teks dari file: (0)", textFromFile); // halo rumah ) Console.Read();

) )

Keluaran konsol:

Teks ditulis ke file Teks dari file: world Teks dari file: hello house

FileStream fstream = nol; coba ( fstream = new FileStream(@"D:\note3.dat", FileMode.OpenOrCreate); // operasi dengan aliran ) catch(Exception ex) ( ) akhirnya ( if (fstream != null) fstream.Close() ;

Jika kita tidak menggunakan konstruk penggunaan, maka kita perlu memanggil metode Close() secara eksplisit: fstream.Close()

Mekanisme I/O yang dikembangkan oleh , tidak sesuai dengan gaya pemrograman berorientasi objek yang diterima secara umum saat ini, selain itu, mekanisme ini banyak menggunakan operasi penunjuk yang dianggap berpotensi tidak aman dalam lingkungan eksekusi kode aman modern. Alternatif dalam mengembangkan aplikasi aplikasi adalah mekanisme kelas I/O standar yang disediakan oleh standar bahasa C++.

Membuka file

Kelas yang paling umum digunakan adalah ifstream untuk membaca, ofstream untuk menulis, dan fstream untuk memodifikasi file.

Semua kelas I/O berulir secara tidak langsung diturunkan dari nenek moyang yang sama ios, dan sepenuhnya mewarisi fungsinya. Dengan demikian, mode pembukaan file ditentukan oleh anggota data dari tipe open_mode yang disebutkan, yang didefinisikan sebagai berikut:

Enum open_mode ( aplikasi, biner, masuk, keluar, trunc, makan );

Di bawah ini adalah kemungkinan nilai bendera dan tujuannya.

Misalnya, untuk membuka file bernama test.txt untuk membaca data dalam bentuk biner, Anda dapat menulis:

berkas ifstream; file.open("test.txt", ios::in | ios::biner);

Operator logika OR (|) memungkinkan Anda membuat mode dengan kombinasi tanda apa pun. Nah, agar pada saat membuka suatu file secara entry tidak sengaja menimpa file yang sudah ada dengan nama yang sama, maka harus menggunakan form sebagai berikut:

Berkas ofstream; file.open("test.txt", ios::out | ios::app);

Diasumsikan bahwa file header yang sesuai disertakan dalam proyek:

#termasuk

Untuk memeriksa apakah file berhasil dibuka, Anda dapat menggunakan konstruk

If (!file) ( //Menangani kesalahan pembukaan file)

Operator inklusi dan ekstraksi

Ditimpa di kelas penanganan file operator inklusi (<<) записывает данные в файловый поток. Как только вы открыли файл для записи, можно записывать в него текстовую строку целиком:

Mengajukan<< "Это строка текста";

Anda juga dapat menulis string teks di beberapa bagian:

Mengajukan<< "Это " << "строка " << "текста";

Pernyataan endl mengakhiri input baris dengan kereta kembali:

Mengajukan<< "Это строка текста" << endl;

Dengan menggunakan operator include, mudah untuk menulis nilai variabel atau elemen array ke file:

File ofstream("Temp.txt"); char buff = "Array teks berisi variabel"; int vx = 100; pi mengambang = 3,14159; mengajukan<< buff << endl << vx << endl << pi << endl;

Sebagai hasil dari eksekusi kode, tiga baris file teks Temp.txt terbentuk:

Array teks berisi variabel 100 3.14159

Perhatikan bahwa nilai numerik ditulis ke file sebagai string teks, bukan nilai biner.

Operator pengambilan(>>) menghasilkan efek sebaliknya. Tampaknya untuk mengekstrak karakter dari file Temp.txt yang ditulis sebelumnya, Anda akan menulis kode seperti berikut:

File ifstream("Temp.txt"); penggemar arang; intvx; mengapung pi; file >> penggemar >> vx >> pi;

Namun, operator ekstraksi akan berhenti pada pembatas pertama yang ditemuinya (spasi, tab, atau baris baru). Jadi, saat mengurai kalimat “Array teks berisi variabel”, hanya kata “Teks” yang akan ditulis ke array buff, spasi diabaikan, dan kata “array” akan menjadi nilai seluruh variabel vx, dan kode eksekusi akan “bermasalah” dengan pelanggaran struktur data yang tak terhindarkan. Selanjutnya, saat membahas kelas ifstream, kami akan menunjukkan cara mengatur pembacaan file dari contoh sebelumnya dengan benar.

kelas ifstream: membaca file

Seperti namanya, kelas ifstream dirancang untuk memasukkan aliran file. Metode utama kelas tercantum di bawah ini. Kebanyakan dari mereka diwarisi dari kelas istream dan kelebihan beban untuk memperluas fungsionalitas induk. Misalnya, fungsi get, bergantung pada parameter panggilan, tidak hanya dapat membaca satu karakter, tetapi juga satu blok karakter.

Sekarang jelas bagaimana contoh sebelumnya perlu dimodifikasi agar penggunaan operator ekstraksi data memberikan hasil yang diharapkan:

File ifstream("Temp.txt"); penggemar arang; intvx; mengapung pi; file.getline(penggemar, ukuran(penggemar)); berkas >> vx >> pi:

Metode getline akan membaca baris pertama file sampai akhir, dan operator >> akan memberikan nilai pada variabel.

Contoh berikut menunjukkan penambahan data ke file teks dan kemudian membaca keseluruhan file. Perulangan while(1) digunakan sebagai pengganti while(!file2.eof()) untuk alasan yang dibahas di .

#termasuk #termasuk menggunakan namespace std; int main() ( file ofstream; file.open("test.txt",ios::out|ios::app); if (!file) ( cout<< "File error - can"t open to write data!"; cin.sync(); cin.get(); return 1; } for (int i=0; i<10; i++) file << i << endl; file.close(); ifstream file2; file2.open("test.txt", ios::in); if (!file2) { cout << "File error - can"t open to read data!"; cin.sync(); cin.get(); return 2; } int a,k=0; while (1) { file2 >> sebuah;<< a << " "; k++; } cout << endl << "K=" << k << endl; file2.close(); cin.sync(); cin.get(); return 0; }

if (file2.eof()) rusak;

#termasuk #termasuk cout<< str << endl; // вывод прочитанной строки на экран cin.sync(); cin.get(); return 0; }

Kode ini pada OS Windows juga bergantung pada keberadaan karakter baris baru di baris terakhir file; akan lebih dapat diandalkan untuk melakukan ini:

Sementara (1) ( if (file.eof()) break; file.getline(str, sizeof(str)); cout<< str << endl; }

Panggilan eksplisit ke metode buka dan tutup tidak diperlukan. Memang benar, memanggil konstruktor dengan argumen memungkinkan Anda untuk segera membuka file, pada saat objek file berulir dibuat:

File ifstream("test.txt");

Daripada metode close, Anda dapat menggunakan operator delete, yang secara otomatis akan memanggil destruktor objek file dan menutup file. Kode perulangan while memastikan pemeriksaan akhir file yang benar.

kelas ofstream: menulis file

Kelas ofstream dirancang untuk mengeluarkan data dari aliran file. Berikut ini daftar metode utama kelas ini.

Operator penyertaan yang dijelaskan sebelumnya berguna untuk mengatur penulisan ke file teks:

File ofstream("temp.txt"); jika (!file) kembali; untuk (int saya=1; saya<=3; i++) file << "Строка " << i << endl; file.close();

File biner

Pada prinsipnya, data biner diperlakukan seperti data teks. Perbedaannya adalah jika data biner ditulis dalam struktur logika tertentu, maka data tersebut harus dibaca dari file ke dalam variabel dengan tipe struktur yang sama.

Parameter pertama metode tulis dan baca (alamat blok tulis/baca) harus bertipe penunjuk karakter char * , sehingga perlu dilakukan konversi eksplisit tipe alamat struktur void *. Parameter kedua menetapkan bahwa blok biner file memiliki ukuran byte yang konstan terlepas dari panjang rekaman sebenarnya. Aplikasi berikut memberikan contoh pembuatan dan menampilkan data dalam buku catatan sederhana. Entri file kemudian dibaca secara berurutan dan ditampilkan di konsol.

#termasuk #termasuk #termasuk menggunakan namespace std; struct Catatan ( // struktur data buku catatan char Nama; // nama lengkap char Telepon; // telepon int Usia; // usia ); int main() ( setlocale(LC_ALL, "Rusia"); Catatan Catatan1= ("Ioann Vasilyevich yang Mengerikan", "tidak terpasang", 60 ); Catatan Catatan2= ("Godunov Boris Fedorovich", "095-111-2233" , 30 ); Catatan Catatan3= ("Romanov Petr Mikhailovich", "812-333-2211", 20 ); ofstream ofile("Notebook.dat", ios::biner.write((char*)&Catatan1, sizeof (Catatan)); // blok pertama ofile.write((char*)&Note2, sizeof(Catatan)); // blok kedua ofile.write((char*)&Note3, sizeof(Catatan)); .close(); // menutup file yang direkam ifstream ifile("Notebook.dat", ios::binary); // variabel terstruktur char str // buffer string statis // Membaca dan menampilkan baris dalam satu loop hingga beberapa waktu (!ifile.read((char*)&Note, sizeof(Notes)).eof()) ( sprintf(str, "%s\tPhone: %s\tAge: %d" , Note.Name, Note.Phone, Catatan.Usia);<< str << endl; } ifile.close(); // закрыть прочитанный файл cin.sync(); cin.get(); return 0; }

Sebagai hasil dari eksekusi kode ini, file biner Notebook.dat dibentuk dari tiga blok masing-masing 80 byte (dengan asumsi karakternya adalah byte tunggal). Secara alami, Anda dapat menggunakan metode threading lain dan melakukan operasi apa pun pada bidang struktur data tertentu.

kelas fstream: akses file acak

Anggaplah kita mempunyai 100 entri di buku catatan kita, dan kita ingin menghitung yang ke-50. Tentu saja, Anda dapat mengatur perulangan dan membaca semua catatan dari yang pertama hingga yang diberikan. Jelas solusi yang lebih bertarget adalah dengan mengatur penunjuk posisi file pos langsung ke entri 50 dan membacanya:

Ifstream ifile("Notebook.dat", ios::biner); int pos = 49 * sizeof(Catatan); ifile.seekg(pos); // mencari entri Catatan Catatan ke-50;

//Catatan – struktur “catatan” yang dijelaskan di atas ifile.read((char*)&Note, sizeof(Notes));

Operasi pencarian seperti itu efektif jika file terdiri dari rekaman dengan ukuran yang diketahui dan konstan. Untuk mengganti konten rekaman arbitrer, Anda perlu membuka aliran keluaran dalam mode modifikasi:

Ofstream ofile ("Notebook.dat", ios::biner | ios::ate); int pos = 49 * sizeof(Catatan); pencarian file(pos); // cari entri ke-50 Catatan Note50 = ("Yeltsin Boris Nikolaevich", "095-222-3322", 64); ofile.write((char*)&Catatan, sizeof(Catatan)); // penggantian

Terakhir, dimungkinkan untuk membuka file secara bersamaan untuk membaca/menulis, menggunakan metode yang diwarisi oleh kelas streaming fstream dari pendahulunya. Karena kelas fstream berasal dari istream dan ostream (masing-masing induk dari ifstream dan ofstream), semua metode yang disebutkan sebelumnya tersedia dalam aplikasi.

Contoh berikut memperlihatkan penataan ulang entri pertama dan ketiga dalam file Notebook.dat.

#termasuk #termasuk #termasuk menggunakan namespace std; struct Catatan (char Nama; char Telepon; int Usia; ); int main() ( setlocale(LC_ALL, "Rusia"); Catatan Note1, Note3; // Buka file untuk membaca/menulis secara bersamaan fstream file("Notebook.dat", ios::binary | ios::in | ios: : out); file.seekg(2 * sizeof(Notes)); // mencari dan membaca file Note3.read((char*)&Note3, sizeof(Notes)); // mencari dan membaca file Note1.read((char *)&Catatan1, sizeof(Catatan)); file.seekg(0);<== Note3 file.write((char*)&Note3, sizeof(Notes)); file.seekg(2 * sizeof(Notes)); // Note3 <== Note1 file.write((char*)&Note1, sizeof(Notes)); char str; // Считывать и отображать записи в цикле, пока не eof file.seekg(0); // вернуться к началу файла while (!file.read((char*)&Note1, sizeof(Notes)).eof()) { sprintf(str, "%s\tТел: %s\tВозраст: %d", Note1.Name, Note1.Phone, Note1.Age); cout << str << endl; } file.close(); cin.sync(); cin.get(); return 0; }

Di konstruktor objek file, Anda harus menentukan flag ios::in dan ios::out, yang memungkinkan operasi baca dan tulis secara bersamaan. Sebagai hasil dari eksekusi kode ini, entri pertama dan ketiga dalam file biner Notebook.dat akan ditukar.

Ada contoh tambahan mengenai topik ini.

Untuk kemudahan akses, informasi dalam perangkat penyimpanan disimpan dalam bentuk file.

File adalah area bernama memori eksternal yang dialokasikan untuk menyimpan array data. Data yang terdapat dalam file memiliki sifat yang sangat beragam: program dalam bahasa algoritmik atau mesin; data awal pengoperasian program atau hasil pelaksanaan program; teks bebas; gambar grafis, dll.

Direktori (folder, direktori) - kumpulan byte bernama pada media penyimpanan yang berisi nama subdirektori dan file, yang digunakan dalam sistem file untuk menyederhanakan pengorganisasian file.

Sistem file disebut bagian fungsional dari sistem operasi yang melakukan operasi pada file. Contoh sistem file adalah FAT (FAT - File Allocation Table), NTFS, UDF (digunakan pada CD).

Ada tiga versi utama FAT: FAT12, FAT16 dan FAT32. Mereka berbeda dalam kedalaman bit catatan dalam struktur disk, mis. jumlah bit yang dialokasikan untuk menyimpan nomor cluster. FAT12 digunakan terutama untuk floppy disk (hingga 4 KB), FAT16 - untuk disk berkapasitas kecil, FAT32 - untuk FLASH drive berkapasitas tinggi (hingga 32 GB).

Mari kita lihat struktur sistem file menggunakan FAT32 sebagai contoh.

Struktur file FAT32

Perangkat memori eksternal dalam sistem FAT32 memiliki pengalamatan blok, bukan pengalamatan byte. Informasi ditulis ke perangkat memori eksternal dalam blok atau sektor.

Sektor adalah unit penyimpanan informasi minimum yang dapat dialamatkan pada perangkat penyimpanan eksternal. Biasanya, ukuran sektor ditetapkan pada 512 byte. Untuk meningkatkan ruang alamat perangkat memori eksternal, sektor-sektor digabungkan menjadi kelompok yang disebut cluster.

Cluster merupakan gabungan dari beberapa sektor, yang dapat dianggap sebagai satu kesatuan yang berdiri sendiri dengan sifat-sifat tertentu. Properti utama sebuah cluster adalah ukurannya, diukur dalam jumlah sektor atau jumlah byte.

Sistem file FAT32 memiliki struktur berikut.

Cluster yang digunakan untuk menulis file diberi nomor mulai dari 2. Biasanya, cluster No. 2 digunakan oleh direktori root, dan mulai dari cluster No. 3 array data disimpan. Sektor yang digunakan untuk menyimpan informasi di atas direktori root tidak dikelompokkan.
Ukuran file minimum yang diperlukan pada disk sesuai dengan 1 cluster.

Sektor boot dimulai dengan informasi berikut:

  • EB 58 90 – lompatan dan tanda tangan tanpa syarat;
  • 4D 53 44 4F 53 35 2E 30 MSDOS5.0;
  • 00 02 – jumlah byte di sektor ini (biasanya 512);
  • 1 byte – jumlah sektor dalam cluster;
  • 2 byte – jumlah sektor cadangan.

Selain itu, sektor boot berisi informasi penting berikut:

  • 0x10 (1 byte) – jumlah tabel FAT (biasanya 2);
  • 0x20 (4 byte) – jumlah sektor pada disk;
  • 0x2С (4 byte) – nomor cluster direktori root;
  • 0x47 (11 byte) – label volume;
  • 0x1FE (2 byte) – tanda tangan sektor boot (55 AA).

Sektor informasi sistem file berisi:

  • 0x00 (4 byte) – tanda tangan (52 52 61 41);
  • 0x1E4 (4 byte) – tanda tangan (72 72 41 61);
  • 0x1E8 (4 byte) – jumlah cluster gratis, -1 jika tidak diketahui;
  • 0x1EC (4 byte) – nomor cluster terakhir yang direkam;
  • 0x1FE (2 byte) – tanda tangan (55 AA).

Tabel FAT berisi informasi tentang status setiap cluster pada disk. 2 byte terbawah dari tabel FAT menyimpan F8 FF FF 0F FF FF FF FF (yang sesuai dengan keadaan cluster 0 dan 1, yang secara fisik tidak ada). Selanjutnya, status setiap cluster berisi nomor cluster tempat file saat ini berlanjut atau informasi berikut:

  • 00 00 00 00 – cluster gratis;
  • FF FF FF 0F – akhir file saat ini.
  • 8 byte – nama file;
  • 3 byte – ekstensi file;

Direktori root berisi sekumpulan catatan informasi 32-bit tentang setiap file, yang berisi informasi berikut:

Saat bekerja dengan nama file yang panjang (termasuk nama Rusia), nama file dikodekan menggunakan sistem pengkodean UTF-16. Dalam hal ini, 2 byte dialokasikan untuk pengkodean setiap karakter. Dalam hal ini, nama file ditulis dalam struktur berikut:

  • 1 byte urutan;
  • 10 byte berisi 5 karakter terbawah dari nama file;
  • atribut 1 byte;
  • 1 byte dicadangkan;
  • 1 byte – checksum nama DOS;
  • 12 byte berisi 3 karakter terbawah dari nama file;
  • 2 byte – nomor cluster pertama;
  • karakter yang tersisa dari nama panjang.

Bekerja dengan file dalam bahasa C

Bagi programmer, file yang terbuka direpresentasikan sebagai urutan data yang dibaca atau ditulis. Ketika sebuah file dibuka, itu dikaitkan dengan aliran I/O. Informasi keluaran ditulis ke aliran, informasi masukan dibaca dari aliran.

Ketika aliran dibuka untuk I/O, itu dikaitkan dengan struktur FILE standar, yang didefinisikan di stdio.h. Struktur FILE berisi informasi yang diperlukan tentang file tersebut.

Membuka file dilakukan menggunakan fungsi fopen(), yang mengembalikan pointer ke struktur FILE yang dapat digunakan untuk operasi selanjutnya pada file.

FILE *fopen(nama, ketik);


nama – nama file yang akan dibuka (termasuk jalur),
type adalah penunjuk ke serangkaian karakter yang menentukan cara file diakses:
  • "r" - buka file untuk dibaca (file harus ada);
  • "w" - buka file kosong untuk menulis; jika file tersebut ada, isinya hilang;
  • "a" - buka file untuk ditulis sampai akhir (untuk ditambahkan); file dibuat jika tidak ada;
  • "r+" - membuka file untuk membaca dan menulis (file harus ada);
  • "w+" - membuka file kosong untuk membaca dan menulis; jika file tersebut ada, isinya hilang;
  • "a+" - membuka file untuk dibaca dan ditambahkan; jika file tidak ada, maka file tersebut dibuat.

Nilai yang dikembalikan adalah penunjuk ke aliran terbuka. Jika terjadi kesalahan, NULL dikembalikan.

Fungsi fclose() menutup aliran atau aliran yang terkait dengan file yang dibuka menggunakan fungsi fopen(). Aliran yang akan ditutup ditentukan oleh argumen fungsi fclose().

Nilai kembalian: nilai 0 jika aliran berhasil ditutup; EOF konstan jika terjadi kesalahan.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

#termasuk
ke dalam utama() (
FILE *fp;
nama char = "my.txt" ;
jika ((fp = fopen(nama, "r" )) == NULL )
{
printf( "Gagal membuka file");
getchar();
kembali 0;
}
// berhasil membuka file
... // tindakan yang diperlukan pada data
fclose(fp);
getchar();
kembali 0;
}

Membaca karakter dari file:

char fgetc(aliran);


Argumen fungsi adalah penunjuk ke aliran bertipe FILE. Fungsi mengembalikan kode karakter yang dibaca. Jika akhir file tercapai atau terjadi kesalahan, EOF konstan dikembalikan.

Menulis simbol ke file:

fputc(char, aliran);

Argumen fungsi adalah karakter dan penunjuk ke aliran bertipe FILE. Fungsi mengembalikan kode karakter yang dibaca.

Fungsi fscanf() dan fprintf() mirip dengan fungsi scanf() dan printf(), namun berfungsi dengan file data, dan memiliki penunjuk ke file tersebut sebagai argumen pertamanya.

fscanf(stream, "InputFormat", argumen);

– perbandingan untuk mengidentifikasi kesetaraan atau ketidaksetaraan.

Tujuan praktis dari enumerasi adalah untuk mendefinisikan sekumpulan konstanta simbolik yang berbeda dari tipe integer.

Contoh penggunaan variabel enumerasi:

mo=1, tu, we, th, fr, sa, su ) hari;

putting(“Masukkan hari dalam seminggu (dari 1 sampai 7) :”); scanf(“%d”, &t_hari);

w_hari = su; mulai = bulan;

akhir = w_hari -t_hari;

printf(“\nSenin adalah %d hari dalam seminggu, \sekarang adalah %d hari.\n\

Sampai akhir minggu %d hari (hari). ”, mulai, hari_t, akhir);

Hasil program: Masukkan hari dalam seminggu (dari 1 hingga 7): 2

Senin adalah hari pertama dalam seminggu, sekarang adalah hari ke-2. Ada 5 hari (hari) sampai akhir minggu.

18. File dalam bahasa C

File adalah sekumpulan data yang terletak di media eksternal dan dianggap sebagai satu kesatuan selama pemrosesan. File berisi data yang dimaksudkan untuk penyimpanan jangka panjang.

Ada dua jenis file: teks dan biner. File teks adalah rangkaian karakter ASCII dan dapat dilihat dan diedit menggunakan editor teks apa pun.

File biner (biner) adalah urutan data, yang strukturnya ditentukan oleh perangkat lunak.

Bahasa C memiliki banyak fungsi untuk bekerja dengan file, yang sebagian besar ditemukan di perpustakaan stdio.h dan io.h.

18.1. Membuka file

Setiap file diberi nama logis internal, yang nantinya digunakan saat mengaksesnya. Nama logis (pengidentifikasi file) adalah

penunjuk ke file, mis. ke area memori yang berisi semua informasi yang diperlukan tentang file tersebut. Format deklarasi penunjuk file adalah sebagai berikut:

FILE * penunjuk ke file;

FILE – pengidentifikasi tipe struktur yang dijelaskan di perpustakaan standar

stdio.h dan berisi informasi berikut:

ketik struct(

– jumlah byte yang belum dibaca yang tersisa di buffer;

ukuran buffer biasa adalah 512 byte; segera setelah level=0,

blok data berikutnya dibaca ke dalam buffer dari file;

– tanda status file – baca, tulis, tambahkan;

– deskriptor file, mis. nomor yang mendefinisikan no-

penangguhan karakter yang tidak ditandatangani;

– karakter yang tidak ditransmisikan, mis. karakter ungetc;

– ukuran buffer perantara internal;

buffer karakter yang tidak ditandatangani;

– nilai penunjuk untuk akses di dalam buffer, mis.

menentukan awal buffer, awal baris, atau nilai saat ini

Nilai pointer di dalam buffer tergantung pada modenya

tapi buffering;

karakter yang tidak ditandatangani *curp;

– nilai penunjuk saat ini untuk akses di dalam

fera, yaitu menentukan posisi saat ini di buffer pertukaran

melanjutkan program;

istemp yang tidak ditandatangani;

– bendera file sementara;

– tandai saat bekerja dengan file;

) FILE;

Sebelum Anda mulai bekerja dengan file tersebut, mis. Untuk dapat membaca atau menulis informasi ke suatu file, file tersebut harus dibuka untuk diakses. Untuk tujuan ini fungsi biasanya digunakan

FILE* fopen(char* nama file, mode char*);

dibutuhkan representasi eksternal - nama fisik file pada media (floppy disk, hard drive) dan mencocokkannya dengan nama logis.

Nama fisik, mis. nama file dan jalur ke sana ditentukan oleh parameter pertama

– sebuah baris, misalnya, “a:Mas_dat.dat” – sebuah file bernama Mas_dat.dat yang terletak di floppy disk, “d:\\work\\Sved.txt” – sebuah file bernama Sved.txt yang terletak di hard berkendara di direktori kerja.

Perhatian! Garis miring terbalik (\), sebagai karakter khusus, ditulis dua kali berturut-turut.

Setelah berhasil dibuka, fungsi fopen mengembalikan penunjuk ke file (selanjutnya disebut penunjuk file). Jika terjadi kesalahan, NULL dikembalikan. Situasi ini biasanya terjadi ketika jalur ke file yang akan dibuka salah ditentukan. Misalnya, jika di kelas tampilan universitas kami Anda menentukan jalur yang dilarang untuk ditulis (biasanya d:\kerja\ diperbolehkan).

Parameter kedua adalah baris yang menentukan mode akses file:

w – file dibuka untuk ditulis; jika tidak ada file dengan nama yang diberikan, maka akan dibuat; jika file seperti itu ada, maka informasi sebelumnya dimusnahkan sebelum dibuka;

r – file dibuka untuk hanya dibaca; jika tidak ada file seperti itu, terjadi kesalahan;

a – file dibuka untuk menambahkan informasi baru di bagian akhir;

r+ – file dibuka untuk mengedit data – menulis dan membaca informasi dimungkinkan;

w+ – sama seperti untuk r+;

a+ – sama seperti a, hanya penulisan yang dapat dilakukan di mana saja dalam file; pembacaan file juga tersedia;

t – file dibuka dalam mode teks; b – file dibuka dalam mode biner.

Mode teks berbeda dari mode biner karena ketika file dibuka sebagai teks, pasangan karakter “line feed”, “carriage return” diganti dengan satu karakter: “line feed” untuk semua fungsi penulisan data ke file , dan untuk semua fungsi keluaran, karakter “line feed” " kini digantikan oleh dua karakter: "line feed", "carriage return".

Secara default, file dibuka dalam mode teks. Contoh: FILE *f; – pointer ke file f dideklarasikan;

f = fopen("d:\\kerja\\Dat_sp.cpp", "w"); – file dengan nama logis f, yang memiliki nama fisik Dat_sp.cpp, terletak di drive d, di direktori kerja, dibuka untuk penulisan; atau lebih singkatnya

FILE *f = fopen("d:\\work\\Dat_sp.cpp", "w");

18.2. Menutup file

Setelah bekerja dengan file, akses ke file tersebut harus ditutup. Ini dilakukan oleh fungsi int fclose (penunjuk file). Misalnya dari contoh sebelumnya, file ditutup seperti ini: fclose (f);

Untuk menutup banyak file, sebuah fungsi diperkenalkan, dideklarasikan sebagai berikut: void fcloseall (void);

Jika Anda perlu mengubah mode akses suatu file, Anda harus menutup file tersebut terlebih dahulu lalu membukanya kembali, tetapi dengan hak akses yang berbeda. Untuk melakukan ini, gunakan fungsi standar:

FILE* freopen (char*nama_file, char *mode, FILE *file_pointer);

Fungsi ini pertama-tama menutup file yang dideklarasikan file_pointer(seperti fungsi fopen), lalu membuka file dengan nama file dan izin "mode".

Bahasa C memiliki kemampuan untuk bekerja dengan file-file sementara yang diperlukan hanya saat program sedang berjalan. Dalam hal ini fungsi tersebut digunakan

FILE*tmpfile (batal);

yang membuat file sementara pada disk dengan hak akses “w+b”; setelah program selesai atau setelah file sementara ditutup, maka secara otomatis dihapus.

18.3. Menulis – membaca informasi

Semua tindakan untuk membaca dan menulis data ke file dapat dibagi menjadi tiga kelompok: operasi input-output karakter demi karakter; operasi I/O baris demi baris; memblokir operasi I/O.

Mari kita lihat fungsi utama yang digunakan dalam masing-masing dari ketiga kelompok operasi ini.

I/O karakter demi karakter

Dalam fungsi I/O karakter per karakter, satu karakter diterima dari file atau satu karakter dikirim ke file:

Baris I/O

Fungsi jalur I/O ditransfer dari file atau ke

Blokir I/O

Fungsi blok I/O beroperasi pada seluruh blok

informasi:

int ketakutan (void*p, intsize,

– membaca masing-masing n blok berukuran byte dari file

ke dalam n, FILE *f)

la f ke area memori dengan penunjuk p (wajib

int fwrite (batal*p, ukuran int,

mengalokasikan memori terlebih dahulu agar blok dapat dibaca);

– menulis masing-masing n blok berukuran byte dari

ke dalam n, FILE *f)

area memori dengan penunjuk p ke file f.

I/O yang diformat dihasilkan oleh fungsi.

  • Sergei Savenkov

    semacam ulasan "pendek"... seolah-olah mereka sedang terburu-buru di suatu tempat