PDA

View Full Version : سوال: تبدیل نوع داده در fread



عالیه.م
جمعه 05 اسفند 1390, 13:45 عصر
سلام...من یه فایل دارم که توش یه سری اطلاعات (ولی نه از یه نوع) ذخیره شده. حالا این فایل رو با fopen باز کردم و با دستور fread به اندازه یک struct از فایل رو خوندم. مبنای بعضی از اعداد توی فایل 16 است. من میخوام این عددا رو که خوندم با یه عدد دیگه جمع کنم و یه سری عملیات روش انجام بدم. ولی مقادیری که واسه من توی watch نشون داده میشه یه سری عدد بزرگ و گاهی منفی هست. (حتی مبنای دهی ها هم این مشکلو داره). برای اطمینان اومدم نتایج رو با فرمتی که میخواستم(%x یا %s یا %d) توی فایل چاپ کردم و دیدم درست چاپ میشه.....فهمیدم یه جایی مشکل تبدیل فرمت موقع خوندن با fread دارم. من همونطور که گفتم میخوام رو این اطلاعات عملیات انجام بدم و قصد چاپشون رو ندارم.....نمیدونم چکار کنم....ممنون میشم راهنمایی کنین

quiet_programmer
جمعه 05 اسفند 1390, 16:29 عصر
باسلام.


من یه فایل دارم که توش یه سری اطلاعات (ولی نه از یه نوع) ذخیره شده.خوب باید آدرس شروع و پایان هر فقره اطلاعات رو بدونی. مثلا اگه آدرس شروع ذخیره رو صفر در نظر بگیریم و انداه این فقره اطلاعات رو 14 در نظر بگیریم شما هنگام خوندن باید از مکان صفر به اندازه 14 بایت بخونین در صورتی که کمتر یا بیشتر از 14 بایت بخونین خوب معلومه اطلاعات خونده شده فاقد ساختار و معنی خواهند بود.(با توجه به اینکه گفتین همه اطلاعات داخل فایلتون ساختار یکسانی ندارن.)

در کل برداشتم اینه که شما نحوه نوشتن و خوندنتون یکی نیست مثلا احتمال میدم شما 14 بایت با یک ساختار مینویسین و کمتر یا بیشتر از 14 بایت موقع خوندن، از فایل میخونین. حتی امکان داره 14 بایت بخونین ولی ساختار ذخیره شده در فایل مثلا رشته باشه ولی خوندنی عدد صحیح میخونین.

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

یاحق.
موفق باشید/

عالیه.م
جمعه 05 اسفند 1390, 18:37 عصر
دوباره سلام و ممنون از پاسخ
فایلی که من دارم از یه سری داده های ماهواره ای به دست اومده و آماده به دست من داده شده و اگه بازش کنم چیز زیادی سر درنمیارم. اما فرمت اون داده ها و ترتیب ذخیرشون رو میدونم. دستور خوندن از فایل این که ساختار data_record قبلا تعریف شده و به علت بزرگی اینجا نمیذارمش.
struct data_record rec;
nitems=fread( (void*) &rec, sizeof(data_record), 1, imagefile);
با این کار توی هرکدوم از فیلدهای ساختار، یه مقداری قرار میگیره که کاملا غیر منطقیه.
اون قضیه چاپ فایل رو هم که گفتم واسه این بود که مطمئن شم داده هام رو درست از فایل خوندم. یعنی تو یه فایل جدید اطلاعات رو با فرمت مناسب چاپ میکنم و کاملا اطلاعات منطقیه. منتها من قصدم چاپ نیست و میخوام روی داده ها یه سری تغییرات انجام بدم.
printf("%d",rec.id)
این دستور دقیقا اون چیزی رو که لازم دارم چاپ میکنه و من فکر میکنم اطلاعات یه جوری کد شده و بدون فرمت تو ساختار قرار میگیرن...حالا هدف من رسیدن به این عدد و دادن تغییر روی اون هست.

quiet_programmer
شنبه 06 اسفند 1390, 20:01 عصر
با سلام.


با این کار توی هرکدوم از فیلدهای ساختار، یه مقداری قرار میگیره که کاملا غیر منطقیه. با این تفاسیر مطمئن شدم ساختار نوشته شده با ساختار خونده شده متفاوته. مثلا شما int بنویسین بعد بیاین رشته بخونین. خوب معلومه که چیزی که نوشته شده با چیزی که خونده میشه متفاوته.(فقط جنبه مثال داشت برداشت دیگه ای نشه)

راستی یه چیز دیگه که یادم رفت بگم اینه که ترتیب ساختار هم مهمه. مثلا اگه آیتم اول از ساختار داده ای با نوع int باشه و دومین آیتم با نوع float و این ساختار تو فایل نوشته بشه هنگام خوندن هم باید ساختار با آیتم اولی از نوع int و دومی هم از نوع float باشه.حله؟

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

به هر حال نظر من اینه. فکر نکنم چیز دیگه باعث یه همچین مشکلی بتونه بشه.

یاحق.
موفق باشید/

quiet_programmer
شنبه 06 اسفند 1390, 20:11 عصر
با سلام مجدد.

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

#include <iostream>
#include <conio.h>
#include <string.h>
using namespace std;

struct name{
char A[10] , B[10];
};

int main()
{
FILE *io;
name po;
int i=0;

io = fopen ("112.dat" ,"w+b");
for (int j=0 ; j<5 ; j++)
{
cout<<"First name : ";
gets (po.A);
cout<<endl;
cout<<"last name : ";
gets (po.B);
cout<<endl;
fwrite(&po, sizeof(name ),1,io) ;
}
fclose (io);

io = fopen ("112.dat" ,"rb");
while (fread(&po, sizeof(name ),1,io))
{
i++;
}
cout<<"item count"<<i;
fclose (io);
io = fopen ("112.dat" ,"rb");
while (fread(&po, sizeof(name),1,io))
{
cout<<po.A<<endl;
cout<<po.B<<endl;
}
fclose (io);
getch();
return 0 ;
}

یاحق.
موفق باشید/

عالیه.م
پنج شنبه 11 اسفند 1390, 18:53 عصر
دوباره سلام و ممنون از پاسخ. ساختاری که شما در کد فرستاده شده تعریف کردین هر دوش رشته هست. فرض کن ساختار ما فیلدهایی با انواع رشته، عدد صحیح/اعشاری داره و این فیلدها اونقدر زیاد هستن که ما قادر نیستیم دونه دونه اونها رو بخونیم و میخوایم با دستور fread کل ساختار رو بخونیم. تا اینجا مشکلی نیست و حتی اطلاعات رو هم اگر بخوایم چاپ کنیم چون فرمت مناسب رو به دستور printf میدیم هم مشکلی نیست . اما فرض کن یکی از این فیلدها معدل دانشجو باشه و ما میخوایم اون رو در ضریبی ضرب کنیم تا یه معدل وزندار به دست بیاریم. با این فرض موقعی که میخوام این معدل رو در اون ضریب ضرب کنم، یه عدد عجیب میده بیرون که میدونم مربوط به همون فرمتهاست . اما هنوز نتونستم رفع کنمش.

quiet_programmer
شنبه 13 اسفند 1390, 11:43 صبح
باسلام.


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

شما اسم اون فیلد رو میدونی؟ اگه آره بعد از خوندن توسط fread و قرار دادن اون در ساختار مربوطه میتونی به اون فیلد با استفاده از عملگر . دسترسی پیدا کنی. چیز زیاد مبهمی نداره.

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

#include <iostream>
#include <conio.h>
#include <string.h>
using namespace std;

struct Student
{
int Age;
float Avg;
float Mark[4];
};

int main()
{
FILE *io;
Student Std;
int i=0;

io = fopen ("112.dat" ,"w+b");
for (int j=0 ; j<3 ; j++)
{
cout<<"Age :";
cin>>Std.Age;
int Sum=0;
for(int i=0;i<4;i++)
{
cout<<"Enter Mark "<<i+1<<" : ";
cin>>Std.Mark[i];
Sum+=Std.Mark[i];
}
Std.Avg=Sum/4;
fwrite(&Std, sizeof(Student),1,io) ;
cout<<"Write info in File..."<<endl;
}
fclose (io);
cout<<"**************************************************"<<endl;
io = fopen ("112.dat" ,"rb");
while (fread(&Std, sizeof(Student),1,io))
{
cout<<"Age: "<<Std.Age<<endl;
for(int i=0;i<4;i++)
cout<<"Mark "<<i+1<<" : "<<Std.Mark[i]<<endl;
float Avg=Std.Avg*10;
cout<<"Avg :"<<Std.Avg<<endl;
cout<<"Avg Zard Shode dar 10: "<<Avg<<endl;
}
fclose (io);
getch();
return 0 ;
}

در هر حال: یا مشکل شماست نمیتونین خوب مشکل رو مطرح کنین یا مشکل از منه که متوجه مشکلتون نمیشم.

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

یاحق.
موفق باشید/