• Dosyadan girdi nasıl yapılır c. Metin dosyalarıyla çalışma

    Çoğu bilgisayar programı dosyalarla çalışır ve bu nedenle dosyaları oluşturmaya, silmeye, yazmaya, okumaya, açmaya ihtiyaç vardır. dosya nedir? Bir dosya, bazı depolama aygıtlarında depolanabilen, adlandırılmış bir bayt koleksiyonudur. Artık bir dosyanın, .txt dosyası gibi kendi benzersiz adına sahip bir bayt dizisi olduğu açıktır. Aynı ada sahip dosyalar aynı dizinde olamaz. Dosya adı yalnızca adı olarak değil, aynı zamanda bir uzantı olarak da anlaşılır, örneğin: file.txt ve file.dat aynı ada sahip olmalarına rağmen farklı dosyalar. Dosyaların tam adı diye bir şey vardır - bu, dosya adıyla dosya dizininin tam adresidir, örneğin: D:\docs\file.txt . Bu temel kavramları anlamak önemlidir, aksi takdirde dosyalarla çalışmak zor olacaktır.

    Dosyalarla çalışmak için bir başlık dosyası eklemeniz gerekir . İÇİNDE tanımlanmış birkaç sınıf ve başlık dosyaları dahil dosya girişi ve dosya çıktısı.

    Dosya G/Ç, standart G/Ç'ye benzer, tek fark, G/Ç'nin ekrana değil bir dosyaya yapılmasıdır. Standart cihazlara giriş/çıkış cin ve cout nesneleri kullanılarak gerçekleştiriliyorsa, dosya G/Ç'yi düzenlemek için cin ve cout operatörlerine benzer şekilde kullanılabilen kendi nesnelerinizi oluşturmanız yeterlidir.

    Örneğin, bir metin dosyası oluşturmanız ve bu dosyaya Working with files in C++ satırını yazmanız gerekir. Bunu yapmak için aşağıdaki adımları uygulamanız gerekir:

    1. bir akış sınıfı nesnesi yarat ;
    2. bir sınıf nesnesini yazılacak dosyayla ilişkilendirin;
    3. bir dosyaya bir satır yazmak;
    4. dosyayı kapatın.

    Neden ifstream sınıfından değil de ofstream sınıfından bir nesne oluşturmak gerekli? Çünkü bir dosyaya yazmanız ve bir dosyadan veri okumanız gerekiyorsa ifstream sınıfından bir nesne oluşturulur.

    // akış dosyasına yazmak için bir nesne yarat /*nesne adı*/; // akış sınıfının nesnesi

    Nesneyi - fout olarak adlandıralım, işte olanlar:

    Yayın dışı maç;

    Neden bir nesneye ihtiyacımız var? Nesne, dosyaya yazabilmek için gereklidir. Nesne zaten yaratılmıştır, ancak dizenin yazılacağı dosyayla ilişkili değildir.

    fout.open("cppstudio.txt"); // nesneyi dosyayla ilişkilendir

    Nokta işlemi ile parantez içinde dosya ismini belirttiğimiz open() class metoduna erişim elde ederiz. Belirtilen dosya, program ile mevcut dizinde oluşturulacaktır. Aynı ada sahip bir dosya varsa, mevcut dosya yenisiyle değiştirilecektir. Böylece dosya açık, geriye istenen satırı içine yazmak kalıyor. Bu şekilde yapılır:

    kavga<< "Работа с файлами в С++"; // запись строки в файл

    Fout nesnesiyle bağlantılı olarak akışa aktarma işlemi kullanılarak, C++'daki Dosya İşleme dizesi bir dosyaya yazılır. Artık dosyanın içeriğini değiştirmek gerekmediği için kapatılmalı, yani nesne dosyadan ayrılmalıdır.

    fout.close(); // dosyayı kapat

    Sonuç olarak, Working with files in C++ satırına sahip bir dosya oluşturuldu.

    1. ve 2. adımlar birleştirilebilir, yani tek satırda bir nesne oluşturun ve onu bir dosyayla ilişkilendirin. Bu şekilde yapılır:

    Akış dışı fout("cppstudio.txt"); // ofstream sınıfından bir nesne oluşturun ve onu cppstudio.txt dosyasıyla ilişkilendirin

    Tüm kodları birleştirelim ve aşağıdaki programı elde edelim.

    // file.cpp: konsol uygulaması için giriş noktasını tanımlar. #include "stdafx.h" #include ad alanı std kullanarak; int main(int argc, char* argv) ( ofstream fout("cppstudio.txt"); // yazmak için ofstream sınıfından bir nesne oluşturun ve onu cppstudio.txt fout dosyasıyla ilişkilendirin<< "Работа с файлами в С++"; // запись строки в файл fout.close(); // закрываем файл system("pause"); return 0; }

    Programın doğru çalışıp çalışmadığını kontrol etmeye devam ediyor ve bunun için dosyayı açıyoruz. cppstudio.txt ve içeriğine bakın, şöyle olmalı - C++'da dosyalarla çalışma.

    1. ifstream sınıfından bir nesne oluşturun ve onu okunacak dosyayla ilişkilendirin;
    2. dosyayı oku;
    3. dosyayı kapatın.
    // file_read.cpp: konsol uygulaması için giriş noktasını tanımlar. #include "stdafx.h" #include #katmak ad alanı std kullanarak; int main(int argc, char* argv) ( setlocale(LC_ALL, "rus"); // Kiril alfabesinin doğru gösterimi char buff; // ifstream fin("cppstudio.txt) dosyasından okunan metnin ara depolama tamponu "); // fin okumak için dosya açıldı >><< buff << endl; // напечатали это слово fin.getline(buff, 50); // считали строку из файла fin.close(); // закрываем файл cout << buff << endl; // напечатали эту строку system("pause"); return 0; }

    Program bir dosyadan okumanın iki yolunu gösterir, birincisi akışa aktarım işlemini kullanmak, ikincisi ise işlevi kullanmaktır. hat almak() . Birinci durumda sadece ilk kelime okunur ve ikinci durumda 50 karakterlik bir dizi okunur. Ancak dosyada 50'den az karakter kaldığı için karakterler son karakter dahil olmak üzere okunur. İkinci kez okumanın (satır 17) ilk kelime okunduğu için baştan değil, ilk kelimeden sonra devam etti.satır 14. Programın sonucu Şekil 1'de gösterilmiştir.

    C++'da Dosyalarla Çalışmak Devam etmek için herhangi bir tuşa basın. . .

    Şekil 1 - C++'da dosyalarla çalışma

    Program düzgün çalıştı, ancak her şey kodla uyumlu olsa bile bu her zaman böyle değildir. Örneğin var olmayan bir dosyanın adı programa geçmiş ya da adında hata yapılmış. Sonra ne? Bu durumda, hiçbir şey olmayacak. Dosya bulunmayacak, bu da onu okumanın mümkün olmadığı anlamına gelir. Bu nedenle, derleyici, dosyanın değiştirildiği satırları yok sayacaktır. Sonuç olarak, programdan doğru bir şekilde çıkılacak, ancak ekranda hiçbir şey gösterilmeyecektir. Görünüşe göre bu, böyle bir duruma tamamen normal bir tepki. Ancak basit bir kullanıcı, sorunun ne olduğunu ve neden dosyadan bir satırın ekranda görünmediğini anlamayacaktır. Bu nedenle, her şeyi netleştirmek için C++, tamsayı değerleri döndüren is_open() gibi bir işlev sağlar: 1 - dosya başarıyla açıldıysa, 0 - dosya açılmadıysa. Dosyanın açılması ile programı sonlandıralım öyle ki dosya açılmazsa buna karşılık gelen bir mesaj görüntülenir.

    // file_read.cpp: konsol uygulaması için giriş noktasını tanımlar. #include "stdafx.h" #include #katmak ad alanı std kullanarak; int main(int argc, char* argv) ( setlocale(LC_ALL, "rus"); // Kiril char buff'ının doğru gösterimi; // ifstream fin("cppstudio.doc"); // dosyasından okunan metnin ara depolama tamponu); / / ( YANLIŞ DOSYA ADI GİRİLDİ) if (!fin.is_open()) // eğer dosya açık değilse cout<< "Файл не может быть открыт!\n"; // сообщить об этом else { fin >> buff; // cout dosyasındaki ilk kelimeyi oku<< buff << endl; // напечатали это слово fin.getline(buff, 50); // считали строку из файла fin.close(); // закрываем файл cout << buff << endl; // напечатали эту строку } system("pause"); return 0; }

    Programın sonucu Şekil 2'de gösterilmiştir.

    Dosya açılamıyor! Devam etmek için herhangi bir tuşa basın. . .

    Şekil 2 - C++'da dosyalarla çalışma

    Şekil 2'den de görebileceğiniz gibi, program dosyanın açılamadığını bildirdi. Bu nedenle, program dosyalarla çalışıyorsa, dosyanın var olduğundan emin olsanız bile is_open() adlı bu işlevi kullanmanız önerilir.

    Dosya açma modları

    Dosya açma modları, dosyaların nasıl kullanılacağını belirler. Modu ayarlamak için ios_base sınıfı, dosya açma modunu belirleyen sabitler sağlar (bkz. Tablo 1).

    Dosya açma modları, bir nesne oluşturulurken veya open() işlevi çağrılırken doğrudan ayarlanabilir .

    Akış dışı fout("cppstudio.txt", ios_base::app); // dosyanın sonuna bilgi eklemek için dosyayı aç fout.open("cppstudio.txt", ios_base::app); // dosyanın sonuna bilgi eklemek için dosyayı aç

    Dosya açma modları, bit düzeyinde bir boole işlemi kullanılarak birleştirilebilir veya| , örneğin: ios_base::out | ios_base::trunc - bir dosyayı temizledikten sonra yazmak için açın.

    ofstream sınıfının nesneleri, dosyalarla ilişkilendirildiklerinde, varsayılan olarak dosya açma kiplerini içerir ios_base::out | ios_base::trunc . Yani, dosya yoksa oluşturulacaktır. Dosya varsa, içeriği silinecek ve dosyanın kendisi kayda hazır olacaktır. ifstream sınıfının nesneleri, bir dosyayla ilişkilendirildiklerinde, varsayılan olarak ios_base::in dosya açma kipine sahiptir - dosya yalnızca okumaya açıktır. Dosya açma modu aynı zamanda bayrak olarak da adlandırılır, okunabilirlik için bu terimi gelecekte kullanacağız. Tablo 1'de tüm işaretler listelenmez, ancak bunlar başlamanız için yeterli olacaktır.

    Lütfen ate ve app bayraklarının açıklama açısından çok benzer olduğunu, her ikisinin de işaretçiyi dosyanın sonuna götürdüğünü, ancak uygulama bayrağının yalnızca dosyanın sonuna yazmaya izin verdiğini ve ate bayrağının bayrağı basitçe yeniden düzenlediğini unutmayın. dosyanın sonu ve kayıt alanını sınırlamaz.

    Sizeof() işlemini kullanarak C++'daki ana veri türlerinin özelliklerini hesaplayacak ve bunları bir dosyaya yazacak bir program geliştirelim. Özellikler:

    1. veri türü için ayrılan bayt sayısı
    2. belirli bir veri türünün saklayabileceği maksimum değer.

    Bir dosyaya yazmak aşağıdaki formatta olmalıdır:

    /* veri tipi bayt maks. değer bool = 1 255.00 char = 1 255.00 short int = 2 32767.00 unsigned short int = 2 65535.00 int = 4 2147483647.00 unsigned int = 4 4294967295.00 long int = 4 214748364 7.00 işaretsiz uzun int = 4 4294967295.00 kayan nokta = 4 2147483647,00 uzun değişken = 8 9223372036854775800,00 çift = 8 9223372036854775800,00 */

    Bu tür bir program bu bölümde daha önce geliştirilmiştir, ancak orada veri türleri hakkındaki tüm bilgiler standart çıktı aygıtına verildi ve bilgilerin bir dosyaya yazılması için programı yeniden oluşturmamız gerekiyor. Bunu yapmak için, dosyayı geçerli dosya bilgilerinin ön kesilmesiyle yazma modunda açmanız gerekir ( satır 14). Dosya oluşturulduktan ve başarıyla açıldıktan sonra (satır 16 - 20), cout ifadesi yerine, satır 22 fout nesnesini kullanın. böylece ekran yerine veri türleri ile ilgili bilgiler bir dosyaya yazılacaktır.

    // write_file.cpp: konsol uygulaması için giriş noktasını tanımlar. #include "stdafx.h" #include #katmak // dosyalarla çalış #include // ad alanı std kullanan G/Ç manipülatörleri; int main(int argc, char* argv) ( setlocale(LC_ALL, "rus"); // nesneyi dosyaya bağla, dosyayı yazma kipinde açarken, önce içindeki tüm verileri silerek fout("data_types.txt) ", ios_base::out | ios_base::trunc); if (!fout.is_open()) // dosya açılmadıysa ( cout<< "Файл не может быть открыт или создан\n"; // напечатать соответствующее сообщение return 1; // выполнить выход из программы } fout << " data type " << "byte" << " " << " max value "<< endl // sütun başlıkları <<"bool = " << sizeof(bool) << " " << fixed << setprecision(2) /*вычисляем максимальное значение для типа данных bool*/ << (pow(2,sizeof(bool) * 8.0) - 1) << endl << "char = " << sizeof(char) << " " << fixed << setprecision(2) /*вычисляем максимальное значение для типа данных char*/ << (pow(2,sizeof(char) * 8.0) - 1) << endl << "short int = " << sizeof(short int) << " " << fixed << setprecision(2) /*вычисляем максимальное значение для типа данных short int*/ << (pow(2,sizeof(short int) * 8.0 - 1) - 1) << endl << "unsigned short int = " << sizeof(unsigned short int) << " " << fixed << setprecision(2) /*вычисляем максимальное значение для типа данных unsigned short int*/ << (pow(2,sizeof(unsigned short int) * 8.0) - 1) << endl << "int = " << sizeof(int) << " " << fixed << setprecision(2) /*вычисляем максимальное значение для типа данных int*/ << (pow(2,sizeof(int) * 8.0 - 1) - 1) << endl << "unsigned int = " << sizeof(unsigned int) << " " << fixed << setprecision(2) /*вычисляем максимальное значение для типа данных unsigned int*/ << (pow(2,sizeof(unsigned int) * 8.0) - 1) << endl << "long int = " << sizeof(long int) << " " << fixed << setprecision(2) /*вычисляем максимальное значение для типа данных long int*/ << (pow(2,sizeof(long int) * 8.0 - 1) - 1) << endl << "unsigned long int = " << sizeof(unsigned long int) << " " << fixed << setprecision(2) /*вычисляем максимальное значение для типа данных undigned long int*/ << (pow(2,sizeof(unsigned long int) * 8.0) - 1) << endl << "float = " << sizeof(float) << " " << fixed << setprecision(2) /*вычисляем максимальное значение для типа данных float*/ << (pow(2,sizeof(float) * 8.0 - 1) - 1) << endl << "long float = " << sizeof(long float) << " " << fixed << setprecision(2) /*вычисляем максимальное значение для типа данных long float*/ << (pow(2,sizeof(long float) * 8.0 - 1) - 1) << endl << "double = " << sizeof(double) << " " << fixed << setprecision(2) /*вычисляем максимальное значение для типа данных double*/ << (pow(2,sizeof(double) * 8.0 - 1) - 1) << endl; fout.close(); // программа больше не использует файл, поэтому его нужно закрыть cout << "Данные успешно записаны в файл data_types.txt\n"; system("pause"); return 0; }

    Standart giriş/çıkış ve dosya giriş/çıkışının tamamen aynı şekilde kullanılması sayesinde programdaki değişikliklerin minimum düzeyde olduğunu fark etmemek imkansızdır. Programın sonunda,satır 45dosyayı açıkça kapattık, bu gerekli olmasa da, iyi bir programlama uygulaması olarak kabul edilir. Standart girdi/çıktıyı biçimlendirmek için kullanılan tüm işlevlerin ve manipülatörlerin, dosya girdi/çıktısıyla da ilgili olduğunu belirtmek gerekir. Bu nedenle, operatör çalışırken herhangi bir hata oluşmadı. cout bir nesne ile değiştirildi kavga

    fopen() işlevi kullanım için bir akış açar, bir dosyayı verilen akışla ilişkilendirir ve ardından verilen akışa bir FILE işaretçisi döndürür. Çoğu zaman, bir dosya bir disk dosyası olarak değerlendirilir. fopen() işlevi aşağıdaki prototipe sahiptir:

    DOSYA *fopen(const char *dosyaadı, const char *mode);

    Mod, istenen dosya açma modunu içeren bir diziyi işaret eder. Borland C++'daki mod için geçerli değerler tabloda gösterilmektedir. dosyaadı, işletim sistemi için geçerli bir dosya adı sağlayan bir karakter dizisi olmalıdır ve bir yol içerebilir.

    fopen() işlevi, DOSYA temel türüne bir işaretçi döndürür. Bu işaretçi bir dosyayı tanımlar ve çoğu dosya sistemi işlevi tarafından kullanılır. Asla kendi başınıza değiştirilmemelidir. Dosya açılamıyorsa işlev boş gösterici döndürür.

    Tabloda gösterildiği gibi, bir dosya metin veya ikili modda açılabilir. Metin modunda, yazarken, satır başı ve satır besleme sırası yeni satır karakterine çevrilir. Çıktıda bunun tersi doğrudur: yeni satır karakteri satırbaşına ve satır beslemeye çevrilir. İkili dosyalarda böyle bir çeviri yoktur. Mod bağımsız değişkeninde ne t ne de b belirtilmediğinde, dosyanın metin/ikili durumu, Borland C++'da tanımlanan _fmode genel değişkeninin değeri tarafından belirlenir. Varsayılan olarak, fmode O_TEXT olarak ayarlanmıştır, yani metin modu ayarlanmıştır. _fmode öğesinin O_BINARY olarak ayarlanması, dosyaları ikili modda açacaktır. (Bu makrolar fcntl.h'de tanımlanmıştır.) Doğal olarak, açık bir t veya b kullanmak, _fmode değişkeninin etkilerini ortadan kaldırır. Bunun dışında _fmode sadece Borland ürünlerine özeldir. ANSI C G/Ç sisteminde tanımlanmamıştır.

    Yazmak için test adlı bir dosyayı açmanız gerekiyorsa, şunu yazmalısınız:

    Fp = fopen("test", "w");

    Burada fp, FILE * türünde bir değişkendir. Ancak, genellikle aşağıdakileri görürsünüz:

    If((fp = fopen("test", "w"))==BOŞ) (
    puts("Dosya açılamıyor.");
    çıkış(1);
    }

    Bu yöntem, bir dosyayı açarken, örneğin yazma korumasının varlığı veya boş disk alanı eksikliği gibi hataları tespit etmenizi sağlar.

    Bir dosyayı yazmak üzere açmak için fopen() kullanılırsa, belirtilen ada sahip önceden var olan herhangi bir dosya silinecektir. Belirtilen ada sahip bir dosya yoksa oluşturulur.

    Dosyanın sonuna bilgi eklemeniz gerekirse, a (ekleme) modunu kullanmalısınız. Dosya yoksa, oluşturulacaktır.

    Bir dosyayı okumak için açmak, dosyanın varlığını gerektirir. Dosya yoksa, bir hata döndürülür. Dosya okuma/yazma işlemine açıksa varsa silinmez, yoksa dosya oluşturulur.

    Tablo: İzin Verilen Mod Değerleri

    Anlam

    Okumak için bir dosya açar. (Varsayılan olarak bir metin dosyası olarak açılır.)

    Yazmak için bir dosya oluşturur. (Varsayılan olarak bir metin dosyası olarak açılır.)

    Bir dosyaya ekler. (Varsayılan olarak bir metin dosyası olarak açılır.)

    Okumak için bir ikili dosya açar.

    Yazmak için bir ikili dosya açar.

    Bir ikili dosyaya ekler.

    Okumak/yazmak için bir dosya açar. (Varsayılan olarak bir metin dosyası olarak açılır.)

    Bir okuma/yazma dosyası oluşturur. (Varsayılan olarak bir metin dosyası olarak açılır.)

    Bir okuma/yazma dosyası ekler veya oluşturur. (Varsayılan olarak bir metin dosyası olarak açılır.)

    Okuma/yazma için bir ikili dosya açar.

    Bir okuma/yazma ikili dosyası oluşturur.

    Bir okuma/yazma ikili dosyası ekler veya oluşturur.

    Yazmak için bir metin dosyası oluşturur.

    Bir metin dosyasına ekler.

    Okumak için bir metin dosyası açar.

    Bir okuma/yazma metin dosyası oluşturur.

    Bir okuma/yazma metin dosyası açar veya oluşturur.

    - eşitlik veya eşitsizliği belirlemek için karşılaştırma.

    Bir numaralandırmanın pratik amacı, bir tamsayı türünden bir dizi farklı sembolik sabit tanımlamaktır.

    Numaralandırılmış değişkenleri kullanmaya bir örnek:

    mo=1, tu, we, th, fr, sa, su ) gün;

    koyar(“ Haftanın gününü girin (1'den 7'ye kadar) : ”); scanf("%d", &t_day);

    w_day=su; başlangıç ​​= ay;

    bitiş = w_day -t_day;

    printf(“\n Pazartesi haftanın %d. günü, \ şimdi %d. günü. \n\

    Haftanın sonuna kadar %d gün (gün). ”, başlangıç, t_gün, bitiş);

    Programın sonucu: Haftanın gününü girin (1'den 7'ye kadar): 2

    Pazartesi haftanın 1. günü, şimdi 2. günü. Hafta sonuna kadar 5 gün (gün).

    18. C dilinde dosyalar

    Dosya, harici bir ortama yerleştirilen ve işlenirken bir bütün olarak kabul edilen bir veri kümesidir. Dosyalar, uzun süreli depolamaya yönelik verileri içerir.

    İki tür dosya vardır: metin ve ikili. Metin dosyaları bir ASCII karakter dizisidir ve herhangi bir metin düzenleyiciyle görüntülenebilir ve düzenlenebilir.

    İkili (ikili) dosyalar, yapısı yazılım tarafından belirlenen bir veri dizisidir.

    C dili, çoğu stdio.h ve io.h kitaplıklarında bulunan dosyalarla çalışmak için geniş bir işlev kümesine sahiptir.

    18.1. dosya açma

    Her dosyaya, daha sonra kendisine atıfta bulunulurken kullanılan dahili bir mantıksal ad atanır. Mantıksal ad (dosya kimliği)

    dosya işaretçisi, yani dosya hakkında gerekli tüm bilgileri içeren bir bellek alanına. Bir dosya işaretçisi bildirme biçimi aşağıdaki gibidir:

    DOSYA * bir dosyaya işaretçi;

    DOSYA, standart kitaplıkta açıklanan yapısal bir tür tanımlayıcıdır

    stdio.h ve aşağıdaki bilgileri içeren:

    yapı tipi (

    – tamponda kalan okunmamış bayt sayısı;

    normal arabellek boyutu 512 bayttır; seviye=0 olur olmaz,

    sonraki veri bloğu dosyadan tampona okunur;

    – dosya durum bayrağı – okuma, yazma, ekleme;

    – dosya tanımlayıcı, yani onu tanımlayan sayı

    imzasız karakter tutma;

    – iletilmemiş karakter, yani ungetc-sembol;

    – dahili ara tamponun boyutu;

    işaretsiz karakter arabelleği;

    arabellek içinde erişilecek işaretçinin değeridir, yani

    arabelleğin başlangıcını, satırın başlangıcını veya geçerli değeri belirtir

    moda bağlı olarak arabellek içindeki işaretçinin değeri

    ara belleğe alma;

    işaretsiz karakter *curp;

    arabellek içinde erişim için işaretçinin geçerli değeridir

    Fera, yani değişim arabelleğindeki geçerli konumu ayarlar

    programa devam;

    imzasız istemp;

    – geçici dosya bayrağı;

    – bir dosya ile çalışırken işaretleyin;

    ) DOSYA;

    Dosyayla çalışmaya başlamadan önce, yani. bir dosyaya bilgi okuyabilmek veya yazabilmek için erişim için açılması gerekir. Bu genellikle işlev kullanılarak yapılır.

    DOSYA* fopen(char* dosya adı, char* modu);

    harici bir temsil alır - ortamdaki (disket, sabit sürücü) dosyanın fiziksel adı ve ona mantıksal bir ad atar.

    Fiziksel ad, yani dosya adı ve yolu ilk parametre tarafından verilir

    – bir dizi, örneğin, “a:Mas_dat.dat” diskette bulunan Mas_dat.dat adlı bir dosyadır, “d:\\work\\Sved.txt” sabit diskte bulunan Sved.txt adlı bir dosyadır. çalışma dizininde sürücü.

    Dikkat! Ters eğik çizgi (\), özel bir karakter olarak bir dizgede iki kez yazılır.

    Başarılı açmanın ardından, fopen işlevi bir dosya işaretçisi döndürür (bundan sonra dosya işaretçisi olarak anılacaktır). Hata durumunda NULL döndürülür. Bu durum genellikle, açılan dosyanın yolu yanlış belirtildiğinde ortaya çıkar. Örneğin, üniversitemizin görüntü sınıfında yazılması yasak olan bir yol belirtirseniz (genellikle d:\work\ izin verilir).

    İkinci parametre, dosya erişim modunu belirten bir dizedir:

    w - dosya yazmak için açılır; verilen ada sahip bir dosya yoksa oluşturulacaktır; böyle bir dosya varsa, önceki bilgiler açılmadan önce yok edilir;

    r - dosya sadece okuma için açılır; böyle bir dosya yoksa bir hata oluşur;

    a - dosya sonuna yeni bilgiler eklemek için açılır;

    r+ - dosya veri düzenleme için açılır - hem bilgi yazmak hem de okumak mümkündür;

    w+, r+ ile aynıdır;

    a+ - a ile aynı, dosyanın herhangi bir yerinde yalnızca yazma işlemi gerçekleştirilebilir; dosya okuma da mevcuttur;

    t - dosya metin modunda açılır; b - dosya ikili modda açılır.

    Metin modu, bir dosyayı bir metin çifti olarak açarken "satır besleme", "satır başı" karakterlerinin bir karakterle değiştirilmesi bakımından ikili moddan farklıdır: dosyaya veri yazmanın tüm işlevleri için "satır besleme" ve tüm çıktı işlevleri için, "satır besleme" " karakteri artık iki karakterle değiştirilmiştir: "satır besleme", "satır başı".

    Varsayılan olarak, dosya metin modunda açılır. Örnek: DOSYA *f; – f dosyasına bir işaretçi bildirilir;

    f = fopen("d:\\work\\Dat_sp.cpp", "w"); – dizin çalışmasında d diskinde bulunan Dat_sp.cpp fiziksel adına sahip f mantıksal adına sahip bir dosya yazmak için açılır; veya daha kısaca

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

    18.2. bir dosyayı kapatma

    Dosyayla çalıştıktan sonra dosyaya erişim kapatılmalıdır. Bu, int fclose (dosya işaretçisi) işlevi tarafından yapılır. Örneğin, önceki örnekte dosya şu şekilde kapatılır: fclose (f);

    Birden çok dosyayı kapatmak için, aşağıdaki gibi açıklanan bir işlev sunulmuştur: void fcloseall(void );

    Dosya erişim modunu değiştirmek istiyorsanız, önce dosyayı kapatmanız ve ardından farklı erişim haklarıyla yeniden açmanız gerekir. Bunu yapmak için standart işlevi kullanın:

    FILE* freopen (char*dosyaadı, char *mode, FILE *filepointer);

    Bu işlev önce bildirilen dosyayı kapatır. dosya işaretçisi(fopen işlevinin yaptığı gibi) ve ardından dosyayı dosya adı ve "mod" izinleriyle açar.

    C dili, yalnızca programın çalışması sırasında ihtiyaç duyulan geçici dosyalarla çalışma yeteneğine sahiptir. Bu durumda, işlev kullanılır

    DOSYA*tmp dosyası(geçersiz);

    “w+b” izinleri ile disk üzerinde geçici dosya oluşturan program sona erdikten veya geçici dosya kapatıldıktan sonra otomatik olarak silinir.

    18.3. Yazma - bilgi okuma

    Bir dosyaya veri okumak ve yazmak için tüm eylemler üç gruba ayrılabilir: karakter karakter giriş-çıkış işlemleri; hat giriş/çıkış işlemleri; blok G/Ç işlemleri.

    Bu üç işlem grubunun her birinde kullanılan ana işlevleri göz önünde bulundurun.

    Karakter G/Ç

    Karakter G/Ç işlevleri, bir dosyadan tek bir karakter kabul eder veya bir dosyaya tek bir karakter aktarır:

    Satır G/Ç

    Hat G/Ç işlevleri bir dosyadan veya

    Blok G/Ç

    Blok G/Ç işlevleri tüm bloklarda çalışır

    bilgi:

    int fread (void*p, intsize,

    - dosyaların her biri için n bayt boyutunda blok okur

    int n, DOSYA *f)

    p işaretçisi ile bellek alanına la f girin (gerekir

    int fwrite (void*p, intsize,

    okunmakta olan blok için önceden bellek ayırın);

    – her biri bayt boyutunda n blok yazar

    int n, DOSYA *f)

    işaretçi p ile f dosyasına bellek konumu.

    Biçimlendirilmiş G/Ç, işlevler tarafından üretilir.

    Bundan önce, veri girip çıkarken standart akışlarla - klavye ve monitör - çalışıyorduk. Şimdi C dilinin dosyalardan veri alıp oraya yazmayı nasıl uyguladığına bakalım. Bu işlemler yapılmadan önce dosyanın açılması ve erişim sağlanması gerekmektedir.

    C programlama dilinde, bir dosya işaretçisi FILE türündedir ve bildirimi şöyle görünür:
    DOSYA *dosyam;

    Öte yandan, fopen() işlevi dosyayı okuma ("r"), yazma ("w") veya ekleme ("a") kipinde ilk bağımsız değişken olarak belirtilen adreste açar ve ona bir işaretçi döndürür programa Bu nedenle, bir dosyayı açma ve onu programa bağlama işlemi şuna benzer:
    dosyam = fopen("merhaba.txt", "r");

    Bir dosyaya veri okurken veya yazarken, dosyaya bir dosya işaretçisi aracılığıyla erişilir (bu durumda, dosyam).

    Herhangi bir nedenle (belirtilen adreste dosya yoksa, ona erişim reddedilirse) fopen() işlevi dosyayı açamaz, ardından NULL değerini döndürür. Gerçek programlarda, bir dosyayı açma hatası neredeyse her zaman if dalında işlenir, ancak bunu daha sonra atlayacağız.

    fopen() işlev bildirimi, stdio.h başlık dosyasında bulunur, bu nedenle dahil edilmesi gerekir. FILE yapı türü ayrıca stdio.h'de bildirilir.

    Dosyayla çalışma bittikten sonra, arabelleği verilerden boşaltmak için ve diğer nedenlerle dosyayı kapatmak gelenekseldir. Bu, özellikle program dosyayla çalıştıktan sonra çalışmaya devam ederse önemlidir. Harici bir dosya ile ona programdan gelen bir işaretçi arasındaki bağlantıyı kesmek, fclose() işlevi kullanılarak yapılır. Bir dosya işaretçisini parametre olarak alır:
    fclose(dosyam);

    Programda birden fazla dosya açılabilir. Böyle bir durumda, her dosya kendi dosya işaretçisi ile ilişkilendirilmelidir. Ancak, program önce bir dosyayla çalışır, sonra onu kapatırsa, işaretçi ikinci bir dosyayı açmak için kullanılabilir.

    Metin dosyasından okuma ve yazma

    fscanf()

    fscanf() işlevi, anlam olarak scanf() işlevine benzer, ancak ondan farklı olarak, standart girdi yerine bir dosyadan biçimlendirilmiş girdi alır. fscanf() işlevi parametreleri alır: dosya işaretçisi, biçim dizesi, veri yazmak için bellek alanlarının adresleri:
    fscanf(dosyam, "%s%d", str, &a);

    Başarıyla okunan veri sayısını veya EOF'yi döndürür. Veri ayırıcı olarak boşluklar, yeni satır karakterleri dikkate alınır.

    Diyelim ki aşağıdaki nesnelerin açıklamasını içeren bir dosyamız var:

    Elma 10 23,4 muz 5 25,0 ekmek 1 10,3

    #katmak main () ( FILE * file; struct food ( char name[ 20 ] ; unsigned qty; float price; ) ; struct food shop[ 10 ] ; char i= 0 ; file = fopen ("fscanf.txt" , "r" while (fscanf (dosya, "%s%u%f" , mağaza[i] .ad , & (dükkan[i] .qty ) , & (dükkan[i] .fiyat ) ) != EOF) ( printf ("%s %u %.2f \N", dükkan[i] .isim , dükkan[i] .qty , dükkan[i] .fiyat ) ; ben++; ) )

    Bu durumda, bir yapı ve bir dizi yapı bildirilir. Dosyadaki her satır, dizinin bir öğesine karşılık gelir; dizi öğesi, bir dize ve iki sayısal alan içeren bir yapıdır. Döngü, yineleme başına bir satır okur. Dosyanın sonu ile karşılaşıldığında fscanf(), EOF'yi döndürür ve döngü sona erer.

    fgets()

    fgets() işlevi, gets() işlevine benzer ve bir dosyadan satır satır girdi gerçekleştirir. fgets() öğesine yapılan bir çağrı, bir satırı okuyacaktır. Bu durumda, satırın tamamını değil, yalnızca bir kısmını baştan okuyamazsınız. fgets() seçenekleri şöyle görünür:
    fgets (array_of_characters, number_of_characters_to_read, pointer_to_file)

    Örneğin:
    fgets(str, 50, dosyam)

    Böyle bir işlev çağrısı, uzunluğu 50 karakterden azsa, işlevin dizide depolayacağı "\n" karakteri de dahil olmak üzere, myfile işaretçisiyle ilişkili dosyadan tam bir metin satırı okuyacaktır. str dizisinin son (50.) öğesi, fgets() tarafından eklenen "\0" karakteri olacaktır. Dize daha uzunsa işlev 49 karakter okuyacak ve sonuna "\0" yazacaktır. Bu durumda, okuma satırında "\n" bulunmaz.

    #katmak #define N 80 main () ( FILE * dosya; char dizi[N] ; dosya = fopen ("fscanf.txt" , "r" ) ; while (fgets (dizi, N, dosya) != NULL) printf (" %s", dizi) ; printf(" \N") ; fclose(dosya); )

    Bu programda öncekinden farklı olarak veriler arr dizisine satır satır okunur. Bir sonraki satır okunduğunda bir önceki satır kaybolur. fgets() işlevi, sonraki satırı okuyamazsa NULL değerini döndürür.

    getc() veya fgetc()

    getc() veya fgetc() işlevi (her ikisi de çalışır), dosyadan bir sonraki karakteri almanızı sağlar.

    while ((arr[ i] = fgetc (dosya) ) != EOF) ( if (arr[ i] == " \N") ( dizi[i] = " \0 " ; printf("%s \N", dizi) ; ben = 0 ) başka i++; ) dizi[i] = " \0 " ; printf("%s \N", dizi) ;

    Örnek olarak verilen kod, bir dosyadaki verileri ekrana yazdırır.

    Bir metin dosyasına yazma

    Tıpkı girdi gibi, bir dosyanın çıktısı da farklı olabilir.

    • Biçimlendirilmiş çıktı. fprintf işlevi (file_pointer, format_string, değişkenler) .
    • Çıkış sonrası. fputs(dize, dosya işaretçisi) işlevi.
    • Sembolik çıktı. fputc() veya putc(karakter, dosya işaretçisi) .

    Aşağıda, verileri bir dosyaya çıkarmak için üç yol kullanan kod örnekleri verilmiştir.

    Bir yapının alan dosyasının her satırına yazma:

    dosya = fopen("fprintf.txt" , "w" ) ; while (scanf ("%s%u%f" , shop[i] .name , & (shop[i] .qty ) , & (shop[i] .price ) ) != EOF) ( fprintf (dosya, " %s %u %.2f \N", dükkan[i] .isim , dükkan[i] .qty , dükkan[i] .fiyat ) ; ben++; )

    Bir dosyaya satır satır çıktı (fputs() , puts()'un aksine, satırın sonuna "\n" koymaz):

    while ((arr) != NULL) ( fputs (dizi, dosya) ; fputs (" \N",dosya); )

    Karakter karakter çıktı örneği:

    while ((i = getchar () ) != EOF) putc (i, dosya) ;

    Bir ikili dosyadan okuma ve yazma

    Bir dosyayla bir karakter dizisi olarak değil, bir bayt dizisi olarak çalışabilirsiniz. Prensip olarak, metin olmayan dosyalarla farklı bir şekilde çalışmak imkansızdır. Ancak, metin dosyalarını da bu şekilde okuyabilir ve yazabilirsiniz. Bir dosyaya erişmenin bu yönteminin avantajı, okuma-yazma hızında yatmaktadır: önemli bir bilgi bloğu tek bir erişimde okunabilir/yazılabilir.

    Bir dosyayı ikili erişim için açarken, fopen() için ikinci argüman "rb" veya "wb" dizgisidir.

    İkili dosyalarla çalışma konusu oldukça karmaşıktır, onu incelemek ayrı bir ders gerektirir. Burada sadece bayt akışı olarak kabul edilen bir dosyaya okuma ve yazma işlevlerinin özellikleri belirtilecektir.

    fread() ve fwrite() işlevleri parametre olarak alır:

    1. verilerin yazıldığı veya okunduğu bellek alanının adresi,
    2. herhangi bir türden verilen birinin boyutu,
    3. Belirtilen boyutta okunacak veri miktarı,
    4. dosya işaretçisi.

    Bu işlevler, başarıyla okunan veya yazılan verilerin sayısını döndürür. Onlar. 50 veri öğesinin okunmasını "sipariş edebilir" ve yalnızca 10 tane alabilirsiniz. Hata olmayacaktır.

    fread() ve fwrite() işlevlerinin kullanımına bir örnek:

    #katmak #katmak main () ( FILE * dosya; char raf1[ 50 ] , raf2[ 100 ] ; int n, m; dosya = fopen ("shelf1.txt" , "rb") ; n= fread (shelf1, sizeof (char ) , 50, dosya) ; fclose (dosya) ; file = fopen ("shelf2.txt" , "rb" ) ; m= fread (shelf2, sizeof (char ) , 50 , dosya) ; fclose (dosya) ; raf1[n] = " \0 " ; raf2[m] = " \N"; raf2[ m+ 1 ] = " \0 " ; dosya = fopen("shop.txt", "wb" ) ; fwrite (strcat (raf2, raf1) , sizeof (char ) , n+ m, dosya) ; fclose(dosya); )

    Burada ilk dosyadan 50 karakter okunmaya çalışılır. n, gerçekten okunan karakter sayısını saklar. n değeri 50 veya daha az olabilir. Veriler bir diziye yerleştirilir. Aynı şey ikinci dosyada da olur. Ardından, ilk satır ikinciye eklenir ve veriler üçüncü dosyaya dökülür.

    Problem çözme

    1. Kullanıcıdan bir metin dosyasının adını (adresini) soran, sonra onu açan ve içindeki karakter ve satır sayısını sayan bir program yazın.
    2. Başka bir dosyadan alınan verileri bir dosyaya yazan ve yazılmadan önce şu veya bu şekilde değiştirilen bir program yazın. Dosyadan alınan her veri satırı bir yapıya yerleştirilmelidir.

    tarafından geliştirilen G / Ç mekanizması, günümüzde genel kabul görmüş nesne yönelimli programlama tarzına karşılık gelmemektedir, ayrıca modern güvenli kod yürütme ortamlarında potansiyel olarak güvensiz kabul edilen işaretçi işlemlerini aktif olarak kullanmaktadır. Uygulama geliştirme için bir alternatif, C++ dil standardı tarafından sağlanan standart G/Ç sınıf mekanizmasıdır.

    Dosyaları açma

    En sık kullanılan sınıflar, okuma için ifstream, yazma için ofstream ve dosyaları değiştirmek için fstream'dir.

    Tüm iş parçacıklı G/Ç sınıfları, işlevselliğini tam olarak devralan ortak atadan dolaylı olarak türetilmiştir. Örneğin, open_mode numaralandırılmış veri üyesi, aşağıdaki gibi tanımlanan dosya açma modunu belirtir:

    Enum open_mode (uygulama, ikili, giriş, çıkış, trunc, ate );

    Bayrakların olası değerleri ve amaçları aşağıdadır.

    Örneğin, ikili verileri okumak üzere test.txt adlı bir dosyayı açmak için şunu yazarsınız:

    ifstream dosyası; file.open("test.txt", ios::in | ios::binary);

    Mantıksal VEYA operatörü (|), herhangi bir bayrak kombinasyonu ile bir mod oluşturmanıza olanak tanır. Bir dosyayı yazarak açarken yanlışlıkla aynı ada sahip mevcut bir dosyanın üzerine yazmamak için aşağıdaki formu kullanmalısınız:

    akış dışı dosya; file.open("test.txt", ios::out | ios::app);

    Uygun başlık dosyasının projeye bağlı olduğu varsayılır:

    #katmak

    Dosyanın başarıyla açılıp açılmadığını kontrol etmek için yapıyı kullanabilirsiniz.

    If (!file) ( // Dosya açma hatası işleme )

    Dahil Etme ve Çıkarma İşleçleri

    Dosya işleme sınıflarında geçersiz kılındı işleci dahil et (<<) записывает данные в файловый поток. Как только вы открыли файл для записи, можно записывать в него текстовую строку целиком:

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

    Bir metin dizesini parçalara da yazabilirsiniz:

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

    endl ifadesi, satır girişini bir satır başı ile sonlandırır:

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

    İnclude operatörünü kullanarak değişkenlerin veya dizi elemanlarının değerlerini bir dosyaya yazmak kolaydır:

    Akış dosyası ("Temp.txt"); char buff = "Metin dizisi değişkenler içeriyor"; int vx = 100; kayan pi = 3,14159; dosya<< buff << endl << vx << endl << pi << endl;

    Kod yürütmenin bir sonucu olarak, Temp.txt metin dosyasının üç satırı oluşturulur:

    Metin dizisi değişkenleri içerir 100 3.14159

    Sayısal değerlerin dosyaya ikili değerler olarak değil metin dizileri olarak yazıldığını unutmayın.

    çıkarma operatörü(>>) tam tersini yapar. Görünüşe göre daha önce yazılmış Temp.txt dosyasından karakterleri çıkarmak için aşağıdaki gibi bir kod yazmanız gerekiyor:

    ifstream dosyası("Temp.txt"); karakter tutkunu; intvx; şamandıra; dosya >> buff >> vx >> pi;

    Ancak, ayıklama işleci karşılaştığı ilk sınırlayıcıda (boşluk, sekme veya yeni satır) duracaktır. Böylece, "Metin dizisi değişkenleri içerir" cümlesini ayrıştırırken, diziye yalnızca "Metin" kelimesi yazılacak buff , boşluk yok sayılır ve "dizi" kelimesi vx tamsayı değişkeninin ve kodun değeri olur. yürütme, veri yapısının kaçınılmaz bir ihlaliyle "karmaşaya dönecek". Ardından, ifstream sınıfını tartışırken, önceki örnekten dosyanın okunmasını doğru bir şekilde nasıl organize edeceğimizi göstereceğiz.

    ifstream sınıfı: dosyaları okuma

    Adından da anlaşılacağı gibi, ifstream sınıfı bir dosya akışı girmek için tasarlanmıştır. Sınıfın ana metotları aşağıda listelenmiştir. Çoğu, istream sınıfından miras alınır ve üst işlevlerle aşırı yüklenir. Örneğin, get işlevi, çağrı parametresine bağlı olarak yalnızca tek bir karakteri değil, aynı zamanda bir karakter bloğunu da okuyabilir.

    Şimdi, veri çıkarma işlecini kullanmanın beklenen sonucu vermesi için önceki örneği nasıl değiştirmeniz gerektiği açıktır:

    ifstream dosyası("Temp.txt"); karakter tutkunu; intvx; şamandıra; file.getline(buff, sizeof(buff)); dosya >> vx >> pi:

    Getline yöntemi dosyanın ilk satırını sonuna kadar okuyacak ve >> operatörü değişkenlere değer atayacaktır.

    Aşağıdaki örnek, bir metin dosyasına veri eklemeyi ve ardından tüm dosyayı okumayı gösterir. bölümünde açıklanan nedenlerden dolayı while(!file2.eof()) yerine while (1) döngüsü kullanılır.

    #katmak #katmak ad alanı std kullanarak; int main() ( akış dosyası; 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 >>a; if (file2.eof()) kırılırsa; cout<< a << " "; k++; } cout << endl << "K=" << k << endl; file2.close(); cin.sync(); cin.get(); return 0; }

    Aşağıdaki örnek, test.txt dosyasındaki satırları okuma ve bunları konsolda görüntüleme arasında döngü halindedir.

    #katmak #katmak ad alanı std kullanarak; int main() ( ifstream dosyası; // bir akış nesnesi oluştur dosya file.open("test.txt"); // if (!file) 1 döndürürse dosyayı okumak için aç; // char str açma hatasında geri dön; / / statik satır arabelleği // eof while (!file.getline(str, sizeof(str))).eof()) cout'a kadar bir döngüdeki satırları okuyun ve görüntüleyin<< str << endl; // вывод прочитанной строки на экран cin.sync(); cin.get(); return 0; }

    Windows işletim sistemi altındaki bu kod, dosyanın son satırında bir yeni satır karakterinin varlığına da bağlıdır, bunu yapmak daha güvenilir olacaktır:

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

    Açık ve kapalı yöntemlere yapılan açık çağrılar isteğe bağlıdır. Aslında, yapıcıyı bir bağımsız değişkenle çağırmak, dosya akış nesnesi yaratıldığı anda dosyayı hemen açmanıza olanak tanır:

    ifstream dosyası("test.txt");

    Close yöntemi yerine, dosya nesnesinin yıkıcısını otomatik olarak çağıracak ve dosyayı kapatacak olan silme işlecini kullanabilirsiniz. While döngüsü kodu, uygun dosya sonu denetimi sağlar.

    akış sınıfı: dosya yazma

    Ofstream sınıfı, bir dosya akışından veri çıkarmak için tasarlanmıştır. Bu sınıfın ana metotları aşağıda listelenmiştir.

    Daha önce açıklanan içerme işleci, bir metin dosyasına yazmayı düzenlemek için uygundur:

    Akış dosyası ("temp.txt"); eğer (!dosya) dönerse; için (int ben=1; ben<=3; i++) file << "Строка " << i << endl; file.close();

    ikili dosyalar

    Prensip olarak, ikili veriler metin verileri gibi sunulur. Aradaki fark, ikili veriler belirli bir mantıksal yapıda yazılırsa, dosyadan aynı yapı tipindeki bir değişkene okunmaları gerektiğidir.

    Yazma ve okuma yöntemlerinin ilk parametresi (yazma/okuma bloğunun adresi), char * karakter işaretçisi türünde olmalıdır, bu nedenle, geçersiz * yapısının adres türünü açıkça dönüştürmek gerekir. İkinci parametre, dosyanın ikili bloklarının gerçek kayıt uzunluğundan bağımsız olarak sabit bir bayt boyutuna sahip olduğunu belirtir. Aşağıdaki ek, verilerin basit bir not defterinde nasıl oluşturulup görüntüleneceğine dair bir örnek vermektedir. Dosyanın kayıtları daha sonra sırayla okunur ve konsolda görüntülenir.

    #katmak #katmak #katmak ad alanı std kullanarak; struct Notlar ( // not defterinin veri yapısı char İsim; // tam isim char Telefon; // telefon int Yaş; // yaş ); int main() ( setlocale(LC_ALL, "Rusça"); Notlar Not1= ("Grozny Ioann Vasilyevich", "kurulu değil", 60 ); Notlar Not2= ("Godunov Boris Fedorovich", "095-111-2233 ", 30); Notlar Not3= ("Peter Romanov ", "812-333-2211 ", 20 ); ofstream ofile("Notebook.dat", ios::binary); ofile.write((char*)&Note1, sizeof ( Notes)); // 1. blok ofile.write((char*)&Note2, sizeof(Notes)); // 2. blok ofile.write((char*)&Note3, sizeof(Notes)); / / 3. blok dosya. kapat(); // yazılan dosyayı kapat ifstream ifile("Notebook.dat", ios::binary); Notlar Not; // yapılandırılmış değişken char str; // statik dize arabelleği // Satırları bir döngü içinde oku ve görüntüle eof while (!ifile.read((char*)&Note, sizeof(Notes))).eof()) ( sprintf(str, "%s\tBody: %s\tAge: %d" , Note.Name, Note. Telefon, Not.Yaş); cout<< str << endl; } ifile.close(); // закрыть прочитанный файл cin.sync(); cin.get(); return 0; }

    Bu kodu çalıştırmanın bir sonucu olarak, her biri 80 baytlık üç bloktan (karakterlerin tek bayt olduğu varsayılarak) bir ikili dosya Notebook.dat oluşturulur. Doğal olarak, diğer akış yöntemlerini kullanabilir ve belirli bir veri yapısının alanları üzerinde herhangi bir işlemi gerçekleştirebilirsiniz.

    fstream sınıfı: rastgele dosya erişimi

    Diyelim ki defterimizde 100 giriş birikti ve 50'nciyi saymak istiyoruz. Tabii ki, bir döngü düzenleyebilir ve ilkinden verilene kadar tüm kayıtları okuyabilirsiniz. Açıkçası daha hedefli bir çözüm, pos dosyası konum işaretçisini doğrudan giriş 50'ye ayarlamak ve onu okumaktır:

    ifstream ifile("Notebook.dat", ios::binary); int konum = 49 * sizeof(Notlar); ifile search(konum); // 50. girişi ara Notlar Not; //Notlar - yukarıda açıklanan "kayıt" yapısı ifile.read((char*)&Note, sizeof(Notes));

    Bu tür arama işlemleri, dosya bilinen ve sabit boyuttaki kayıtlardan oluşuyorsa etkilidir. Rastgele bir girişin içeriğini değiştirmek için çıktı akışını değiştirme modunda açmanız gerekir:

    Akış ofile("Notebook.dat", ios::binary | ios::ate); int konum = 49 * sizeof(Notlar); ofile searchp(konum); // 50. notayı arayın Notlar Not50 = ("Yeltsin Boris Nikolaevich", "095-222-3322", 64); ofile.write((char*)&Not, sizeof(Notlar)); // yenisiyle değiştirme

    ios::ate (veya ios::app) bayrağını belirtmezseniz, Notebook.dat ikili dosyasını açtığınızda önceki içeriği silinecektir!

    Son olarak, fstream akış sınıfının öncüllerinden devraldığı yöntemleri kullanarak bir dosyayı aynı anda okuma/yazma için açmak mümkündür. fstream sınıfı, istream ve ostream'den (sırasıyla ifstream ve ofstream'in ebeveynleri) türetildiğinden, daha önce bahsedilen tüm yöntemler uygulama tarafından kullanılabilir hale gelir.

    Aşağıdaki örnek, Notebook.dat dosyasındaki birinci ve üçüncü girişleri değiştirir.

    #katmak #katmak #katmak ad alanı std kullanarak; struct Notlar ( char Adı; char Telefon; int Yaş; ); int main() ( setlocale(LC_ALL, "Rusça"); Notlar Not1, Not3; // Aynı anda okumak/yazmak için dosyayı aç fstream file("Notebook.dat", ios::binary | ios::in | ios:: out); file.seekg(2 * sizeof(Notes)); // Note3'ü bul ve oku file.read((char*)&Note3, sanaof(Notes)); file.seekg(0); // Note1'i bul ve oku file.read((char*)&Not1, sizeof(Notlar)); file.seekg(0); // Not1<== 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; }

    Eşzamanlı okuma ve yazma işlemlerine izin vermek için dosya nesnesinin yapıcısında ios::in ve ios::out işaretleri belirtilmelidir. Bu kodu çalıştırmanın bir sonucu olarak, Notebook.dat ikili dosyasının birinci ve üçüncü kayıtları değiştirilecektir.

    Konuyla ilgili ek örnekler var.