PDA

Tam Sürümünü Görmek İçin : C++ Dosyadan Karakter Okumada Sorun?


eray2509
20/05/2008, 23:23
selam arkadaşlar ufak bi sorunla karşılaştım yardım ederseniz sevinirim.. yasinefe arkadaşımızın yaşadığı problemin biraz aynısı.. dosyada kayıtlı olan bilgiler içinden sayıları çekip ayrı ayrı değişkenlere atmak istiyorum ama değişkene aktarma kısmını bi türlü yapamadım yardımcı olursanız sevinirim..

dosya.txt deki veriler

12; 23; 245; 2452
13
11; 24; 5; 56;
12; 13;

programdaki yapamadığım kısım :(

char str[] ="12; 13; 145; 145; 12; 35; 35;";
char * pch;
printf ("Splitting string \"%s\" into tokens:\n",str);
pch = strtok (str,"; ");
while (pch != NULL)
{
printf ("%s\n",pch);
pch = strtok (NULL, "; ");
}

str değişkenindeki verileri dosyadan alamıyorum ve dosyadan aldığımdada dizi yada vectore aktarmak istiyorum yardımcı olursanız sevinirim

saygılarımla
EraY :sus::sus::sus::sus:


acehreli
21/05/2008, 00:06
Gosterdigin kod calisir. Dosyadan okumak icin fgets'i kullanirsan calisacaktir. Ondan sonra vector<string>'in oldugunu varsayarsak:

v.push_back(pch);

Ali

eray2509
21/05/2008, 00:13
slm ali abi :D senin cevizdeki yazılarını dikkatle okudum projemde çok katkısı oldu fakat ben burda derdimi anlatamadım :(

şimdi dosya.txt deki dosya formatı yukarda belli zaten satırların başındaki sayılar farklı şeyler devamındakiler farklı yani

23;bu sayı hasta nosu (boşluk) 234; 2134; devamındaki sayılar ilac numaraları :D
yani ben mesela şöyle düşünüyorum

dizi[satırlar][satırdaki sayılar]
yani bu dizi içine satırları atmak istiyorum

dizi[0][0] dediğimde mesela 1.satırdaki ilk sayıyı vermesini istiyorum.. şimdi fgetse bakıyorum.. cevabını bekliyorum

saygılarımla
EraY

eray2509
21/05/2008, 01:31
sanırım kimse ilgilenmicek sorunumla :(

neyse sağolun yinede

acehreli
21/05/2008, 01:38
Soru sormadin ki... :) Satiri fgets'le okumayi ogrendin... Onu strtok ile teker teker parcalamayi ogrendin. O parcalarla istedigini yapabilirsin artik. Ornegin bir vector<string>'e push_back'le ekleyebilirsin...

Sonra o parcalara [] isleciyle erisebilirsin. Ornegin vector'un ismi 'v' ise:

cout << v[0] << '\n';

Ali

yasinefe
21/05/2008, 03:44
merhabalar tekrardan ben aşağıdaki gibi bi kod buldum

#include <iostream>
using std::cout;
using std::endl;

#include <cstring> // prototype for strtok
using std::strtok;

int main()
{
char sentence[] = "This; is a sentence with 7 tokens";
char *tokenPtr;

cout << "The string to be tokenized is:\n" << sentence
<< "\n\nThe tokens are:\n\n";

// begin tokenization of sentence
tokenPtr = strtok( sentence, ";" );

// continue tokenizing sentence until tokenPtr becomes NULL
while ( tokenPtr != NULL )
{
cout << tokenPtr << '\n';
tokenPtr = strtok( NULL, " " ); // get next token
} // end while

cout << "\nAfter strtok, sentence = " << sentence << endl;
system("pause");
return 0; // indicates successful termination

ben bu kodu aşağıdaki gibi kullanmak istedim ama geçersiz ilkleme diye bi hata verdi bunu nasıl kullanabilrim:super:

vector<string> s1;
int hasta_no,ilac_no;
const int enfazla=30;
char satir[enfazla];
ifstream dosyam ("recete.txt");
while(!dosyam.eof())
{
dosyam.getline(satir,enfazla);
s1.push_back(satir);
}
char sentence[] = s1[0]; bu satırda hata veriyo:aglama: ben yukarıdaki progrmda sentence nesnesi gibi bu programda bunu nasıl kullanabilirim. bunu alırsam bunu satırı parçalamayı başaracağım yardımlarınız için çok teşekkürler

acehreli
21/05/2008, 07:32
s1[0]'in tUrU 'string&' (string referansi) oldugu icin olmuyor. string'in icerigine c_str() ile erisebilirsin ama onunle ele gecirdigin bellegi strtok ile parcalayamazsin. Onun icin once bir kopyasini alman gerekir. Soyle:

/* kopyasini al */
char * sentence = strdup(s1[0].c_str());
/* sentence'i strtok ile kullan */
/* strtok ile isin bitince strdup'un ayirdigi bellegi geri vermeyi unutma: */
free(sentence);

Ali

yasinefe
21/05/2008, 16:20
çok teşekkürler yardımlarınız için.

yasinefe
21/05/2008, 20:36
merhabalar:iih: tekrardan dediğiniz gibi yaptım ve ilk satırı parçaladım ben bu parçaların ilkini hasta no olarak almam için (tabi string int dönüşümü yaptıktan sonra) aşağıdaki gibi bi kod yazdım ama char dan char a geçersiz çevri şeklinde türünden hatalar veriyo bunu nasıl yapabilirim acaba yardımlarınız için sonsuz teşekkürler

while(!dosyam.eof())
{
dosyam.getline(satir,enfazla);
s1.push_back(satir);
}
dosyam.close();
char * sentence = strdup(s1[0].c_str());
cout<<"new: "<<sentence<<endl;
char *tokenPtr;
cout << "The string to be tokenized is:\n" << sentence
<< "\n\nThe tokens are:\n\n";

// begin tokenization of sentence
tokenPtr = strtok( sentence, ";" );

// continue tokenizing sentence until tokenPtr becomes NULL

while ( tokenPtr != NULL )
{
cout << tokenPtr << '\n';
tokenPtr = strtok( NULL, "; " ); // get next token
if(no=0)
hasta=tokenPtr;
cout<<hasta<<endl;
else
k.push_back(tokenPtr);
} // end while

cout<<k[0]<<endl;
cout << "\nAfter strtok, sentence = " << sentence << endl;

free(sentence);

acehreli
21/05/2008, 21:03
O hatayi anlamamiz icin hangi satirda oldugunu ve o nesnelerin tUrlerinin ne olduklarini bilmemiz gerekir. Hic bilmeden tahmin: 'hasta' bir yapi oldugu halde ona bir 'char*' olan 'tokenPtr'in degerini atamaya calisiyorsun. (?)

Ali

eray2509
21/05/2008, 21:06
:super:ali abi selam.. abi şimdi programı ben biraz geliştirdim dediğin gibi yapmaya çalışıyorum ama bi kısmı yapamadım :garip: şimdi abi ben dosyadakileri bi string değişkene aldım bitek strtok la parçalamam lazım ama string olduğu için beceremedim açıkcası yapmaya çalıştığım şey şu

string değişkende olan değerler
txt deki gibi

12; 34
3; 5
25;
12; 24; 45; 67;

şimdi ben satır ve sutun sayılarını ayarladım kendimce ve noktalı virgülleri sildim
şu şekile getirdim..

12 34
3 5
25
12 24 45 67

yukardaki string değişkeni parçalayıp dongü içinde diziye stringten alıp parçaladığım değeri yazmak istiyorum.

dizi[0][0]=12;
dizi[0][1]=34;
dizi[1][0]=3;
dizi[1][1]=5;
dizi[2][0]=25;
dizi[3][1]=12;
dizi[3][2]=24;
dizi[3][3]=45;
dizi[3][4]=67; :utangac:
değişken string olduğu için strtok ile parçalayamadım nasıl yapıcam lütfen ali abi yardım:kuul:

acehreli
21/05/2008, 21:32
dizi elemanlarinin int oldugun varsayarsak, string iceriklerinin int'e dOnUsturmeye calisiyorsun. Bunun icin atoi'yi kullanabilirsin (Dikkat: hata denetimi yapmaz!). s bir string ise:

int i = atoi(s.c_str());

C++ akimlarini kullanarak da o string'i once bir istringstream giris akimi yapmak icin kullanirsin; sonra da o giris akimindan int'leri teker teker cikartirsin. Bu durumda hata olup olmadigini da anlayabilirsin:


#include <sstream>
#include <string>
#include <iostream>

using namespace std;

int main()
{
const string dizgi("1 2 3 dort 5");
istringstream giris(dizgi);

while (giris) {
int sayi = 0;
giris >> sayi;

if (giris) {
cout << "sayi buldum: " << sayi << '\n';
}
}

if (!giris.eof()) {
cerr << "Giriste hata var!\n";
}
}


Ali

eray2509
22/05/2008, 01:38
ali abi teşşekkür ederim yardımın için yaptım :D
ama ufacık bi sorunum daha kaldı saatlerdir uğraşıyorum seni meşgul etmemek için yazmadım buraya belki yaparım diye ama yapamadım :(
şimdi abicim

satırlara ve sutunlara böldüm olayı
4 satır ve maksimum sutun 5 diyelim
ben iç içe for döngüsü kurdum fakat bi türlü boş olan sütunları aradan nasıl çıkarırım kuramadım yardımcı olursan sevinirim

dizi[0][0] dizi[0][1] dizi[0][2] dizi[0][3] dizi[0][4]
dizi[1][0] dizi[1][1] dizi[1][2] dizi[1][3] dizi[1][4]
dizi[2][0] dizi[2][1] dizi[2][2] dizi[2][3] dizi[1][4]
dizi[3][0] dizi[3][1] dizi[3][2] dizi[3][3] dizi[1][4]

şimdi abicim yukarda kırmızı ile yazdığım elemanlar boş olucak yani sıfır
olabilir mesela ben değerleri diziye atarken o boşlukların
yerine sıfır değeri vermek istiyorum ama bi türlü yapamıyorum :(


************************
string veriler, gecici,kalici,kalici2;
int sk=0;
while (!dosya.eof ()) // dosyanın sonuna gelinmediği sürece
{
*******************
}
FILE * pFile;
****************
int c;
****************
if (pFile==NULL) perror ("Dosya Açılamadı!!!");
else
{
do {
****************
if(c==' ') t++;
if(c==';') k++;
if (c == '\n') {
m.push_back(t); t=0; i++; n++; if(k>=p){p=k; k=0;}
//burda m vectorunde her bir satırda kaç sutun olduğunu ,n de
kaç satır olduğunu ve p de maksimum sutun sayısını buluyorum
}
} while (c != EOF);
***************
}
string hastadizi[n][p];
for(int i=0;i<=n;i++) //satır sayısına kadar dönsün
for(int j=0;j<=p;j++) // maksimum sutun sayısına kadar dönsün
{
string sayi = "0";
giris >> sayi;
//bu araya öle bi şart koymalıyım ki boş olan elemanların
yerine 0 değeri versin :(
hastadizi[i][j]=sayi; }:garip::garip:

acehreli
22/05/2008, 01:47
Satirda 4 tane sayi varsa eksik olanin hangisi oldugunu bilemezsin. Sondakinin eksik oldugunu varsayacaksak,

giris >> sayi;

yaptiktan sonra giris'in durumunu hep denetlemen gerekir. Eger iyi durumda degilse j'nin dOngUsunden cikman gerek:


giris >> sayi;
if (!giris) {
break;
}
// Ancak simdi sayi'yi kullanabilirsin


Sonra j dongusu disindayken bir hata mi oldugunu veya akimin sonuna mi geldigine bakmalisin:


if (giris.eof()) {
// satir sonundayim; simdi j'nin degerini kullanarak kac tane eksik oldugunu anlayabilirim
} else {
// Giriste hata var!
}


Ali

acehreli
22/05/2008, 01:50
Benim soyledigimin calisabilmesi icin 'giris'in her seferde tek bir satiri tutmasi gerekir (butun dosyayi degil). Yoksa eof() satir sonunu degil, butun dosya sonunu soyler.

Ali

eray2509
22/05/2008, 01:53
ali abi süpersin :super: ne diyeyim daha ben (bu arada abi diyorum umarım kızmıyosundur :D)

gönülden teşekkür ederim çok saol kalite belli oldu başka lafa gerek yok..

teşekkürler

saygılarımla

EraY

not: deniyorum şuan abicim :D

eray2509
22/05/2008, 02:00
abi bu arada aradaki elemanlar değil sondan elemanlar eksik dediğini yapmaya çalışıyorum saol tekrar

yasinefe
22/05/2008, 02:05
iyi geceler yeniden ben :garip: aşağıdaki gibi bi kodla ben bu değişkenin ilk (; ) olan yerine kadarki değişkeni alıp kullanabiliyorum hatta bunu integer bi sayıya bile cevirdim ama bi türlü 4 3 345 alamıyorum:aglama: dolayısıylada kullanamıyorum bunu nasıl yapabilirim? yardımlarınızı bekliyorum çok teşekkürler

char sentence[] = "1234; 4; 3; 345";
char *tokenPtr;

cout << "The string to be tokenized is:\n" << sentence
<< "\n\nThe tokens are:\n\n";

// begin tokenization of sentence
tokenPtr = strtok( sentence, ";" );

// continue tokenizing sentence until tokenPtr becomes NULL
while ( tokenPtr != NULL )
{
cout << tokenPtr << '\n';
tokenPtr = strtok( NULL, "; " ); // get next token
} // end while

cout << "\nAfter strtok, sentence = " << sentence << endl;
system("pause");
return 0;

acehreli
22/05/2008, 02:25
yasinefe, "1234; 4; 3; 345" gibi dizgilerin aslinda sabit olduklarini ve degistirilemediklerini konustuk. strtok parcalarken ayraclarin yerine '\0' karakterlerini yerlestiremez.

Ya degistirilebilen bir dizgi kullan, ya da o sabit dizgiden strdup'u kullanarak alacagin kopyanin ustunde calis.

Ali

yasinefe
24/05/2008, 02:52
iyi geceler kolay gelsin benim programda int bir sayı yerine harf girildiğinde program sonsuz döngüye giriyor
bunu nasıl önleyebilirim cin.good(); diye bişey varmış bu nasıl kullanılıyo ben onla ilgili bişey bulamadım
yardımlarınızı bekliyorum çok teşekkürler

quasimodo
24/05/2008, 03:35
int sayi = 0;
do {
std::cin >> sayi ;
bool bad = std::cin.fail();

if( bad ) {
std::cout << "tamsayi girin \n";
std::cin.clear();
std::cin.ignore (std::numeric_limits<int>::max(),'\ n');
} while(bad)