Tam Sürümünü Görmek İçin : pointerin gosterdiklerini file`a yazma
mrhaba arkadaslar sorumu daha iyi anlatabilmek icin ufak bir ornek uzerind soracagim
typedef struct{
char name[10];
int no;
}TAM;
typedef struct{
char name[10];
char ch;
}HARF;
typedef struct{
TAM *i;
CHAR *c;
}DENEME;
main(){
FILE *f1;
DENEME *d;
d=(DENEME *) malloc(sizeof(DENEME)*2);
int i;
d[0].i=(TAM *) malloc(sizeof(TAM)*2);
d[0].c=(HARF *) malloc(sizeof(HARF)*2);
d[1].i=(TAM *) malloc(sizeof(TAM)*2);
d[1].c=(HARF *) malloc(sizeof(HARF)*2);
/* BURAYA KADR SORUN YOK DISARIDAN GIRILEN DEGERLERII (d[0].i[0].name,d[0].i[0].no) seklinde digerlerinide okutup yazabiliyorum
*/
f1=fopen("c:\\deneme.txt","w+b");
/* AMACM file a sadece d[o] ve d[1] yazmak */
for(i=0;i<2;i++){
fwrite(d[i],sizeof(DENEME),1,f1); //bu sekilde hata veriyor HATA1
fwrite(&d[i],sizeof(DENEME),1,f1) // bu seferde file a pointer degerlerini
//yaziyor amacim daha oncede dedigim gibi d[] seklinde yazip daha sonra d[1]
//seklinde okuttugumda d[1].i[0].name seklindeki bilgilere ulasmak
// son olarak soyle birsey denedim
fwrite(d[i],sizeof(TAM)*2+sizeof(HARF)*2,1,f1)// ama bunda da hata werdi
}
}
HATA1=49 C:\Documents and Settings\SeyN\Belgelerim\deneme.cpp
cannot convert `
bu durumda yapabilecek ne kaldi bilemiyorum
simdiden yardimlariniz icin tesekkur ederim
main(){
FILE *f1;
DENEME *d;
d=(DENEME *) malloc(sizeof(DENEME)*2);
main(){
FILE *f1;
DENEME **d;
d=(DENEME **) malloc(sizeof(DENEME*)*2);
Seklinde yaparsan olacaktir yada
yada sadece DENEME* d[2]; yeterli olacaktır..
Gozume carpan ilk hata bu oldu..
Kolay Gelsin
sanirim tam analayamadim nerde hata war?
walla Enver kardesim yorum yapiyim diyorum ama neden boyle birseye basvurdun anlamadim lutfen biraz daha acarmisin
https://secure.experts-exchange.com/register.jsp?rsid=10&srid=GQQZE%2FtzVr62NDj2%2FEkTPw%3D%3D&query=how%20to%20write%20the%20datas%20that%20poin ter%20shows&redirectURL=%2Fsearch.jsp%3Fquery%3Dhow%2Bto%2Bwri te%2Bthe%2Bdatas%2Bthat%2Bpointer%2Bshows%26search Type%3Dall%26Submit.x%3D0%26Submit.y%3D0&rsid=60
bu arkadasin da benimki gibi bi sorunu war ancak hala cozum bulamadim bu safadaki coum icinde parali uyelik istiyor :(
acehreli
06/01/2006, 18:41
SeyN, ilgili veya ilgisiz gozlemlerim soyle:
1) Butunuyle buyuk harfle yazilmis adlar gelenek olarak makrolara ayrilirlar (sabitleri adlandirmak icin C++'ta da butunuyle buyuk harf kullananlar oluyor). TUr adlari icin yalnizca bas harfleri buyuk kullanmak isteyebilirsin. Yani DENEME yerine Deneme...
2) Her islevde oldugu gibi main'in de dOnUs turunun bildirilmesi gerekir: int main. DOnus tUrU olmadan kullanmana izin veren derleyiciler genellikle tarih oncesinde yazilmis kod kullandigini sandiklari icin buna izin veriyorlar.
3) Bir hata: DENEME icinde CHAR* olmasina ragmen sen onunla bir HARF'e isaret ediyorsun.
4) EnverGulMfc baska yaygin bir hatadan bahsediyor; senin durumunda ise (DENEME*)malloc kullanman dogru (gerek olmasa bile). Aslinda soyle de yapabilirdin ama deniyor oldugun icin malloc kullandigin anlasiliyor:
/* Yukarida bir yerde: */
#define TOPLAM_DENEME 2
/* ... */
DENEME d[TOPLAM_DENEME];
5) DENEME nesnelerini olusturmak icin her birisi icin ayri ayri kod yazmak buyuk eziyet. Ya 2 degil de 20 tane olsalardi? Soyle bir islev kullanabilirsin:
void DENEME_kur(DENEME * deneme, size_t adet)
{
// C'de malloc'un dOnus turune tUr donusumu uygulamaya gerek yoktur:
deneme->i = malloc(sizeof(TAM));
// Tabii simdi deneme->i'yi de duzgunce kurmak gerekir.
// Cunku o da karmasik bir tUr olabilir...
// Boyle bir islev oldugunu da varsayarsak:
TAM_kur(deneme->i);
deneme->c = malloc(sizeof(HARF));
// Ayni sekilde:
HARF_kur(deneme->c);
}
6) Gercek hatan su: Dosyaya sizeof(DENEME) kadar bayt yaziyorsun ve o kadarcik yere bekledigin butun bilgininin sigacagini umuyorsun. sizeof(DENEME)'nin ne kadar oldugunu yazdirip bakmak isteyebilirsin :)
7) Yukaridaki maddeyi uygun bir sekilde cozmek icin soyle islevler kullanman cok iyi olacak:
void TAM_yazdir(FILE * akim, const TAM * tam)
{
// Ornegin:
fprintf(akim, "%s\n", tam->name);
fprintf(akim, "%d\n", tam->no);
}
void HARF_yazdir(FILE * akim, const HARF * harf)
{
/* ... */
}
void DENEME_yazdir(FILE * akim, const DENEME * deneme)
{
/* Bu islev yukaridaki ikisini kullanacak... */
}
// Bunlarin benzeri olarak bir de _oku karsiliklarini yazarsan isin tamamdir...
Buradaki en onemli konu, butun isi kucuk alt islere bolup oyle cozmek... Ancak o alt islerin dogru olarak calistiklarindan emin olduktan sonra daha ust islere gecebilirsin.
Ali
Ya arkadasım sanırım ben yanlis anlamısım..
Ilk gonderdigimi gormezden gel...
Bak bakalım yapmak istedigin bu mu??? Ali Beyin ki kadar akademik olmadı ama :)
Sevgiler...
#include <stdio.h>
#include <stdlib.h>
typedef struct{
char name[10];
int no;
}TAM;
typedef struct{
char name[10];
char ch;
}HARF;
typedef struct{
TAM *i;
HARF *c;
}DENEME;
int main()
{
int m,n;
FILE *f1;
DENEME *d;
d=(DENEME *)malloc(sizeof(DENEME)*2);
if(!d) return -1;
d[0].i=(TAM *) malloc(sizeof(TAM)*2);
d[0].c=(HARF *) malloc(sizeof(HARF)*2);
d[1].i=(TAM *) malloc(sizeof(TAM)*2);
d[1].c=(HARF *) malloc(sizeof(HARF)*2);
//Aklımca veri giriyorum.. :)
for(m=0;m<2;m++)//2 tane d icin
{
for(n=0;n<2;n++)//iki tane HARF ve TAM icin
{
d[m].c[n].ch=65+m+n;
sprintf(d[m].c[n].name,"%d,%d.Harf",m,n);
d[m].i[n].no=65+m+n;
sprintf(d[m].i[n].name,"%d,%d.Sayi",m,n);
}
}
//Dosyaya yazma islemi
f1=fopen("c:\\deneme.txt","w+b");
for(m=0;m<2;m++)
{
fwrite(d[m].c,sizeof(HARF),2,f1);
fwrite(d[m].i,sizeof(TAM) ,2,f1);
}
/*Boylede olabilir...
//Dosyaya yazma islemi
f1=fopen("c:\\deneme.txt","w+b");
for(m=0;m<2;m++)
{
for(n=0;n<2;n++)
{
fwrite(&d[m].c[n],sizeof(HARF),1,f1);
fwrite(&d[m].i[n],sizeof(TAM) ,1,f1);
}
}
*/
return 0;
}
Sewgili ali ve enver ikiniz e de ilginiz icin tesekkur ederim
soylediginiz gibi (yazdiginiz gibi) dosyaya kaydedip istedigim gibi yapabiliyorum islemlerimi kisitli bir zmanim kaldigi icin de sanirim yine boyle yapacagim
ancak eger
6) Gercek hatan su: Dosyaya sizeof(DENEME) kadar bayt yaziyorsun ve o kadarcik yere bekledigin butun bilgininin sigacagini umuyorsun. sizeof(DENEME)'nin ne kadar oldugunu yazdirip bakmak isteyebilirsin
de bahsettigi gibi bisey yapabiliyo olsaydim algoritmam icin cok buyuk bir kolaylik olacakti cok daha moduler yazabilirdim
soyle ornek vereyimm
AD NO TEL
a--1--34
b--2--35
seklinde bitablo dusunun Deneme bir HARF 2 tane TAM dan olusuyor
eger ilk tavsiyedeki gibi once ad sutununu sonra no sutununu sonra tel sutunun kaydedersek daha osnra herhangi bir sort isleminde weya delete isleminde diyelim tel 35 olan kayiti sil gibi once tel bulogunu bulucaz sonra 35 bulucaz sonra 35 kacinci eleman oldugunu bulucaz sonra no blogundaki i elemainini degerini silecez sonra ad blogunu bul sonra ayni sekilde i indexi sil
veya butun bilgileri yine bi d[] dizisine alicaz sonra karsilastirip bulup silicez
we silicez derken diyelim 2. eleman silindi 3456. elamnlari sikistiracaz yukaridaki soledigim iki ornek icinde gecerli
d[1].tam[1].no seklinde kaydedersek is daha da karmasiklasacakk
ancak dusunun dosyaya d[1],d[2] seklinde yazidimizi teker teker her elamni okur nosu 35 olani bulurduk sonra direk ustundekileri bir satir islemle (blok seklinde yazarak ) sikistirirdik
haksizmiyim
gerci artik bi sekilde yetistirmem lazim projeyi ben sizinde werdiginiz ilk ornege biraz benzer isimi birazdaha kolaylastiracak algoritmala basladim
yardimlariniz icin tesekkur ederim ama aklinizin bi ucunda olsun boyle birsey yapilabilirmi diye?
iyi gunler
acehreli
08/01/2006, 19:50
SeyN, soylediklerinin hemen hemen tumu, dosya uzerinde sanki bellekmis gibi calisilabildigini varsaydigini dusunduruyor. Sen zaten butun islemleri bellekte yapacagin icin, dosyaya hangi duzende kaydettiginin hicbir onemi yoktur. Bakiniz XML...
[Not: Aslinda dosya uzerinde sanki bellekmis gibi dogrudan oynama yapilabiliyor. Bunun icin eger varsa isletim sisteminin "memory mapped file" olanagindan yararlanabilirsin.]
Eger kullandigin veri yapisi diziyse, evet, silinenden sonrakileri kaydiracaksin; C++'in std::vector'u de boyle calisir. Eger bunu istemiyorsan ya daha karmasik bir yontem uygulayacaksin (ornegin silinenleri gercekten silmek yerine, "silindi" diye isaretlemek), ya da baska bir veri yapisi kullanacaksin (ornegin bagli liste.)
Sen "dusunun dosyaya d[1],d[2] seklinde yazidimizi" derken sanki ben oyle dememisim gibi soyluyorsun. Benim DENEME_yazdir islevim zaten tek bir DENEME yazdiriyor iste. Boylece DENEME yazdiran kapsam icinde DENEME'nin uyelerinin ne olduklarini bilmeden tek bir DENEME yazdiriyorsun.
DENEME'nin okunma isini de baska bir isleve verirsen isin cok kolaylasir. "_oku karsiliklari" dedigimde bunu kasdetmistim. Yani DENEME_oku diye bir islevin olacak ve sen okumak icin onu kullanacaksin. Iste bu noktada senin programinin DENEME'lerin nasil yazilip okunduklarindan hicbir haberi yok. Super! :) Sen istersen (ve eger calisacaksa) o islevler icinde fwrite ve fread kullanir ve sizeof(DENEME) kadar bilgiyle ugrasabilirsin.
Ama eger printf("%d", sizeof(DENEME)) yaparsan, DENEME'nin kendisinin o bilgileri tasimayacak kadar kucuk oldugunu goreceksin. (Umarim bunu yapmissindir; cunku yukarida soylemistim... Yoksa bir seyler yazip da arkadaslar uygulamayinca cok heves kirici oluyor :( )
Mutlaka sizeof(DENEME) kadar yazdirmak istiyorsan, butun bilginin bir DENEME icine sigmasini saglaman gerekiyor:
#define TOPLAM_TAM 2
#define TOPLAM_HARF 2
/* ... */
typedef struct
{
TAM i[TOPLAM_TAM];
HARF c[TOPLAM_HARF];
} DENEME;
sizeof(DENEME)'nin ne kadar oldugunu lutfen bir de simdi yazdir.
Sen oyle yapmadigin icin, gosterge kullanmanin getirdigi esnekliklere gerek duyuldugunu varsaymisiz... Eger gercekten o dizilerin boylarinin 2 tane olduklari bastan biliniyorsa hic malloc kullanmaya gerek yok...
Ali
Forum Yazılımı : vBulletin v3.7.3, Copyright ©2000-2008, Jelsoft Enterprises Ltd.