3 سال پیش / خواندن دقیقه

مدیریت فایل ها در برنامه نویسی C به مثال کاربردی

 مدیریت فایل ها در برنامه نویسی C به مثال کاربردی

در این آموزش با مدیریت فایل در زبان C آشنا خواهید شد و کار با توابع ورودی و خروجی (I/O) استاندارد مانند ()fprintf() fscanf() ، fread()، fwrite()، fseek و … را با کمک مثال های مختلف یاد خواهید گرفت.

یک فایل یک نگهدارنده در دستگاه های ذخیره سازی سیستم برای ذخیره داده می باشد.

چرا به فایل ها نیاز داریم؟

  • با تمام شدن اجرای برنامه، همه داده ها از بین می روند. ذخیره در فایل، اطلاعات شما را حفظ می کند حتی اگر برنامه تمام شده باشد.
  • اگر باید داده های زیادی را وارد برنامه کنید، زمان زیادی طول خواهد کشید. اما اگر یک فایل شامل همه داده ها داشته باشید، می توانید به راحتی با چند دستور به محتوای فایل دسترسی پیدا کنید.
  • می توانید داده های خود را به آسانی و بدون تغییر از یک سیستم به سیستم دیگری منتقل کنید.

انواع فایل ها

دو نوع فایل در زبان C وجود دارد:



 

  • فایل های متنی
  • فایل های باینری

۱- فایل های متنی

فایل های متنی فایل های معمولی با پسوند .txt هستند که با استفاده از ویرایشگرهای متنی ساده مانند Notepad به راحتی می توانید آنها را ایجاد کنید.

این فایل ها داده ها را به صورت متن ساده ذخیره می کنند و به سادگی قابل ویرایش یا حذف هستند.

کار با این فایل ها راحت است و تلاش زیادی نمی خواهد و همچنین به راحتی قابل خواندن هستند. از طرف دیگر امنیت کمتری دارند و فضای ذخیره سازی بیشتری استفاده می کنند.

۲- فایل های باینری

بیشتر فایل های باینری یا دودویی با پسوند.bin  در سیستم ذخیره می شوند. این فایل ها به جای ذخیره داده ها به صورت متن ساده، آنها را به صورت باینری (۰ و ۱) ذخیره می کنند.

فایل های باینری داده ها بیشتری را می توانند در خود جای دهند اما به راحتی قابل خواندن نیستند. نسبت به فایل های متنی امنیت بیشتری دارند.

عملیات فایل در C

در زبان C می توانید چهار عملیات اصلی روی فایل های متنی و باینری انجام دهید:

۱- ایجاد یک فایل جدید

۲- باز کردن فایل موجود

۳- بستن فایل

۴- خواندن و نوشتن اطلاعات در یک فایل

کار با فایل ها

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

FILE *fptr;

باز کردن فایل- برای ایجاد و ویرایش

با استفاده از تابع ()fopen می توانید یک فایل را باز کنید، این تابع در فایل هدر stdio.h تعریف شده است.

شیوه باز کردن یک فایل در ورودی/ خروجی استاندارد:

ptr = fopen(“اسم فایل”,”حالت”);

مثال

fopen(“E:\\cprogram\\newprogram.txt”,”w”);
fopen(“E:\\cprogram\\oldprogram.bin”,”rb”);
  • فرض کنید فایل newprogram.txt در E:\cprogram وجود ندارد. تابع اول، یک فایل جدید به نام newprogram.txt می سازد و آن را براساس حالت “w” برای نوشتن باز می کند.

در حالت نوشتن امکان ایجاد و ویرایش(رونویسی) محتوای فایل وجود دارد.

  • حالا فرض کنید در تابع دوم، فایل باینری oldprogram.bin در E:\cprogram وجود دارد. تابع فایل موجود را برای خواندن در حالت باینری ‘rb’ باز می کند.

حالت خواندن فقط امکان خواندن فایل را فراهم می کند و نمی توانید در فایل بنویسید.

حالت های باز کردن فایل در ورودی/ خروجی استاندارد
وجود یا عدم وجود فایل معنی حالت حالت
اگر فایل وجود نداشته باشد، تابع ()fopen مقدار NULL را برمی گرداند. باز کردن فایل متنی برای خواندن r
اگر فایل وجود نداشته باشد، تابع ()fopen مقدار NULL را برمی گرداند. باز کردن فایل باینری برای خواندن rb
اگر فایل وجود داشته باشد، محتوای آن رونویسی می شود. اگر فایل وجود نداشته باشد، آن را ایجاد می کند. باز کردن فایل متنی برای نوشتن w
اگر فایل وجود داشته باشد، محتوای آن رونویسی می شود. اگر فایل وجود نداشته باشد، آن را ایجاد می کند. باز کردن فایل باینری برای نوشتن wb
اگر فایل وجود نداشته باشد، آن را ایجاد می کند. باز کردن فایل متنی برای پیوست و ضمیمه داده ها به انتهای فایل a
اگر فایل وجود نداشته باشد، آن را ایجاد می کند. باز کردن فایل باینری برای پیوست و ضمیمه داده ها به انتهای فایل ab
اگر فایل وجود نداشته باشد، تابع ()fopen مقدار NULL را برمی گرداند. باز کردن فایل متنی برای خواندن و نوشتن r+
اگر فایل وجود نداشته باشد، تابع ()fopen مقدار NULL را برمی گرداند. باز کردن فایل باینری برای خواندن و نوشتن rb+
اگر فایل وجود داشته باشد، محتوای آن رونویسی می شود. اگر فایل وجود نداشته باشد، آن را ایجاد می کند. باز کردن فایل متنی برای خواندن و نوشتن w+
اگر فایل وجود داشته باشد، محتوای آن رونویسی می شود. اگر فایل وجود نداشته باشد، آن را ایجاد می کند. باز کردن فایل باینری برای خواندن و نوشتن wb+
اگر فایل وجود نداشته باشد، آن را ایجاد می کند. باز کردن فایل متنی برای خواندن و پیوست داده ها a+
اگر فایل وجود نداشته باشد، آن را ایجاد می کند. باز کردن فایل باینری برای خواندن و پیوست داده ها ab+

بستن فایل

فایل (متنی و دودویی) بعد از خواندن یا نوشتن باید بسته شود، برای بستن فایل از تابع ()fclose استفاده می شود

fclose(fptr);

fptr اشاره گر فایلی است که بسته می شود.

خواندن و نوشتن فایل متنی

برای خواندن و نوشتن در یک فایل متنی از توابع ()fprintf و ()fscanf استفاده می کنیم. این توابع نسخه ()printf و ()scanf برای فایل هستند. تنها تفاوتشان این است که ()fprintf و ()fscanf نیاز به یک اشاره گر به ساختار FILE دارند.

مثال ۱: نوشتن در یک فایل متنی

#include <stdio.h>
#include <stdlib.h>
int main()
{
int num;
FILE *fptr;
// از یک مکان مناسب استفاده کنید MacOS یا Linuxدر
fptr = fopen(“C:\\program.txt”,”w”);
if(fptr == NULL)
{
printf(“Error!”);
exit(1);
}
printf(“Enter num: “);
scanf(“%d”,&num);
fprintf(fptr,”%d”,num);
fclose(fptr);
return 0;
}

در این برنامه یک عدد از کاربر گرفته شده سپس در فایل program.txt ذخیره می شود. پس از کامپایل و اجرای این برنامه یک فایل متنی با نام program.txt در درایو C سیستم شما ساخته شده که می توانید عدد صحیح وارد شده را در آن مشاهده کنید.

مثال ۲: خواندن از یک فایل متنی

#include <stdio.h>
#include <stdlib.h>
int main()
{
int num;
FILE *fptr;
if ((fptr = fopen(“C:\\program.txt”,”r”)) == NULL){
printf(“Error! opening file”);
// برگرداند، از برنامه خارج می شود NULL اگر اشاره گرفایل
exit(1);
}
fscanf(fptr,”%d”, &num);
printf(“Value of n=%d”, num);
fclose(fptr);
return 0;
}

این برنامه عدد صحیح موجود در فایل program.txt را می خواند و آن بر روی صفحه نمایش می دهد. اگر فایل در مثال ۱ با موفقیت ایجاد شده باشد، این برنامه عدد صحیح وارد شده را نمایش داده می شود اما اگر فایل وجود نداشته باشد، اجرای برنامه به اتمام می رسد.

توابع دیگر مانند ()fgetchar()،  fputc و … را می توان به روش مشابه استفاده کرد.

خواندن و نوشتن فایل باینری

توابع ()fread و ()fwrite به ترتیب برای خواندن و نوشتن در فایل های باینری استفاده می شوند.

نوشتن در یک فایل باینری

برای نوشتن در یک فایل باینری باید از تابع ()fwrite استفاده می شود. این تابع چهار آرگومان دارد:

fwrite(addressData, sizeData, numbersData, pointerToFile);

۱- addressData: آدرس داده ها

۲- sizeData: اندازه داده ها

۳- numbersData: تعداد نوع داده

۴- pointerToFile: اشاره گر فایل

مثال ۳: نوشتن در یک فایل باینری با استفاده از تابع ()fwrite

#include <stdio.h>
#include <stdlib.h>
struct threeNum
{
int n1, n2, n3;
};
int main()
{
int n;
struct threeNum num;
FILE *fptr;
if ((fptr = fopen(“C:\\program.bin”,”wb”)) == NULL){
printf(“Error! opening file”);
// برگرداند، از برنامه خارج می شود NULL اگر اشاره گرفایل مقدار
exit(1);
}
for(n = 1; n < 5; ++n)
{
num.n1 = n;
num.n2 = 5*n;
num.n3 = 5*n + 1;
fwrite(&num, sizeof(struct threeNum), 1, fptr);
}
fclose(fptr);
return 0;
}

در این برنامه، یک فایل جدید با نام program.bin در درایو C ساخته می شود.

متغیر num از نوع ساختار threeNum با سه عدد n1، n2 و n3 در تابع main ایجاد شده است.

در داخل حلقه for با استفاده از ()fwrite، مقادیر در فایل ذخیره می شوند. پارامتر اول تابع، آدرس متغیر num و پارامتر دوم آن اندازه ساختار threeNum می باشد.

به دلیل اینکه در هر بار نوشتن فقط یک نمونه از num در فایل را نوشته می شود، در نتیجه مقدار پارامتر سوم برابر با ۱ است. آخرین پارامتر *fptr نیز اشاره گر به فایلی است که داده ها در آن ذخیره می شوند.

در انتهای برنامه، فایل بسته می شود.

خواندن از فایل باینری

تابع ()fread نیز مانند تابع fwrite()، ۴ آرگومان دارد.

fread(addressData, sizeData, numbersData, pointerToFile);

مثال ۴: خواندن یک فایل باینری با استفاده از ()fread

#include <stdio.h>
#include <stdlib.h>
struct threeNum
{
int n1, n2, n3;
};
int main()
{
int n;
struct threeNum num;
FILE *fptr;
if ((fptr = fopen(“C:\\program.bin”,”rb”)) == NULL){
printf(“Error! opening file”);
// برگرداند، از برنامه خارج می شود NULL اگر اشاره گر فایل مقدار
exit(1);
}
for(n = 1; n < 5; ++n)
{
fread(&num, sizeof(struct threeNum), 1, fptr);
printf(“n1: %d\tn2: %d\tn3: %d”, num.n1, num.n2, num.n3);
}
fclose(fptr);
return 0;
}

در این برنامه، فایل قبلی program.bin باز شده و رکوردها در حلقه، یکی یکی خوانده می شوند. به زبان ساده، یک رکورد (از ساختار threeNum) به تعداد یک ساختار از threeNum از فایل اشاره گر *fptr خوانده و در متغیر num ذخیره می شود. (همان رکوردی که در مثال ۳ در فایل نوشته شده است.)

دریافت داده با استفاده از ()fseek

اگر رکوردهای زیادی در داخل فایل وجود داشته باشد و نیاز به یک رکورد در یک موقعیت خاص دارید، برای دسترسی به آن باید تمام رکوردهای قبل از آن را بخوانید.

با این کار حافظه و زمان زیادی تلف می شود. استفاده از تابع ()fseek دستیابی به داده های مورد نیاز را آسان تر می کند.

ساختار ()fseek

fseek(FILE * stream, long int offset, int whence);

پارامتر اول، اشاره گر فایل است، پارامتر دوم موقعیت رکوردی است که باید پیدا شود و پارامتر سوم مکان شروع را مشخص میکند.

معنی مکان شروع جستجو در فایل
از ابتدای فایل شروع می کند. SEEK_SET
از انتهای فایل شروع می کند. SEEK_END
از مکان فعلی مکان نما در فایل شروع می کند. SEEK_CUR

مثال ۵: ()fseek

#include <stdio.h>
#include <stdlib.h>
struct threeNum
{
int n1, n2, n3;
};
int main()
{
int n;
struct threeNum num;
FILE *fptr;
if ((fptr = fopen(“C:\\program.bin”,”rb”)) == NULL){
printf(“Error! opening file”);
// برگرداند، از برنامه خارج می شود NULL اگر اشاره گر فایل
exit(1);
}
// مکان نما را به انتهای فایل منتقل می کند
fseek(fptr, -sizeof(struct threeNum), SEEK_END);
for(n = 1; n < 5; ++n)
{
fread(&num, sizeof(struct threeNum), 1, fptr);
printf(“n1: %d\tn2: %d\tn3: %d\n”, num.n1, num.n2, num.n3);
fseek(fptr, -2*sizeof(struct threeNum), SEEK_CUR);
}
fclose(fptr);
return 0;
}

این برنامه از انتها به صوروت معکوس شروع به خواندن و چاپ رکوردهای فایل program.bin می کند.


شاید از نوشته‌های زیر خوشتان بیاید
نظر خود را درباره این پست بنویسید ...

منوی سریع