Şimdi Ara

C++ / char* [] problem // Acil

Daha Fazla
Bu Konudaki Kullanıcılar: Daha Az
2 Misafir - 2 Masaüstü
5 sn
13
Cevap
0
Favori
3.234
Tıklama
Daha Fazla
İstatistik
  • Konu İstatistikleri Yükleniyor
0 oy
Öne Çıkar
Sayfa: 1
Giriş
Mesaj
  • Arkadaşlar basit bir program yazıyorum,

    kişi isimlerini ve kişi yaşlarını bir array içine alıp sonra tekrar array okunarak ekrana yazdıran çok basit bir program..

    Problem:

    ' char *isim[20] ' şeklinde bir bir karakter pointer tanımlayıp, isimleri for döngüsüyle bunun içine alıp tekrar okutmak istedim ama çalışmadı.
    daha sonra ' string isim[20] ' şeklinde tanımladım, yine for döngüsüyle isimleri çektim, bu sefer de isim girerken boşluk bıraktığımda hata verdi, daha sonra ' getline(cin,isim) ' şeklinde alayım dedim, bu sefer de birinci döngü de veriyi aldı diğer döngülerde boş geçti,

    bir türlü çözemedim,

    teşekkürler şimdiden..



    < Bu mesaj bu kişi tarafından değiştirildi fabercs -- 22 Temmuz 2010; 20:46:07 >







  • Sorunlar.

    İlk sorun char ın pointer olmasından kaynaklanıyor. isim dediğin pointer nedir ? Pointer dır. İçinde isim verisi değil, Hafızadaki yer bilgisi vardır. Sen isim in 0. öğesine Ali koyamazsın. O kendi içinde bir adres değeri taşır. Pointer konusunu birkaç kez tekrar edin, çünkü boş pointer tanımlamışsınız gibi görünüyor...

    String boşlukta elbet hata verir. Sanırım Null Terminating String denilen olayı duymadınız. String denilen şey charların birleşmesidir. Böyle ise, "/0" gördüğünde string in bittiğini düşünür. Bilin bakalım "/0" neye denk gelmektedir ? Evet gerçekten bilmeye çalışın bu soruyu, aklınıza kazınır böylece, biraz beyin fırtınası yapın. Cevabı bulunca - veya sıkılınca - aşağı bkaın.

    Evet, boşluğa denk gelmektedir. Bunun için 3. bir array yapabilirsiniz. Ya da bir çeşit Multidimensional Array yapabilirsiniz.


    getline ise yanlış kullanılmış... getline ın 1. verisi Array i, 2. verisi ise alınacak verinin boyutunu verir. Yani 10 derseniz 10 karakter çeker array den. Kullanım şöyledir;

    isimArray[256]; 

    cin.getline(isimArray, 256);


    Bu kod, isimArray den 256 karakterlik veri çeker.

    Sorularınızı cevapladım, sanırım çözersiniz gerisini. Çünkü tüm kod yazmak hem biraz üşeniyorum, hem de kendi çabalarınızla bulduğunuz herşey daha yararlıdır. Sorunuz olursa sorun, yanıtlamaya çalışırım kendi bilgilerimle. Olmazsa, ne diyebilirim ki, başarmışsınız demektir...




  • quote:

    Orijinalden alıntı: AlperXp

    Sorunlar.

    İlk sorun char ın pointer olmasından kaynaklanıyor. isim dediğin pointer nedir ? Pointer dır. İçinde isim verisi değil, Hafızadaki yer bilgisi vardır. Sen isim in 0. öğesine Ali koyamazsın. O kendi içinde bir adres değeri taşır. Pointer konusunu birkaç kez tekrar edin, çünkü boş pointer tanımlamışsınız gibi görünüyor...

    String boşlukta elbet hata verir. Sanırım Null Terminating String denilen olayı duymadınız. String denilen şey charların birleşmesidir. Böyle ise, "/0" gördüğünde string in bittiğini düşünür. Bilin bakalım "/0" neye denk gelmektedir ? Evet gerçekten bilmeye çalışın bu soruyu, aklınıza kazınır böylece, biraz beyin fırtınası yapın. Cevabı bulunca - veya sıkılınca - aşağı bkaın.

    Evet, boşluğa denk gelmektedir. Bunun için 3. bir array yapabilirsiniz. Ya da bir çeşit Multidimensional Array yapabilirsiniz.


    getline ise yanlış kullanılmış... getline ın 1. verisi Array i, 2. verisi ise alınacak verinin boyutunu verir. Yani 10 derseniz 10 karakter çeker array den. Kullanım şöyledir;

    isimArray[256]; 

    cin.getline(isimArray, 256);


    Bu kod, isimArray den 256 karakterlik veri çeker.

    Sorularınızı cevapladım, sanırım çözersiniz gerisini. Çünkü tüm kod yazmak hem biraz üşeniyorum, hem de kendi çabalarınızla bulduğunuz herşey daha yararlıdır. Sorunuz olursa sorun, yanıtlamaya çalışırım kendi bilgilerimle. Olmazsa, ne diyebilirim ki, başarmışsınız demektir...


    Mükemmel, teşekkürler...




  • Birde string nesnelerini almak için global olan getline fonksiyonu var: std::getline(istream& is, string& str );

    string isim[20];
    getline(cin, isim[0]); şeklinde kullanılabilir.

    Bu şekilde kolayca string kullanmak iyi hoştur ama önce AlperXp arkadaşın dediği gibi işaretçi (pointer) konusunu ve ilkel c-stringi anlamak lazım.

    Yazındaki en kritik nokta şu.
    char *isim[20];



    < Bu mesaj bu kişi tarafından değiştirildi Guest-BF8E9B238 -- 24 Temmuz 2010; 16:04:01 >
  • Liste için dinamik listelerden yaralanabilirsin. Yani önceden kaç adet bilgi girileceği belli değilse. vector bu iş için sana uygun olabilir. http://www.dreamincode.net/forums/topic/33631-c-vector-tutorial/
    İsimler için ise pointerle uğraşma bence zaten hali hazırda string sınıfı var. Onu kullan. Kolay gelsin.
  • arkadaşlar cevaplarınız için çok teşekkürler.. fakat, ben c'yi çok iyi bilen biri değilim ve sorun ne yazık ki devam ediyor, 2-3 gündür uğraşıyorum, gerçi çok üstüne de gitmedim ama şöyle aşağıya ben kodu yazayım;

     
    #include<iostream>
    #include<cstdlib>
    #include<cstring>
    #include<string>

    #define SIZE 100

    using namespace std;



    int main(){

    float uzunluk[SIZE];
    string caddeisim[SIZE];
    string temp;
    int i,j;
    double sum=0.0;


    cout<<"\t\t========================================="<<endl;
    cout<<"\t\t============KM FINDER Ver 1.1============"<<endl;
    cout<<"\t\t========================================="<<endl;
    cout<<"\n";
    cout<<"This program allows you to store the names of the streets you take and\n"<<endl;
    cout<<"to calculate the total length of these streets. Have a nice trip! \n\n"<<endl;
    cout<<"!!Whenver you finish your trip, you can use 'exit' quote on street name blank!!\n"<<endl;

    for(i=0; i<SIZE; i++){



    cout<<"Enter the "<<i+1<<". street name:"<<endl;

    cin>>caddeisim[i];
    //cin.getline(temp,100);

    //caddeisim[i] = temp;

    //temp.empty();



    if (caddeisim[i]=="exit"){
    j = i-1;
    break;
    }

    cout<<"Enter the "<<i+1<<". length in meters:"<<endl;
    cin>>uzunluk[i];


    j=i;


    }
    for(i=0; i<=j; i++){
    sum+= uzunluk[i];
    }
    for(i=0; i<=j; i++){

    cout<<i+1<<". Street Name:"<<caddeisim[i]<< " and Length:"<<uzunluk[i]<<" meters"<<endl;


    }

    cout<<"\nTotal length we take :"<<sum/1000<<" km"<<endl;





    system("PAUSE");
    return 0;
    }



    birinci string'in alındığı for döngüsünde benim istediğim uzunlukta ve boşlukta kabul eden bir string almam nasıl mümkün olabilir?

    kusura bakmayın, buraya yazmamak için çok uğraştım , çok araştırdım, yeniyim de.. bana çok faydalı olacak sağolun.




  • quote:

    Orijinalden alıntı: fabercs

    birinci string'in alındığı for döngüsünde benim istediğim uzunlukta ve boşlukta kabul eden bir string almam nasıl mümkün olabilir?


    Yukarıda da yazmıştım ama neyse alıştık artık cevapların okunmamasına.
     
    // temp e gerek yok

    getline(cin, caddeisim[i]);

    Ayrıca bu tam vektörlük bir iş. Vector kullanımını bir araştır.
  • yazdıklarını daha önce okudum, verdiğin linki gezdim, dediğim gibi acemiyim, vektör nedir bilmiyorum, çok basit bir işlem için oturup vektör öğrenmem mi lazım?

    ayrıca keşke kodu alıp bi çalıştırıp output'un ne olduğuna bir baksaydın, temp ile ilgili işlemler, kodda comment halinde ve senin dediğin şekilde deneyince for'un ilk döngüsünden sonra cadde ismini pas geçiyor, gerçi değişik şekillerde birçok deneme yaptım ve çoğu denenmem de problem buydu..

    garip!
  • Senin için ufak bi deneme yaptım. İlk mesajında isimleri ve yaşları isteyip sonrada ekrana yazıcam demişsin. Onu baz alarak bikaç satırlık kod yazdım. Vector şöyle kullanılıyor. Verdiğim linktede anlatıyor fakat pek faydalı değil galiba. Tekrar baktığımda farkettim.
    #include "stdafx.h" 
    #include <iostream>
    #include <string>
    #include <conio.h>
    #include <vector>

    using namespace std;

    vector<string> Isimler;
    vector<int> Yaslar;

    int main(int argc, char** argv)
    {
    char Secim;
    string AktifIsim;
    int AktifYas;

    do
    {
    cout << "Isim giriniz: ";
    cin >> AktifIsim;
    Isimler.push_back(AktifIsim);
    cout << "Yas giriniz: ";
    cin >> AktifYas;
    Yaslar.push_back(AktifYas);
    cout << "Eklemek istiyor musunuz? E/H :";
    cin >> Secim;
    cout;
    }while(Secim != 'H' && Secim != 'h');
    for(int i=0;i < Isimler.size();i++)
    {
    cout << "Isim :" << Isimler[i] << "Yas :" << Yaslar[i] << endl;
    }
    getche();
    return EXIT_SUCCESS;
    }

    Programı incelediğinde ne kadar kolay olduğunu görüceksin. Kullanıcından isim ve yaşı istiyorum sonrada ayrı ayrı listelere ekliyorum. Sonrada ekrana yazıyorum. vectorismi.size() fonksiyonu max uzunluğu veriyor. push_back'lede listenin sonundan ekliyorum. Vector kullanması hem çok kolay hemde etkin programlar yazmana olanak sağlar. Bu programıdan yararlanarak kendi istediğini yazabilirsin. Mantık yine aynı olacaktır. Denedim gayet iyi çalışıyor:
     C++ / char* [] problem // Acil



    < Bu mesaj bu kişi tarafından değiştirildi hasan1980125 -- 24 Temmuz 2010; 23:19:16 >




  • Tamam boşver vektörü. temp in comment olduğunu farketmedim pardon. Ayrıca link falan vermedim ortalık biraz karışmış.

    Bu kod çalışıyor herhangi bi sorun yok. Derleyici gcc.
     
    #include <iostream>
    #include <string>
    using namespace std;

    int main()
    {
    string isim[5];
    int i;
    for(i = 0; i < 5; i++) getline(cin, isim[i]);

    for(i = 0; i < 5; i++) cout << '\n' << isim[i];
    return 0;
    }
  • çok garip, ben de derleyici DevC++, normalde bu kod çalışmıyordu bende basite indirgeyerek yapıyordum seninki gibi,
    bilgisayarı açtım kapadım düzeldi..

    ayrıca mantık hatasını da arda arda verilen 2 örnekle keşfettim for değil while kullanmam gerekmiş.

    teşekkürler arkadaşlar, vektörleri de öğrenmeye başlayacağım bir an önce..
  • arkadaşlar while döngüsü ile tekrar kurdum yine aynı hatayı verdi, ama problemi çözdüm, döngünün sonuna "cin.get();" koyunca düzeldi. aynı problemi yaşayan arkadaşlar olması ihtimaline karşı borcum..
  • Merhaba arkadaşlar bende istenilen kodu C'de yazayım dedim.
    quote:


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

    #define NAME_SIZE 20
    #define ARRAY_SIZE 5

    typedef struct tagNameAge {
    char name[NAME_SIZE];
    int age;
    } NameAge;

    int main(int argc, char *argv[])
    {
    NameAge names[ARRAY_SIZE];
    int i;

    for (i = 0; i < ARRAY_SIZE; i++) {
    printf("Please enter the name and age of the person : ");
    scanf("%s%d", names.name, &names.age);
    }

    printf("**************************************************\n");
    printf("NAMES and AGES \n");

    for (i = 0; i < ARRAY_SIZE; i++)
    printf("%s --> %d \n", names.name, names.age);

    system("PAUSE");
    return 0;
    }



    Birkaç açıklama yapmak gerekirse; struct ile kendi türlerimizi oluşturuyoruz denilebilir. içinde bir isim ve yaş tutabilen bir yapı oluşturmuş olduk. C'de C++ da olduğu gibi vector, string tarzı sınıflarımız olmadığı için bu tür yapılar kullanıyoruz. Zaten biraz C bilginiz varsa C'de sınıf olmadığını da biliyorsunuzdur. C'de sınıfların yerini ilkel olan yapılar (struct) alır.
    Başında typedef kullanmamızın nedeni, typedef kullandığımız zaman bu yapı türünde bir nesne tanımlarken struct tagNameAge yerine NameAge ile nesne tanımlayabiliriz. Yani aşağıdaki iki kod aynı işi yapar:

    quote:


    struct tagNameAge names[20]; //typedef kullanmasaydık bunu kullanmamız zorunlu olurdu.
    NameAge names[20];


    Yapının elemanlarına " . "(nokta) operatörü ile ulaşılır.

    quote:

    scanf("%s%d", names.name, &names.age);


    Kodun en önemli kısmı yukarıdaki kısım diyebiliriz. Burada klavyeden names nesnesi içine isim ve yaş bilgilerini alıyoruz. %s 'i string gibi düşünebilirsiniz. scanf ile birden fazla karakter alacağımız zaman kullanıyoruz. %d ise decimal olarak düşünebilirsiniz. Yani tam sayı. scanf ile tamsayı alacağınız zaman kullanılır. (bunun dışında %c ile bir karakter %lf ile ise double türdeki gerçek sayıları yani ondalıklı sayıları alırız. ) Gelelim virgülden sonraki kısma. C'de bir dizi tanımladığınız zaman dizinin ismi (burada name oluyor) dizinin ilk adresini verir. c++ da siz cin ile nesneyi adres düşünmeden alırken c'de bu bu şekilde işlemez. c'de scanf ile bir klavyeden değer okurken mutlaka scanf fonksiyonuna nesnenin adresini göndermeniz gerekiyor. burada biz names.name şeklinde bir kod yazdığımızda name yapının içindeki dizinin adresini gösteriyor. Burada herhangi bir sorun yok. Yalnız klavyeden yaş bilgisi alınırken &names.age şeklinde yazılmış. Yapının elemanına ulaşılırken gene nokta operatörü kullanılmış. Fakat burada bir fark var. Önünde & operatörü var. C 'de bu bir nesnenin adresini gösterir. (Aynısı C++ için de kullanılır, fakat gerek olmadıkça c++ da bu yapıdan kaçınılması gerekir. Zorunlu durumlar dışında reference kullanmanızı tavsiye ederim. c'deki pointer yapısı yerine geçer) scanf de klavyeden nesne alırken adresini göstermemiz gerektiğinden dolayı bu şekilde önüne & operatörünü getirdik.




  • 
Sayfa: 1
- x
Bildirim
mesajınız kopyalandı (ctrl+v) yapıştırmak istediğiniz yere yapıştırabilirsiniz.