PDA

View Full Version : مشکل در خواندن فایل



killer-star
دوشنبه 30 مهر 1386, 17:10 عصر
سلام دوستان

من C++ کمی کار کردم اما C نه ... می خواستم کمی هم C یاد بگیرم به مشکلی بر خوردم ... میخوام یک فایل رو بخونم و محاسباتی روش انجام بدم ... در حقیقت این سوال ماله المپیاده ... این ورودیه :

SAMPLE INPUT (file gift1.in)

5
dave
laura
owen
vick
amr
dave
200 3
laura
owen
vick
owen
500 1
dave
amr
150 2
vick
owen
laura
0 2
amr
vick
vick
0 0

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

۱-چجوری اسم ها رو بزارم تو یک آرایه؟
۲-چجوری یک آرایه برای حساب ها بسازم ؟ چون ممکنه یکی پولش ۱۰۰۰ و دیگری ۰ باشه ... چجوری اینا رو جدا از هم بزارم ؟

ممنون

emad_67
دوشنبه 30 مهر 1386, 17:40 عصر
اگه ترتیب قرار گیری اطلاعات توی فایل به همین شکلی باشه که نوشتی میتونی با خوندن خط اول از اون تعداد نفرات رو به دست بیاری. به نظرم بهتره 2 تا آرایه به تعداد خونه ایی که از ورودی به دست میاری بسازی. یکی برای اسم ها و یکی برای حساب ها البته آرایه مربوط به اسم ها رو از نوع اشاره گر بساز. خونه های آرایه رو معادل هم در نظر بگیر یعنی مثلا اگه خونه 0ام یه اسمی توش قرار داره در خونه 0ام از آرایه عددی هم مقدار پول همون فرد قرار داشته باشه.
بعدش طبق هر الگوریتمی که تعریف شده میتونی به خونه های اون آرایه مقداری رو اضافه یا کم کنی. البته منم مثل خودت با c کار نکردم ولی اگه اگه با c++ خواستی بگو تا نحوه خوندن فایل ها و نحوه قرار دادنشون توی آرایه رو بهت بگم.

killer-star
دوشنبه 30 مهر 1386, 20:11 عصر
اگه ترتیب قرار گیری اطلاعات توی فایل به همین شکلی باشه که نوشتی میتونی با خوندن خط اول از اون تعداد نفرات رو به دست بیاری. به نظرم بهتره 2 تا آرایه به تعداد خونه ایی که از ورودی به دست میاری بسازی. یکی برای اسم ها و یکی برای حساب ها البته آرایه مربوط به اسم ها رو از نوع اشاره گر بساز. خونه های آرایه رو معادل هم در نظر بگیر یعنی مثلا اگه خونه 0ام یه اسمی توش قرار داره در خونه 0ام از آرایه عددی هم مقدار پول همون فرد قرار داشته باشه.
بعدش طبق هر الگوریتمی که تعریف شده میتونی به خونه های اون آرایه مقداری رو اضافه یا کم کنی. البته منم مثل خودت با c کار نکردم ولی اگه اگه با c++ خواستی بگو تا نحوه خوندن فایل ها و نحوه قرار دادنشون توی آرایه رو بهت بگم.

بگی ممنون میشم :چشمک:

emad_67
دوشنبه 30 مهر 1386, 20:37 عصر
فکر میکنم فایلت باید به صورت txt باشه، به همین خاطر خوندن این نوع فایل ها رو میگم
فرض کن یه فایل متنی داریم به نام name.txt
این کد رو ببین:


#include<iostream.h>
#include<fstream.h>
void main()
{
ifstream in("name.txt",ios::in);
char *s;
while(!in.eof())
{
s=new char[20];
in>>s;
cout<<s<<endl;
}
}

برای کار با فایل ها باید از هدر fstream.h استفاده کنیم. برای این کار ابتدا یه شی ایی رو از کلاس ifstream (کلاس ورودی فایل) میسازیم (در اینجا به نام in) و در حین ساخت اون نام فایلی که باید در برنامه باز بشه رو بهش میدیم


fstream in("name.txt",ios::in);

ios::in و مشخص میکنه که فایل باید به صورت ورودی باز بشه یعنی برای خوانده شدن در برنامه.
حلقه while هم تا جایی که به انتهای فایل نرسیدیم تکرار میشه و کلمه به کلمه فایل رو می خونه و چاپ میکنه.
تابع eof() یه مقدار boolean رو بر میگردونه وقتی که به انتهای فایل برسیم مقدار 1 رو بر میگردونه. از عملگر << هم میتونی مثل cin برای خواندن از فایل استفاده کنی.
اگه اینو درست متوجه شده باشی فایل خودت رو هم مثل همین میتونی بخونی. البته در مورد برنامه خودت باید در حین خوندن کنترل کنی ببینی که رشته خونده شده عددی هست یا نه که بتونی اونو در آرایه مورد نظر قرار بدی.

killer-star
سه شنبه 01 آبان 1386, 14:56 عصر
فکر میکنم فایلت باید به صورت txt باشه، به همین خاطر خوندن این نوع فایل ها رو میگم
فرض کن یه فایل متنی داریم به نام name.txt
این کد رو ببین:


#include<iostream.h>
#include<fstream.h>
void main()
{
ifstream in("name.txt",ios::in);
char *s;
while(!in.eof())
{
s=new char[20];
in>>s;
cout<<s<<endl;
}
}
برای کار با فایل ها باید از هدر fstream.h استفاده کنیم. برای این کار ابتدا یه شی ایی رو از کلاس ifstream (کلاس ورودی فایل) میسازیم (در اینجا به نام in) و در حین ساخت اون نام فایلی که باید در برنامه باز بشه رو بهش میدیم


fstream in("name.txt",ios::in);
ios::in و مشخص میکنه که فایل باید به صورت ورودی باز بشه یعنی برای خوانده شدن در برنامه.
حلقه while هم تا جایی که به انتهای فایل نرسیدیم تکرار میشه و کلمه به کلمه فایل رو می خونه و چاپ میکنه.
تابع eof() یه مقدار boolean رو بر میگردونه وقتی که به انتهای فایل برسیم مقدار 1 رو بر میگردونه. از عملگر << هم میتونی مثل cin برای خواندن از فایل استفاده کنی.
اگه اینو درست متوجه شده باشی فایل خودت رو هم مثل همین میتونی بخونی. البته در مورد برنامه خودت باید در حین خوندن کنترل کنی ببینی که رشته خونده شده عددی هست یا نه که بتونی اونو در آرایه مورد نظر قرار بدی.

سلام

ممنون

ببین از اونجا که ممکنه بین 2-10 نفر باشن من از قبل نمیتونم آرایه تعریف کنم چجوری توی برنامه آرایه بسازم مثلا اگر عدد اول برابر 5 بود بسازم t1, t2, t3,t4, t5

یک سوال دیگه و اینکه وقتی مینویسی s=new char[20]; اونوقت این s میتونه 20 تا حرف و عدد بگیره یا این که خودش میتونه 20 تا رشته بگیره ؟ ممنون

emad_67
سه شنبه 01 آبان 1386, 15:09 عصر
ببین از اونجا که ممکنه بین 2-10 نفر باشن من از قبل نمیتونم آرایه تعریف کنم چجوری توی برنامه آرایه بسازم مثلا اگر عدد اول برابر 5 بود بسازم t1, t2, t3,t4, t5

نیازی نیست از قبل آرایه رو تعریف کنی. وقتی که مثلا عدد 5 رو از فایل به دست اوردی یه آرایه dynamic ایجاد کن به این صورت:


int *a=new int[5];

این دستور آرایه ای به نام a و به طول 5 میسازه


یک سوال دیگه و اینکه وقتی مینویسی s=new char[20]; اونوقت این s میتونه 20 تا حرف و عدد بگیره یا این که خودش میتونه 20 تا رشته بگیره ؟

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

killer-star
پنج شنبه 03 آبان 1386, 15:41 عصر
اگه بتونی تو سی نشونم بدی بهتره ... یا اینکه بگی تو لینوکس چجوری از سی +‌+ استفاده کنم ...
تو سی اونجوری نمیشه آرایه ساخت ... در ضمن یکم آرایه های و اشاره گر ها رو توضیح بدی ممنون میشم

emad_67
پنج شنبه 03 آبان 1386, 16:07 عصر
والا من c کار نکردم. کلا مباحث آرایه ها و اشاره گر ها توی c و c++ فرقی نمیکن.
توی c برای تخصیص حافظه باید از دستور malloc (به جای new ) در هدر فایل stdlib.h استفاده کنی. به این صورت:


int *a;
a=(int *)malloc(2);
که این دستور میاد دو خونه از حافظه رو میگیره و آدرس ابتدای اونو در اشاره گر a قرار میده


در ضمن یکم آرایه های و اشاره گر ها رو توضیح بدی ممنون میشم
به مجموعه ای از متغیر هایی که همگی از یک نوع هستند (مثلا int و ...) و در کنار هم قرار دارن آرایه میگن که دسترسی به عناصر آرایه به صورت اندیسی انجام میشه ( [0] )


int a[10];
که این دستور به اندازه 10 تا int حافظه میگیره و برای دسترسی به هر عضو اون هم اندیس اون عضو رو باید بدی مثلا


cout<<a[2];
که عنصر سوم از آرایه a رو چاپ میکنه چون آرایه از 0 شروع میشن. مثلا در اینجا اندیس ها از 0 تا 9 هستند.
اشاره گر ها هم متغیر هایی هستند که میتونن آدرس یک متغیری رو که در حافظه قرار دارن توی خودشون نگه داره مثلا وقتی می نویسی:


int *a;
یعنی اینکه متغیری رو تعریف میکنی که میتونه به یه آدرسی تو حافظه اشاره کنه (آدرس رو در خودش نگه داره) البته چون a از نوع int تعریف شده پس این متغیر میتونه فقط آدرس متغیر هایی رو که ار نوع int تعریف شدن نگه داره. برای مثال:


int b=2;
int *a=&b;
cout<<*a;
در اینجا ابتدا یه متغیر از نوع int به نام b تعریف کردیم و در خط بعد یک متغیر اشاره گر به نوع داده int به نام a تعریف شده و در خط سوم آدرس متغیر b به a نسبت داده شده یعنی اینکه a داره به b اشاره میکنه. برای دسترسی یه عضوی که a داره به اون اشاره میکنه باید اونو به صورت a* به کار ببری. بنابراین در خط آخر مقدارمغعیر b چاپ میشه. توجه داشته باش که اگه بنویسی


cout<<a;
یه آدرس برات چاپ میشه که همون آدرس متغیر b هست.

killer-star
پنج شنبه 03 آبان 1386, 19:20 عصر
ممنون ...
1-چطوری میشه این 2 تا رو جدا کرد :
300 2


2- من تو برنامم به مشکل بر خوردم :

اول np رو بگیر
به تعدادش آرایه از نوع char
10 تا متغیر از نوع char
10 تا متغیر از نوع char اشاره گر
10 تا متغیر از نوع int
10 تا متغیر از نوع int اشاره گر

از np+1 اسم رو بخون
توی آرایه ی اسم ها جستجو کن و ببین چندمیه
(اینجا اسم رو نمیده که ! آدرس رو میده درست میگم ؟؟ )

مشکلم اینجاست ! ... بنظرم نباید این همه متغیر تعریف کنم ...
و اینکه آیا نمیشه یک آرایه ساخت که اسم هارو توش قرار بدم ...
وقتی توی یک آرایه یک اشاره گر قرار داره آدرس اشاره شده تو آرایه هست یا خود اشاره شده ؟...

ممنون

emad_67
پنج شنبه 03 آبان 1386, 19:55 عصر
1-چطوری میشه این 2 تا رو جدا کرد :
300 2

با توجه به پست دوم باید اینجوری بنویسی:


int a;
char num;
in>>num;
a=atoi(&num);
ابتدا یه متغییر از نوع char میسازیم و اولین کاراکتر از فایل رو می خونیم( به شرطی توی فایل اولی باشه، مثلا در ابتدای فایل یه space نباشه و بعد عدد). متغیر خونده شده یک کاراکتر هست برای اینکه اونو به عدد تبدیل کنی باید از atoi استفاده کنی. این دستور در هدر stdlib.h قرار داره که یک پاراکتر از نوع char * میگیره و اونو به عدد تبدیل میکنه در صورتی هم که رشته فرستاده شده عدد نباشه مقدار 0 رو بر میگردونه.
اگه نخواستی از این روش استفاده کنی میتونی اینجوری بنویسی:


int a;
char num;
in>>num;
a=(int)num-48;
در اینجا مقدار num رو به عددی که معادل کد اسکی اون هست تبدیل کردم و چون کد اسکی اعداد از 48 شروع میشه اونو از 48 کم کردم.


2- من تو برنامم به مشکل بر خوردم :

اول np رو بگیر
به تعدادش آرایه از نوع char
10 تا متغیر از نوع char
10 تا متغیر از نوع char اشاره گر
10 تا متغیر از نوع int
10 تا متغیر از نوع int اشاره گر

از np+1 اسم رو بخون
توی آرایه ی اسم ها جستجو کن و ببین چندمیه
(اینجا اسم رو نمیده که ! آدرس رو میده درست میگم ؟؟ )

مشکلم اینجاست ! ... بنظرم نباید این همه متغیر تعریف کنم ...
و اینکه آیا نمیشه یک آرایه ساخت که اسم هارو توش قرار بدم ...
اصلا نیازی به تعریف این همه متغیر نیست. شما باید یه آرایه عددی به تعداد نفراتت و یه آرایه کاراکتری از نوع اشاره گر و یه آرایه کاراتری به عنوان یه واسط که بیاد اسم ها رو از فایل بخونه و در آرایه اشاره گر قرار بده. به طور مثال یه فایل به اسم name.txt بساز و توش یه سری اسم بنویس بعد کد زیر رو اجرا کن تا عمکردش رو ببینی


#include<iostream.h>
#include<fstream.h>
void main()
{
ifstream in("name.txt",ios::in);
char *word;
char *names[10];
int i=0;
while(!in.eof())
{
word=new char[20];
in>>word;
names[i]=word;
i++;
}
for(int j=0;j<i;j++)
cout<<names[j]<<endl;

}
در واقع این برنامه هر رشته از فایل رو میخونه و آدرس اونو در یک خونه از آرایه کاراکتری یعنی names قرار میده.

وقتی توی یک آرایه یک اشاره گر قرار داره آدرس اشاره شده تو آرایه هست یا خود اشاره شده ؟...
آدرس اشاره شده توی آرایه هست.

killer-star
پنج شنبه 03 آبان 1386, 20:48 عصر
کار نمیکنه :


#include <stdio.h>
#include <stdlib.h>

main ()
{
char *word;
char *names[10];
int i=0, j=0;
FILE *fin = fopen ("gift1.in", "r");
while(!feof(fin))
{
word=(char*)malloc(20);
word = getc(fin);
names[i] = word;
i++;
}
for(j=0;j<=i;j++)
printf ("%c\n", names[j]);
fclose (fin);
}


و ارور‌ :


[root@localhost ~]# cc gift1.c -o gift1
gift1.c: In function ‘main’:
gift1.c:19: warning: assignment makes pointer from integer without a cast

emad_67
پنج شنبه 03 آبان 1386, 21:20 عصر
این خط مشکل داره


word = getc(fin);
تابع getc یه مقدار int بر میگردونه و شما میخوایین اونو بریزین تو یه متغیر اشاره گر که طبیعیه که ارور میده.
من با دستور های c آشنا نیستم. در این مورد هم نمیدونم که باید با چه دستوری یه رشته رو از فایل بخونی.
به هر حال امیدوارم یکی دیگه از بچه ها جوابتو بده.
موفق باشید.

emad_67
پنج شنبه 03 آبان 1386, 22:00 عصر
اینجا ها رو هم ببین شاید به کارت بیاد
http://barnamenevis.org/forum/showthread.php?t=71292&highlight=%D9%81%D8%A7%DB%8C%D9%84+%D9%87%D8%A7
http://barnamenevis.org/forum/showthread.php?t=70819&highlight=%D9%81%D8%A7%DB%8C%D9%84+%D9%87%D8%A7

killer-star
پنج شنبه 03 آبان 1386, 22:59 عصر
با این کد کار کرد :


char *word;
char *names[10];
int *accounts[10];
int i=0, np, *money, division, part, divz;
FILE *fin = fopen ("gift1.in", "r");
fscanf(fin, "%d", &np);
fgets(word,1,fin);

for (i=0;i<=np;i++)
{
word=(char*)malloc(14);
fgets(word,13,fin);
names[i] = word;
printf ("%d|%s", i,names[i]);
}


تا اینجاش درست ...
ببینم بقیشو میتونم بنویسم :چشمک: