آموزش کار با فایل در c++ - هفت خط کد انجمن پرسش و پاسخ برنامه نویسی

آموزش کار با فایل در c++

+19 امتیاز

برای کار کردن با فایل در  سی پلاس پلاس از چه کتابخانه ای استفاده کنم ؟

در c++ برای باز کردن فایل می توانید از  کلاس های ofstream-ifstream-fstream  استفاده کنید.

چگونه فایل را باز کنیم ؟

در c++ میتوانید از open برای باز کردن فایل استفاده کنید.

مثال :

std::fstream file;
file.open ("test.txt");

یا می توایند هنگام صدا زده شدن سازنده(یا fstream  (constructor  فایل را باز کنید به این شکل :

fstream file ( "test.txt" );

در صورتی که فقط میخواهید فایل را برای خواندن باز کنید از ifstream و برای فقط نوشتن از ofstream نیز میتوان استفاده کرد مثال:

  ofstream file ("a.txt");
  ifstream file ("a.txt");

آیا میتوان فایل را در حالت های متفاوت باز کرد ؟

بله با ارسال پارامتر های زیر به open یا سازنده fstream

  1. in : فایل برای خواندن باز میشود.
  2. out : فایل برای نوشتن باز میشود.
  3. binary : انجام عملیات ها در حالت باینری
  4. ate : محل عملیا خروجی در آخر فایل قرار می گیرد(نوشتن در آخر فایل انجام میشود)
  5. app : خروجی در آخر فایل اضافه میشود.
  6. trunc : زمان باز شدن فایل کل اطلاعاتش پاک می شود.

زمانی که در open  با سازنده پرامتر خاصی فرستاده نشوذ پارامتر های پیش فرض زیر فرستاده میشوند : 

  • fstream:in,out
  • ifstream:in
  • ofstream:out

میباشد.

همچنین میتوان 2 یا چند پارامتر را بصورت همزمان به open فرستاد .

تفاوت ate با app چیست ؟

ate زمانی که فایل باز میشود به آخر فایل می رود ولی app هر بار قبل از نوشتن اطلاعات به آخر فایل می رود یعنی اگر فایل را در حالت app باز کرده باشید فقط می توانید به آخر فایل متن اضافه کنید ولی برای ate می توان در بقیه جاهای فایل هم متن اضافه کرد.

پارامتر binary چیست ؟

سیستم عامل های متفاوت برای ذخیره کردن کاراکتر newl line یعنی \n از روش های متفاوتی استفاده می کنند مثلا ویندوز r\n\ یا لینوکس \n.

َزمانی که از پارامتر باینری استفاده نشود  c++ بصورت خودکار  مثلا برای ویندوز تبدیل \n به r\n\ را انجام می دهد ولی وقتی که فایل در حالت باینری باز شود این گونه تبدیل ها انجام نمیشود .

 

مثال :

    fstream file("test.txt",ios::out|ios::trunc);
    file.open ("test.txt" );// == file.open ("test.txt", ios::in | ios::out );
    file.open ("test.txt", ios::in );
    file.open ("test.bin", ios::in |ios::binary);
    file.open ("test.bin", ios::out | ios::ate |ios::binary );
    file.open ("test.txt", ios::out |ios::trunc );  
    ofstream file ("a.txt",ios::app);
    ifstream file ("a.txt",ios::binary);

با وجود fstream که کار ifstream,ofstream را نیز انجام میدهد چرا ofstream,ifstream هم وجود دارند ؟

 

به 2 دلیل

  1. استفاده از ofstream,ifstream  برای زمان هایی که فقط می خواهیم فایل را بخوانیم یا فقط در فایل بنویسیم باعث کمتر شدن اشتباهات و باگ های برنامه می شود.
  2. استفاده از ifstream,ofstream باعث خواناتر شدن کد میشود.

 

سوال شده آذر 1, 1392  بوسیله ی BlueBlade (امتیاز 15,315)   15 18 89
دوباره تگ گذاری شد بهمن 22, 1392 بوسیله ی BlueBlade

4 پاسخ

+10 امتیاز
 
بهترین پاسخ

چگونه ار باز شدن فایل مطمئن شویم؟

با استفاده از فانکشن is_open مثال :

  std::fstream file;
  file.open ("test.txt");
  if (file.is_open())
  {
        //do stufs
  }
  else
  {
         std::cout << "Error opening file";
  }

 

چه زمانی لازم است که از close برای بستن فایل استفاده کنیم ؟

fstream-ofstream-ifstream در c++ زمانی که از scope خارج میشوند و destructor  شون صدا زده میشه ()close هم میشوند .

فقط وقتایی لازمه از ()close استفاده کنید که  می خواهید با آبجکت fstream ای که ساخته اید یک فایل دیگه رو باز کنید.

مثال :  کد زیر نیازی به close ندارد.

#include <fstream>
using namespace std;
int main ()
{

  while(1)//nizay be file.close() nist inja
  {
     ofstream file;
     file.open("a.txt",ios::app);
     file<<"TEXT"<<endl;
    // file.close();
  }
  return 0;
}

اطلاعات مربوط به محل ذخیره و نوشتن فایل کجا ذخیره میشوند ؟(get pointer-put pointer)

در ifstream محلی که قراره اطلاعات خونده بشن در یک پوینتر ذخیره میشن که اصطلاحا بهش get pointer میگن.

توی ofstream محلی که قراره اطلاعات نوشته بشن هم توی پوینتر ذخیره میشن که بهش put pointer میگن.

fstream چون هم توانایی نوشتن و هم خواندن رو داره هر 2 تای این پوینتر ها رو داره.

چگونه می توان محل put pointer , get pointer را فهمید ؟ 

محل put_pointer  و get_pointer داخل 2 متغیر int ذخیره میشه که با tellp  , tellgمیشه بهشون دسترسی داشت. (tellg مال get_pointer و برعکس)

مثال :  کد زیر تعداد کاراکتر های یک فایل رو نشون میده

ifstream file ("a.txt", ios::in|ios::ate);//ate mahale get pointer ro mizare akhare file
cout<<file.tellg();//tellg() mahale get pointer ro bar migardoone

چگونه می توان محل put pointer , get pointer را عوض کرد؟

با استفاده از فانکشن های seekp,seekg

این 2 فانکشن رو میشه به یکی از 2 روش زیر استفاده کرد .

روش 1

seekg ( pos);
seekp ( pos);

;که این جا pos محل مورد نظر از ابتدای فایل میباشد.

مثال : 

ifstream file("test.txt");
file.seekg(10);//be character 10 om file miravad... chon ifstream bood az seekg estefade kardim.

روش 2 :

seekg ( pos, direction );
seekp ( pos, direction );

پارامتر دوم مشخص میکنه که محل مورد نظر از ابتدا-انتها یا موقعیت فعلی محاسبه بشه .

پارامتر های ورودی میتوانند یکی از موارد زیر باشند :

  1. ios::beg : محل از ابتدا
  2. ios::cur : محل از موقعیت فعلی
  3. ios::end : محل از انتها

مثال :

file.seekg(10,ios::beg);//moadele file.seekg(10);
file.seekg(10,ios::cur);//10 khane bad az mahale feli get_pointer
file.seekp(10,ios::end);//10 khane ghabl az entehaye file

 

 

پاسخ داده شده آذر 1, 1392 بوسیله ی BlueBlade (امتیاز 15,315)   15 18 89
ویرایش شده مرداد 24, 1393 بوسیله ی BlueBlade
سلام. بابت اطلاعات جامعی که در این پست ارائه دادید ممنون. اما یک ایرادی در قسمت آخر وجود داره که مربوط به seekp و seekg است ios::beg مربوط به محل از ابتداست نه محل از موقعیت فعلی در حالی که ios::cur به معنای محل از موقعیت فعلیه.
همچنین در مثال اولی که زدید معمولا برای زمانی که فایل باز نمی شود به جای استفاده از std::cout از std::cerr استفاده می کنند. اگر چه که std::cout هم درسته.
+9 امتیاز

چگونه اطلاعات فایل را بخوانیم ؟ 

بعد از باز کردن فایل می توانید با استفاده از روش های زیر اطلاعات را بخوانید .

اگر فایل متنی باشد .

کد پایین هر کاراکتر را داخل وکتور جدا جدا ذخیره کی کند.

  ifstream file ("a.txt");
  vector<char>outputs;
  char temp;
  if(file.is_open())
    while (!file.eof())
    {
        file>>temp;
        outputs.push_back(temp);
    }

کد زیر هر کلمه را جدا جدا در وکتور  ذخیره می کند.

  ifstream file ("a.txt");
  vector<string>outputs;
  string temp;
  if(file.is_open())
    while (!file.eof()) //eof check mikone ke be akhare file residim ya na
    {
       file>> temp;
       outputs.push_back(temp);
    }

این کد هر خط را داخل وکتور جدا جدا ذخیره می کند.

ifstream file("a.txt");
vector<string> outputs;
string temp;
if(file.is_open()) 
    while (std::getline(file, temp))
    {
         outputs.push_back(temp);
    }

اگر فایل باینری باشد .

از اونجایی که روش های getline ,... برای فایل های متنی  هستن و یک سری عملیات ها برای فرمت دهی انجام میدن  که برای فایل های بانری لازم نیستن  2 تا فانکشن در  c++ مخصوص فایل های باینری ایجاد شدن.

write ( data, size );
read ( data, size );

که این جا data یک char* ه 

writeمخصوص نوشتن و read مخصوص خواندن است.

مثال :

  char *data;
  ifstream file ("test.bin", ios::in|ios::binary|ios::ate);
  if (file.is_open())
  {
    size = file.tellg();
    data= new char [size];
    file.seekg (0, ios::beg);
    file.read (data, size);
    file.close();
}

چگونه هنگام خواندن کاراکتر به کاراکتر  space را هم بخونیم ؟

با استفاده از کد زیر 

file.unsetf(ios_base::skipws);
چگونه درون فایل اطلاعات جدید بنویسیم ؟
با استفاده از اپراتور >> 
مثال :
 ofstream file( "test.txt" );
 file<<"MAtn mored nazar baraye neveshtan dar file";

برای تعیین محلی که می خواهید بنویسید میتواند از seekp استفاده کنید.

برای فایل های باینری همون جوری که توضیح دادم باید از write استفاده شود.

 

پاسخ داده شده آذر 1, 1392 بوسیله ی BlueBlade (امتیاز 15,315)   15 18 89
+9 امتیاز

پیدا کردن رشته و جایگزین کردن آن در فایل :

#include <iostream>
#include <fstream>
#include <vector>
using namespace std;
//barname kalame text ra ba newText jaygozin moikone
int main()
{
    fstream file;
    file.open("a.txt");
    if(file.is_open())
    {
         vector<string>inputs;
         while (!file.eof())
        {
            string temp;
            file>> temp;
            if(temp=="text")
            {
                temp="newText";
            }
            inputs.push_back(temp);
        }

        file.seekg(0);
        for(int i=0;i<inputs.size()-1;i++)
            file<<inputs[i]<<" ";
        file<<inputs[inputs.size()-1];
        file.close();
    }
    else
    {
        cout<<"can not open file";
    }

}

 

پاسخ داده شده آذر 3, 1392 بوسیله ی BlueBlade (امتیاز 15,315)   15 18 89
+9 امتیاز

خواندن تمام فایل بصورت یک جا :

در صورتی که می خواهید کل فایل رو بصورت یکجا بخونین میتونین از stringstream هم استفاده کنین که به مراتب سریع تر از خوندن خط به خط فایل بوسیله getline هست :

#include <iostream>
#include <fstream>
#include <sstream>

using namespace std;

int main()
{
    ifstream file("D:\\file.txt");
    string wholeFile;

    if (file.is_open())
    {
        std::stringstream buffer;
        buffer << file.rdbuf();
        wholeFile=buffer.str();
    }
    else
        cout<<"error in openening file";

    cout<<wholeFile;

    return 0 ;
}

 

پاسخ داده شده بهمن 22, 1392 بوسیله ی BlueBlade (امتیاز 15,315)   15 18 89
...