PDA

Tam Sürümünü Görmek İçin : c dosya işlemleri ile ilgili birkaç soru


BFS
15/01/2008, 21:25
Arkadaşlar sırasal erişimli dosya ve doğrudan erişimli dosyalama olay nedir?açıklayabilir misiniz?

Asıl sorum ise şu;
Ben ,atıyorum 20 kayıttan oluşan bir dosya yapmak istiyorum.Ve her bir kayıt da ad,sicil no,maas gibi verilerin olduğu bir yapı şeklinde olacak yani dosyaya kayıt eklerken yapı olarak kayıt yapacam.Diyelim ki tüm kayıt işlemleri yapıldı.
Sonra da o dosyadan ,kayıt numarası girerek bilgilerin ekrana yazdırılmasını istiyorum.YAni 5 numara girdiğimde 5 numaralı kaydın bilgileri ekrana yazılacak.

Biraz yapabiliyorumda sonrası gelmiyor.
fseek(),fwrite(),fread() fonksiyonlarının kullanımlarını tam olarak anlamadığım için sonunu getiremiyorum.

Kayıt için olan kodlar:

struct insan{
char isim[20];
int sicil,maas,k_no;
}man;
FILE*dosya;
dosya=fopen("file.txt","a")
int main()
{
char c='e';

if(dosya==NULL){
printf("hata");exit(1);
}

while(c!='h');
{
printf("kayit numarasini giriniz...");scanf("%d",&man.k_no);printf("\n");
printf("ismi giriniz...");scanf("%s",&man.isim);printf("\n");
printf("sicil noyu giriniz...");scanf("%d",&man.sicil);printf("\n");
printf("maas giriniz...");scanf("%d",&man.maas);printf("\n");

fseek(...........); // bu fonksiyonlar tam olarak nasıl çalışır bilmiyorum.
fwrite(...........); // onun için ne gibi parametler yazacağımdan emin değilim
printf("tekrar kayit yapilacak mi(e/h)..");c=getch();printf("\n");
}
fclose(dosya);

getch();
return 0;
}Kaydedilen bilgileri ekrana çağırma kısmını hiç yapamadım.

Zaman ayırıpda ilgilenebilecek arkadaşlara müteşekkir olurum.


quasimodo
15/01/2008, 23:11
C de global alanda fonksiyon cagiramazsin yani fopen() i main() in icinde cagirmalisin.

Sirali erisim adi ustunde dosyadaki bilgilere sirayla erisilir cunku dosya position pointera sirayla erisilir. Rastgele erisimde ise iste o isaretciyle oyniyabiliyorsun. fseek fonksiyonu bu ise yariyor. http://www.cplusplus.com/reference/clibrary/cstdio/fseek.html

BFS
15/01/2008, 23:31
fwrite() fonksyonunda 2. ve 3. parametrelerin yerleri değişirse bişey farketmiyor
mu?
fwrite(&man,sizeof(man),1,dosya);
fwrite(&man,1,sizeof(man),dosya);

yani ikiside doğru olur mu?

Çünkü nette bazı örnekler 1. si gibi bazılarındaysa 2. si gibi yapmışlar herhalde o parametreler yer değiştirince bişey değişmiyor.

quasimodo
15/01/2008, 23:37
char olusa aslinda farketmeyebilir ama digerlerinde farkeder.

BFS
16/01/2008, 00:11
Ben hala problemleri tam olarak çözemedim.

#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
struct insan{
char ad[10];
int no,yas;
};
int main()
{
char ch='e';
FILE*dosya;
dosya=fopen("C:\\Documents and Settings\\Administrator\\Desktop\\file.txt","a");
struct insan man;

if(!dosya){
printf("hata...");
}
else{
while(tolower(ch)!='h')
{
printf("AD : ");scanf("%s",man.ad);printf("\n");
printf("NO : ");scanf("%d",&man.no);printf("\n");
printf("YAS : ");scanf("%d",&man.yas);printf("\n");
fwrite(&man,sizeof(man),1,dosya);
printf("\n yeni kayit (E/H)...\n");ch=getch();
}
fclose(dosya);

}
}

bu kodlar kayıt yapıyor ama yas ve no yu integer olarak kaydetmesi gerekirken değişik bi karakter tipinde kaydediyor.
Ve ben bu dosyadan veri okuma işlemini yapmak istiyorum.Bunu ilk mesajımda da belirttiğim gibi örneğin kişinin ismini girip ekrana onun yas ve numarasını çağırma şeklinde yapabilir miyim?

quasimodo
16/01/2008, 14:49
Yapabilirsin tabi. Dedigim gibi fwrite fonksiyonununda paramerte sirasini degistirmezsen dogru bir bicimde yazacaktir dosyaya.
Okumak icinde fread i kullanabilirsin. fseek ile dosya position pointeri aradigin ismin basladigi yere getireceksin. fread ile de o byte tan istedigin kadar byte i okuyacaksin.

BFS
16/01/2008, 17:33
Teşekkurler ,deneyeceğim.

bluekid
17/01/2008, 09:45
Eğer sabit sayıda kaydın varsa
O sayıda boş kayıdı dosyaya kaydedeceksin

Dosya da istediğin kayıda ulaşmak için
int VeriNo= 5 // hangi kayıda ulaşmak istersen dikkat kayıt no 0 dan başlar
fseek(fp,VeriNo*sizeof(man), SEEK_SET);
bu işlemden sonra istersen fread ile oku istersen fwrite ile yaz

Kayıtsayın sabit değilsen Dosyanın başında bir başlık kısmı tanımlayıp kayıt sayısını kayıt büyüklüğünü falan orada tutabilirsin...

BFS
20/01/2008, 14:30
Arkadaşlar bu işi bir türlü doğru düzgün yapamadım.

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

struct insan{
char ad[10];
int no,yas;
}man;
int main()
{
char ch='e';
FILE*dosya;
dosya=fopen("C:\\Documents and Settings\\Administrator\\Desktop\\file.txt","ab");

if(!dosya){
printf("hata...");
}
else{
while(tolower(ch)!='h')
{
printf("AD : ");scanf("%s",man.ad);printf("\n");
printf("NO : ");scanf("%d",&man.no);printf("\n");
printf("YAS : ");scanf("%d",&man.yas);printf("\n");
fwrite(&man,1,sizeof(man),dosya);
printf("\n yeni kayit (E/H)...\n");ch=getch();
}
fclose(dosya);

}
}bu kodlar dosyaya kayıt yaparken sadece char değişkenlerini düzgün yyazıyorlar.yas ve no değişkenleri dosyaya değişik karakter tiplerinde yazılıyorlar.

mesela programa,ad:test,no:65487,yas:20 olarak giriyorum.Sonra dosyayı açıp bakıyorum.Dosyanın içeriği aşağdaki gibi oluyor.

test Ïÿ 

quasimodo
20/01/2008, 23:12
fwrite (&man, sizeof (man), 1, dosya);

acehreli
20/01/2008, 23:25
20 gibi bir tamsayi degerinin bilgisayarin icinde '2' ve '0' karakterleri olarak saklanmadiklarini anlamak gerek... 20 degeri, "birler ve sifirlar olarak" yazildigi icin, dosyada '2' ve '0' gibi "karakterler" bulamazsin.

man adli nesnenin basindan sonuna kadar o birleri ve sifirlari yazdirdigin icin (fwrite ve &man ile), bilgisayarin icindeki gosterimi goruyorsun.

Ben sana int icin kucuk bir program gostereyim:

#include <stdio.h>

void sayi_yaz(int sayi)
{
FILE * dosya = fopen("sayi_deneme", "wb");

fwrite(&sayi, sizeof(sayi), 1, dosya);
fclose(dosya);
}

int sayi_oku()
{
int sayi = 0;
FILE * dosya = fopen("sayi_deneme", "rb");

fread(&sayi, sizeof(sayi), 1, dosya);
fclose(dosya);

return sayi;
}

int main()
{
int sayi = 0;

sayi_yaz(42);
sayi = sayi_oku();
printf("okudum: %d\n", sayi);

return 0;
}


Ali

BFS
20/01/2008, 23:27
Öyle de denemiştim.Tekrar denedim değişen bişey yok!
dosya açılış moduyla bir ilgisi olabileceğini düşündüm onu da değiştirip denedim yine aynı şey...

Bu mesajı quasimodonun mesajına yazmıştım ,yazarken acehreli (http://forum.ceviz.net/member.php?u=326) hocamın verdiği cevap yoktu.

quasimodo
20/01/2008, 23:34
@acehreli
Dosyayi bu sekilde fonksiyon icinde acmak mi daha mantikli,
yoksa 1 kere acip islemleri yapip kapamak mi?

acehreli
20/01/2008, 23:38
Ikinci soyledigin gibisi daha iyi: Ac, islem yap, kapa.

Yazdiktan sonra dosyadan okumak icin hem fopen'a "wb" yerine okumaya ve yazmaya elverisli bir mode parametresi (ornegin "w+b") vermem, hem de okumadan once bir fseek yerlestirmem gerekecekti.

Ali

quasimodo
20/01/2008, 23:42
Understood :P

BFS
20/01/2008, 23:45
Ya arkadaşlar valla ben yapamadım olmuyor.YApmak istediğim şey belirli kayıt numaralarıyla kişileri kaydetmek ve sonra da gerektiğinde kayıt numarasını girip o kişinin bilgilerini almak bu mümkünse bana örnek kodları verebilir misiniz.onlarca kez denedim hep sorun çıkıyor

acehreli
21/01/2008, 00:36
BFS, once benim verdigim programda 'int' yazip okumak yerine, senin 'insan' tUrUnu okuyup yazmaya calis.

O isi ogrendikten sonra fseek ile istedigin kayda gitmek cok kolay: Once dosyaya 1'den fazla sayida kayit yaz. Sonra fseek'i soyle cagir:

fseek(dosya, kayit_yeri, SEEK_SET);

kayit_yeri de soyle hesaplanir:

kayit_yeri = kayit_numarasi * sizeof(struct insan);

Eger dosyada ornegin 10 kayit varsa, kayit_numarasi [0,9] araliginda olur...

Ali

BFS
21/01/2008, 00:53
Tamam uğrasacam,ilgilenen herekes teşekkurler...

quasimodo
21/01/2008, 16:39
Su kodu incele istersen Deitel in dosya icin ornegi...

#include <stdio.h>

struct clientData {
int acctNum;
char lastName[ 15 ];
char firstName[ 10 ];
double balance;
};

int enterChoice( void );
void textFile( FILE * );
void updateRecord( FILE * );
void newRecord( FILE * );
void deleteRecord( FILE * );

int main()
{
FILE *cfPtr;
int choice;

if ( ( cfPtr = fopen( "credit.dat", "r+" ) ) == NULL )
printf( "File could not be opened.\n" );
else {

while ( ( choice = enterChoice() ) != 5 ) {

switch ( choice ) {
case 1:
textFile( cfPtr );
break;
case 2:
updateRecord( cfPtr );
break;
case 3:
newRecord( cfPtr );
break;
case 4:
deleteRecord( cfPtr );
break;
}
}

fclose( cfPtr );
}

return 0;
}

void textFile( FILE *readPtr )
{
FILE *writePtr;
struct clientData client = { 0, "", "", 0.0 };

if ( ( writePtr = fopen( "accounts.txt", "w" ) ) == NULL )
printf( "File could not be opened.\n" );
else {
rewind( readPtr );
fprintf( writePtr, "%-6s%-16s%-11s%10s\n",
"Acct", "Last Name", "First Name","Balance" );

while ( !feof( readPtr ) ) {
fread( &client, sizeof( struct clientData ), 1,
readPtr );

if ( client.acctNum != 0 )
fprintf( writePtr, "%-6d%-16s%-11s%10.2f\n",
client.acctNum, client.lastName,
client.firstName, client.balance );
}

fclose( writePtr );
}

}

void updateRecord( FILE *fPtr )
{
int account;
double transaction;
struct clientData client = { 0, "", "", 0.0 };

printf( "Enter account to update ( 1 - 100 ): " );
scanf( "%d", &account );
fseek( fPtr,
( account - 1 ) * sizeof( struct clientData ),
SEEK_SET );
fread( &client, sizeof( struct clientData ), 1, fPtr );

if ( client.acctNum == 0 )
printf( "Acount #%d has no information.\n", account );
else {
printf( "%-6d%-16s%-11s%10.2f\n\n",
client.acctNum, client.lastName,
client.firstName, client.balance );
printf( "Enter charge ( + ) or payment ( - ): " );
scanf( "%lf", &transaction );
client.balance += transaction;
printf( "%-6d%-16s%-11s%10.2f\n",
client.acctNum, client.lastName,
client.firstName, client.balance );
fseek( fPtr,
( account - 1 ) * sizeof( struct clientData ),
SEEK_SET );
fwrite( &client, sizeof( struct clientData ), 1,
fPtr );
}
}

void deleteRecord( FILE *fPtr )
{
struct clientData client,
blankClient = { 0, "", "", 0 };
int accountNum;

printf( "Enter account number to "
"delete ( 1 - 100 ): " );
scanf( "%d", &accountNum );
fseek( fPtr,
( accountNum - 1 ) * sizeof( struct clientData ),
SEEK_SET );
fread( &client, sizeof( struct clientData ), 1, fPtr );

if ( client.acctNum == 0 )
printf( "Account %d does not exist.\n", accountNum );
else {
fseek( fPtr,
( accountNum - 1 ) * sizeof( struct clientData ),
SEEK_SET );
fwrite( &blankClient,
sizeof( struct clientData ), 1, fPtr );
}
}

void newRecord( FILE *fPtr )
{
struct clientData client = { 0, "", "", 0.0 };
int accountNum;
printf( "Enter new account number ( 1 - 100 ): " );
scanf( "%d", &accountNum );
fseek( fPtr,
( accountNum - 1 ) * sizeof( struct clientData ),
SEEK_SET );
fread( &client, sizeof( struct clientData ), 1, fPtr );

if ( client.acctNum != 0 )
printf( "Account #%d already contains information.\n",
client.acctNum );
else {
printf( "Enter lastname, firstname, balance\n? " );
scanf( "%s%s%lf", &client.lastName, &client.firstName,
&client.balance );
client.acctNum = accountNum;
fseek( fPtr, ( client.acctNum - 1 ) *
sizeof( struct clientData ), SEEK_SET );
fwrite( &client,
sizeof( struct clientData ), 1, fPtr );
}
}

int enterChoice( void )
{
int menuChoice;

printf( "\nEnter your choice\n"
"1 - store a formatted text file of acounts called\n"
" \"accounts.txt\" for printing\n"
"2 - update an account\n"
"3 - add a new account\n"
"4 - delete an account\n"
"5 - end program\n? " );
scanf( "%d", &menuChoice );
return menuChoice;
}

BFS
21/01/2008, 21:40
Benim seviyemdeki biri için biraz ağır gelebilir ama yine de inceleyecem.Teşekkurler quasimodo (http://forum.ceviz.net/member.php?u=56425)