Keresés

Új hozzászólás Aktív témák

  • Rickazoid
    addikt

    Az i nem feltélten lesz 0. Egyszerűen csak nem változik az értéke. Mivel te semmivel sem inicializáltad, véletlen érték lesz, ami éppen a memóriában volt. Feladattól függően egyébként sem biztos, hogy a 0 hibás bevitel lenne.

    Azért végtelen a ciklus mert ha a scanf elakad, akkor nem olvassa ki a pufferből a maradékot. A következő scanf hívás tehát pont ugyanúgy elakad. Neked kell takarítani, a következő sorvég jelig, például getchar használatával. EOF-ot is illik lekezelni.

    A scanf amúgy visszaadja mennyi mezőt sikerült beolvasnia, de ettől még lehet szemét a pufferben. Nem véletlenül mondják, hogy nem ajánlott scanf-et használni. Bármennyire is nem szeretnéd, a korrekt megoldás általában teljes sor olvasása (fgets) után kézi feldolgozás (strtol, strtod).

    Egyelőre megoldottam puffertörléssel.. bár néha csinál érdekességeket, bugos a drága. Egy következő programomnál már lehet eleve másképp állok majd neki.

  • Rickazoid
    addikt

    Üdv!

    A következő kóddal (mintakód, de a problémám ugyanez) lenne a problémám:
    int i;
    scanf("%d",&i);
    printf("%d",i); //nem integer esetén 0
    while(i==0)
    {
    printf("Nem jó. Új szám: ");
    scanf("%d",&i);
    }
    printf("%d",i);

    Amíg az i-nek számot adok meg, nincs gond, de amint betűt, a mögötte lévő ciklus végtelen ciklusba kerül. Ezt próbáltam meg kiküszöbölni a példában szereplő while ciklussal ami megnézi, hogy 0-e, mivel nem szám esetében 0 lesz az i értéke, de az is végtelen ciklusba kerül. Hogy tudom elérni, hogy nem szám beírásakor újrakérje a számot végtelen ciklusok helyett?
    Az int-et nem módosíthatom karakterre, főleg nem karaktertömbre, az most túl bonyolult lenne a program többi része miatt.
    Van valami megoldás erre? Egyáltalán miért nem működik? Ha az i értéke 0 lesz, akkor a while miért hülyül meg, mi a különbség 0 és 0 közt, ha mindkettő integer?

  • Rickazoid
    addikt

    @szkorhetz> nalam jo, lehet azert nem megy mert linuxon irtam. igaz ezzel nem kene problema lenni

    valaki nem tud mondani egy string to int konvertal fuggvenyt?
    megvan mar!
    a fv neve > atoi

    Nálam először -1 hibakódot dobott a Code::Blocks, aztán rájöttem, hogy nincs bemenet.txt fájl. Erre nem írsz egy ellenőrzést, hogy ilyenkor se hibával lépjen ki? Ha jól gondolom ez iskolai feladat, oda nem árt ilyesmit beleírni, hátha beleköt a tanár (persze lehet nem, te ismered jobban). De egyébként is jobb (főleg később), ha az ember úgy írja a programjait, hogy hibánál (már amelyiket előre meg lehet jósolni) figyelmeztessen rá, "szóljon", hogy mi a gond.

  • Rickazoid
    addikt

    Ez fordítható és futtatható. Nálam is csak ennyi fut épp a programomban. Egyedül az I és a rows változók deklarációja maradt ki, azok globálisak (ügy könnyebb több ciklusban kezelni ezt a néhányat, mint folyamatos értékátadásokkal, amit fogalmam sincs hogy kéne például két dimenziós tömb esetén), de erre utalok is, illetve az első pár sorból kitalálható.

    Nekem ennyi a hibaüzenet a Code::Blocks alatt:
    Process terminated with status 0 (0 minutes, 0 seconds)
    0 errors, 0 warnings

    Mielőtt és miután javítottam a hibát a sorszámlálásnál, ahol a bezárt fájlra hivatkozott a megnyitott helyen. Persze nem ez a gond.

    Valgrindről nem is hallottam eddig, debug programok lesznek az utolsók, amiket tanulunk, ha egyáltalán sor kerül rá. Korábban sem tanultam hasonló programok használatát, pedig TurboPascalban sokkal messzebb mentünk anno.

    "Ezen felül, a buffer2 és buffer3 tömbök induláskor nincsenek inicializálva"
    Ez nem is tudom mit jelent. Illetve tudom, csak nem értem ez C-ben mit jelent. Nem használtunk semmi egyebet órákon eddig, igazából fájlkezelést se, de nem lehet megoldani az adatbázis eltárolását fájlkezelés nélkül. A buffer viszont miután fel van töltve, a buffer2-nek és a buffer3-nak pont úgy kéne működnie, mint az eddigi tömböknek, amikkel dolgom volt.
    Egyébként az általad írt hibaüzenet mit jelent? Valahogy nem tűnik értelmes mondatnak számomra egyik sem. Az általam tanultak szerint a while(Name[I][l]=buffer3[l++]); kifejezés megfelelő. Amíg van elem a buffer3-ban (l 0-ról indul és növeli önmagát, amíg a kifejezés érvénytelenné válik, mert az aktuális buffer3 helyen nincs semmi), azt eltárolja a Name tömbbe.

    Az EOF csak egy találgatás volt, nem akartam felesleges ciklusokat írni, de kellett valami, ami kinullázza a tömb tartalmát, mielőtt új értékek mennének bele, mert ha a második rövidebb, felesleges karakterek maradnak bent. De azt át tudom írni, ha jól rémlik (így reggel már rémlik) ha kihagyom az összehasonlítást és csak annyit írok, hogy while(buffer2[l++])buffer2[l-1]=' \0'; ugyanazt az eredményt érem el.

    Szerk.: Köszi, úgy tűnik az EOF elhagyása megoldotta a dolgot. Ezt megjegyzem, hogy ezt nem használjuk ilyenkor, csak ha ezzel zárjuk a streamet.

    Ja, a globális változók, rögtön a #define-ok után:
    int ID[MAXID],I;
    char Name[MAXID][MAXLEN];
    char Tpy[MAXID];
    long rows;

  • Rickazoid
    addikt

    Tényleg olyan nagy dolog fordítható, futtatható kóddal megtisztelni a segítőkész embereket? :U

    Valahogy kipótoltam, de hogy így most az-e amit te használsz azt honnan tudjam?

    Általános jótanács, hogy kapcsold be a fordító figyelmeztetéseit:

    warning: suggest parentheses around assignment used as truth value
    warning: operation on 'l' may be undefined

    Ezek a while(Name[I][l]=buffer3[l++]); sorra vonatkoznak.

    Következő jótanács, hogy használd a valgrind (vagy más hasonló) programot. Ez például megmutatja, hogy itt-ott a már bezárt f fájlból akarsz olvasni az ff helyett.

    Ezen felül, a buffer2 és buffer3 tömbök induláskor nincsenek inicializálva, tehát legalább az első iterációban baj van. A későbbiekben sem látom hogy kerül bele EOF ami különben is int konstans, tehát char változóba nem szabad beletenni.

    Ezeket javítva már valamit csinál a program, de hogy az jó-e azt nem tudtam a leírásodból kibogozni.

    Ez fordítható és futtatható. Nálam is csak ennyi fut épp a programomban. Egyedül az I és a rows változók deklarációja maradt ki, azok globálisak (ügy könnyebb több ciklusban kezelni ezt a néhányat, mint folyamatos értékátadásokkal, amit fogalmam sincs hogy kéne például két dimenziós tömb esetén), de erre utalok is, illetve az első pár sorból kitalálható.

    Nekem ennyi a hibaüzenet a Code::Blocks alatt:
    Process terminated with status 0 (0 minutes, 0 seconds)
    0 errors, 0 warnings

    Mielőtt és miután javítottam a hibát a sorszámlálásnál, ahol a bezárt fájlra hivatkozott a megnyitott helyen. Persze nem ez a gond.

    Valgrindről nem is hallottam eddig, debug programok lesznek az utolsók, amiket tanulunk, ha egyáltalán sor kerül rá. Korábban sem tanultam hasonló programok használatát, pedig TurboPascalban sokkal messzebb mentünk anno.

    "Ezen felül, a buffer2 és buffer3 tömbök induláskor nincsenek inicializálva"
    Ez nem is tudom mit jelent. Illetve tudom, csak nem értem ez C-ben mit jelent. Nem használtunk semmi egyebet órákon eddig, igazából fájlkezelést se, de nem lehet megoldani az adatbázis eltárolását fájlkezelés nélkül. A buffer viszont miután fel van töltve, a buffer2-nek és a buffer3-nak pont úgy kéne működnie, mint az eddigi tömböknek, amikkel dolgom volt.
    Egyébként az általad írt hibaüzenet mit jelent? Valahogy nem tűnik értelmes mondatnak számomra egyik sem. Az általam tanultak szerint a while(Name[I][l]=buffer3[l++]); kifejezés megfelelő. Amíg van elem a buffer3-ban (l 0-ról indul és növeli önmagát, amíg a kifejezés érvénytelenné válik, mert az aktuális buffer3 helyen nincs semmi), azt eltárolja a Name tömbbe.

    Az EOF csak egy találgatás volt, nem akartam felesleges ciklusokat írni, de kellett valami, ami kinullázza a tömb tartalmát, mielőtt új értékek mennének bele, mert ha a második rövidebb, felesleges karakterek maradnak bent. De azt át tudom írni, ha jól rémlik (így reggel már rémlik) ha kihagyom az összehasonlítást és csak annyit írok, hogy while(buffer2[l++])buffer2[l-1]=' \0'; ugyanazt az eredményt érem el.

    Szerk.: Köszi, úgy tűnik az EOF elhagyása megoldotta a dolgot. Ezt megjegyzem, hogy ezt nem használjuk ilyenkor, csak ha ezzel zárjuk a streamet.

  • Rickazoid
    addikt

    Üdv!

    Akadt némi problémám egy programommal. Gyakorlatilag kész vagyok vele, látszólag pont úgy működik, ahogy kell, azonban a tesztelés közben belefutottam egy jókora problémába. Bizonyos helyzetekben a fájlból beolvasott számokat lenullázza. Beolvassa jól a számot, mint karaktert, de a számmá alakításnál 0 kerül a változókba. Látszólag számtól független, bármi lehet ott, rendesen átalakítja, amíg csak pár sor van. De ha ismétlődnek a sorok, akkor akármennyit átalakít, ahogy kell. Ha ugyanannyi van, mintha ismétlődne, de más a tartalom, akkor is jól működik. De ha az eredeti tesztfájlba csak még egy sort beírok, máris rossz lesz. Illetve akkor is rossz lesz, ha bizonyos sorokat meghosszabbítok. Magyarul számtalanszor előidéztem a hibát, de abszolút semmi fogalmam nincs róla, hogy mi lehet a gond.

    A kérdéses része a programomnak a következő:

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


    #define MAXID 100
    #define MAXLEN 20

    #define OUTF "AdatbazisTeszt3.ctlg"

    void printFile2Mem()
    {
    long size;
    rows=0;
    I=0;
    //az OUTF által hivatkozott fájl létrehozása, ha nem létezne
    FILE *f;
    f=fopen(OUTF, "a");
    fclose(f);
    //a fájl megnyitása olvasásra
    FILE *ff;
    ff = fopen(OUTF, "rt");
    fseek(ff, 0, SEEK_END); //a fájl végének megkeresése
    size = ftell(ff); //a file pointer beolvasása, megadja a fájl méretét
    fseek(ff, 0, SEEK_SET); //vissza a fájl elejére
    //printf("%d\n",size);
    //a buffer tömbök átmeneti tárolóként funkcionálnak majd a fájlból beolvasandó adatoknak
    char buffer[size+1],buffer2[size+1],buffer3[size],buffer4,c;
    //a teljes fájl beolvasása a buffer[] tömbbe
    fread(buffer, 1, size, f);
    buffer[size]=0;
    //fclose(f);
    //printf("The file:\n%s\n", buffer);
    //segédváltozók a ciklusokhoz, amik a buffer[] tömbből olvassák ki az adatokat és teszik a megfelelő átmeneti tárolóba
    int i=0,j=0,k=0,l=0,ii;

    fseek(ff, 0, SEEK_SET); //ismét a fájl elejére állítja a mutatót
    //beolvassa a rows globális változóba a sorok számát
    while((c=fgetc(f))!=EOF)
    if(c=='\n')rows++;
    //a fájl bezárása
    fclose(ff);

    printf("%d\n",rows);
    printf("The file:\n");
    //a buffer[] tömb elemeinek megfelelő tömbökbe helyezése

    for(ii=0;ii<rows;ii++)
    {
    j=0;
    while(buffer2[l++]!=EOF)buffer2[l-1]='\0';l=0; //enélkül hibák keletkeznek a különböző hosszúságú értékek ugyanazon tömbbe tárolásakor
    //a buffer2[] tömbbe beolvassa az aktuális sor ID-jét
    //egyelőre szövegként kezeli
    while(buffer[i++]!=';')
    if(buffer[i-1]>='0'&&buffer[i-1]<='9')
    buffer2[j++]=buffer[i-1];
    printf("buffer: %s\n",buffer2);
    j=0;
    while(buffer3[l++]!=EOF)buffer3[l-1]='\0';l=0; //enélkül hibák keletkeznek a különböző hosszúságú értékek ugyanazon tömbbe tárolásakor
    //a buffer[3] tömbbe beolvassa az aktuális sor nevét
    while(buffer[i++]!=';')buffer3[j++]=buffer[i-1];
    //printf("buffer: %s\n",buffer3);
    //buffer4='\0'; //bár a buffer4 csak egy karakteres változó, biztosítékként bekerült ez az értékadás a buffer[] tömbből való értékadás elé
    //eltárolja a buffer4 változóba az aktuális sor típusát
    buffer4=buffer[i];
    //az ID[] tömbb adott helyére eltárolja a buffer2-ben tárolt stringet integerként
    printf("buffer: %s\n",buffer2);
    ID[I]=atoi(buffer2);
    printf("ID: %d\n",ID[I]);
    //a Name[][] tömb adott helyeire eltárolja a buffer[] tömb elemeit
    while(Name[I][l]=buffer3[l++]);l=0;
    //a Tpy[] tömb adott helyére eltárolja a buffer4 értékét
    Tpy[I++]=buffer4;
    //kezdetlegesen formázott kiírása az adatbázis elemeinek
    //printf("%d\t%s\t%c\n", ID[ii],Name[ii],Tpy[ii]);
    }
    }

    Namost sejtem, hogy nem valami szép (és a tömbök méretei sincsenek egyelőre pontosan beállítva), de ennél jobbat egyelőre nem tudok írni. A hiba valahol a vége felé lehet, kiírattam a buffer2 változó értékét két helyen is, amikor az ID-tömbbe 0-kat rak, akkor a második kiíratásnál üres. Valamiért a kettő közt történik vele valahogy valami, viszont nem értem hogy, hisz nem nyúl hozzá semmi.

    Egy példafájl:
    ID;Name;Type
    1;egyes;C
    2;kettes;C
    945;kilencszáznegyvenönégyes;C
    4;négyes;C
    5;ötös;C

    Ezzel működik. De például ezzel már nem:
    ID;Name;Type
    1;egyes;C
    2;kettes;C
    945;kilencszáznegyvenönégyes;C
    4;négyes;C
    5;ötös;C
    6;hatos;C

    Ezzel sem:
    ID;Name;Type
    1;egyes;C
    2;kettes;C
    945;kilencszáznegyvenönégyes;C
    4;négyes;C
    512;ötszáztizenkettő;C

    Ezzel viszont igen:
    ID;Name;Type
    1;egyes;C
    2;kettes;C
    945;kilencszáznegyvenönégyes;C
    4;négyes;C
    512;ötszáz;C

    Ez utóbbinál ha megnövelem egy nem ékezetes karakterrel az utolsó sort, akkor még működik, de nagyobb növelést nem visel el. Amikor ezt észrevettem, azt hittem valami bájt korlátba ütköztem, de nem, ha a címsor alatti sorokat lemásolom és újra beillesztem, akkor is jól működik. Sőt ha egyenként átírom az ID-ket és össze-vissza írok karaktereket a nevekbe, hogy ne legyen ismétlődés, még akkor is működik. Sőt ha azt kibővítem egy akármilyen sorral (13.), az is működik. De ha még egy sort hozzáadok (14.), -1 hibakóddal kilép. De ha törlöm és beírok 13 sort, azonos karakterszámmal, csak más tartalommal, akkor működik. De ha azt bővítem ki egy sorral, megint jön a -1 hibakód. Ha lecsökkentem a nevek hosszát majd úgy írok be 14 sort, akkor nem kapok hibakódot, de 0-k lesznek az ID tömbben.
    Nem vagyok képes felismerni a rendszert a hibákban, mintha több dolog is hibát váltana ki, de képtelen vagyok rájönni, hogy miért.
    Ötletek?

  • Rickazoid
    addikt

    Üdv!

    Ismét volna némi C problémám. Továbbra is táblázat, ezúttal a feltöltése nem akar működni. A cél az lenne, hogy előre nem meghatározott méretű tömbökbe kérek be értékeket, szövegeket és újabb értékeket.
    A példaprogramom a következőképp néz ki:

    int main()
    {
    int i=0,j=0,k=0,idx[MAXIDX];
    char c='y',name[MAXIDX][NAMELEN];
    float data[MAXIDX];

    while(c=='y')
    {
    printf("ID: ");
    scanf("%d",&idx[i]);
    printf("Name: ");
    while(getc(stdin)!='\n'){} //ha nem írom be, a következő while ciklus nem fut le
    while(name[i][j]=getchar()!='\n')
    j++;
    printf("Data: ");
    scanf("%f",&data[i]);
    printf("New? (y/n): ");
    while(getc(stdin)!='\n'){} //ha nem írom be, a következő getchar() függvény nem fut le
    c=getchar();
    i++;
    }
    printf("\nWriting out:\n\n");
    for(j=0;j<i;j++)
    {
    printf("ID: %d\n",idx[j]);
    printf("Name: ");
    for(k=0;k<NAMELEN;k++)
    {
    putchar(name[j][k]);
    }
    printf("\nData: %.2f\n",data[j]);
    }

    printf("\n");
    system("pause");
    return 0;
    }

    A nagybetűs változók előre vannak definiálva.
    A gond az, ahogy azt a kódba is beírtam, hogy bizonyos helyzetekben a program továbblép karakterbeolvasás nélkül, illetve a szöveget a name tömbből nem írja ki, esetleg el sem tárolja.
    Viszont ha ezt írom:

    int main()
    {
    int i=0,j=0,k=0,idx[MAXIDX];
    char c='y',name[MAXIDX][NAMELEN];
    float data[MAXIDX];

    while(c=='y')
    {
    printf("ID: ");
    scanf("%d",&idx[i]);
    printf("Name: ");
    while(getc(stdin)!='\n'){} //ha nem írom be, a következő while ciklus nem fut le
    while(name[i][j]=getchar()!='\n')
    j++;

    printf("New? (y/n): ");
    c=getchar();
    i++;
    }
    printf("\nWriting out:\n\n");
    for(j=0;j<i;j++)
    {
    printf("ID: %d\n",idx[j]);
    printf("Name: ");
    for(k=0;k<NAMELEN;k++)
    {
    putchar(name[j][k]);
    }
    }

    printf("\n");
    system("pause");
    return 0;
    }

    vagyis mindössze lehagyom a lebegőpontos szám beolvasását, nem kell a második while(getc(stdin)!='\n'){}, de ilyenkor meg ha a c értéke 'n' lesz, egy plusz entert kell nyomnom, hogy továbblépjen. Azok alapján, amit tanultam, ennek és az ez előttinek is jónak kéne lennie, se plusz entereket nem kéne várnia, se while(getc(stdin)!='\n'){} ügyeskedésre nem kéne, hogy szükség legyen és a szövegeket is el kéne tárolnia. Átnéztem az órai, működő példákat (persze egyik sem komplexebb pár sorosnál), de nem találom, hogy miért fut ez a program másképp. A scanf() és a getchar() valahogy ütközik egymással? A name[x][y] alak nem alkalmas szövegek tömbbe tárolására? (karakterek két dimenziós tömbje... miért nincs string típusú változó C-ben?)
    Az órai példa ez volt szövegekre:

    char i,name[5][80];
    for(i=0;i<5;i++)
    {
    printf("Type a word: ");
    scanf("%s",name[i]); //nem kell & jel, mivel a nev[i] itt eleve mutató
    //scanf() esetén a space is megszakító karakter,
    //ezzel nem lehet szóközöket tartalmazó sorokat beolvasni
    }
    for(i=0;i<5;i++)
    printf("%s\n",name[i]);

    Ebből sajnos nem jövök rá, hogy tudnék a getchar() függvénnyel beolvastatni több szöveget is egy tömbbe, ha a scanf() nem alkalmas szóközök olvasására, de nekem azok is kellenek.

    Na jó, arra rájöttem, hogy a szöveg eltárolása getchar() függvénnyel szemantikai hiba miatt nem volt jó, kimaradt egy zárójel: while((name[i][j++]=getchar())!='\n');
    És a kiíratás is egyszerűbben megoldható: while(putchar(name[j][k++]));
    De mi van a while(getc(stdin)!='\n'){} szükségességével? Ha ezt benne hagyom, félek könnyen veszíthetek egy jegyet (c<='a' helyett c<=97 alakért is kaptam már rosszabbat).

  • Rickazoid
    addikt

    Üdv!

    Ismét volna némi C problémám. Továbbra is táblázat, ezúttal a feltöltése nem akar működni. A cél az lenne, hogy előre nem meghatározott méretű tömbökbe kérek be értékeket, szövegeket és újabb értékeket.
    A példaprogramom a következőképp néz ki:

    int main()
    {
    int i=0,j=0,k=0,idx[MAXIDX];
    char c='y',name[MAXIDX][NAMELEN];
    float data[MAXIDX];

    while(c=='y')
    {
    printf("ID: ");
    scanf("%d",&idx[i]);
    printf("Name: ");
    while(getc(stdin)!='\n'){} //ha nem írom be, a következő while ciklus nem fut le
    while(name[i][j]=getchar()!='\n')
    j++;
    printf("Data: ");
    scanf("%f",&data[i]);
    printf("New? (y/n): ");
    while(getc(stdin)!='\n'){} //ha nem írom be, a következő getchar() függvény nem fut le
    c=getchar();
    i++;
    }
    printf("\nWriting out:\n\n");
    for(j=0;j<i;j++)
    {
    printf("ID: %d\n",idx[j]);
    printf("Name: ");
    for(k=0;k<NAMELEN;k++)
    {
    putchar(name[j][k]);
    }
    printf("\nData: %.2f\n",data[j]);
    }

    printf("\n");
    system("pause");
    return 0;
    }

    A nagybetűs változók előre vannak definiálva.
    A gond az, ahogy azt a kódba is beírtam, hogy bizonyos helyzetekben a program továbblép karakterbeolvasás nélkül, illetve a szöveget a name tömbből nem írja ki, esetleg el sem tárolja.
    Viszont ha ezt írom:

    int main()
    {
    int i=0,j=0,k=0,idx[MAXIDX];
    char c='y',name[MAXIDX][NAMELEN];
    float data[MAXIDX];

    while(c=='y')
    {
    printf("ID: ");
    scanf("%d",&idx[i]);
    printf("Name: ");
    while(getc(stdin)!='\n'){} //ha nem írom be, a következő while ciklus nem fut le
    while(name[i][j]=getchar()!='\n')
    j++;

    printf("New? (y/n): ");
    c=getchar();
    i++;
    }
    printf("\nWriting out:\n\n");
    for(j=0;j<i;j++)
    {
    printf("ID: %d\n",idx[j]);
    printf("Name: ");
    for(k=0;k<NAMELEN;k++)
    {
    putchar(name[j][k]);
    }
    }

    printf("\n");
    system("pause");
    return 0;
    }

    vagyis mindössze lehagyom a lebegőpontos szám beolvasását, nem kell a második while(getc(stdin)!='\n'){}, de ilyenkor meg ha a c értéke 'n' lesz, egy plusz entert kell nyomnom, hogy továbblépjen. Azok alapján, amit tanultam, ennek és az ez előttinek is jónak kéne lennie, se plusz entereket nem kéne várnia, se while(getc(stdin)!='\n'){} ügyeskedésre nem kéne, hogy szükség legyen és a szövegeket is el kéne tárolnia. Átnéztem az órai, működő példákat (persze egyik sem komplexebb pár sorosnál), de nem találom, hogy miért fut ez a program másképp. A scanf() és a getchar() valahogy ütközik egymással? A name[x][y] alak nem alkalmas szövegek tömbbe tárolására? (karakterek két dimenziós tömbje... miért nincs string típusú változó C-ben?)
    Az órai példa ez volt szövegekre:

    char i,name[5][80];
    for(i=0;i<5;i++)
    {
    printf("Type a word: ");
    scanf("%s",name[i]); //nem kell & jel, mivel a nev[i] itt eleve mutató
    //scanf() esetén a space is megszakító karakter,
    //ezzel nem lehet szóközöket tartalmazó sorokat beolvasni
    }
    for(i=0;i<5;i++)
    printf("%s\n",name[i]);

    Ebből sajnos nem jövök rá, hogy tudnék a getchar() függvénnyel beolvastatni több szöveget is egy tömbbe, ha a scanf() nem alkalmas szóközök olvasására, de nekem azok is kellenek.

  • Rickazoid
    addikt

    Bár egy ideje már nem dolgozom a Code Blocks-al, de meg kell hogy védjem: pontosan mit is kellene csinálnia, hogy vezesse a kezdők kezét? Ha egy olyan library-val akarsz dolgozni, amihez van benne varázsló, akkor megkérdezi, hogy hol vannak a lib és az include fájlok majd dob egy main.c template-et kezdésnek. Ha nincs benne varázsló, akkor az üres project tulajdonságainál be kell állítani ezeknek a helyét és lehet kezdeni dolgozni. Én személy szerint nem gondolom, hogy az IDE-nek kellene megtanítanie programozni azokat az embereket, akiknek pl. az int main/ return 0 koncepciója sem világos.

    Csatlakozom, szerintem sincs semmi gond vele. Mondom ezt kezdőként. Aki tanulja a C programozási nyelvet, igazából egy szövegszerkesztővel és egy GCC-vel is boldogulnia kéne. Én nemrég kezdtem újra tanulni C-t, sikeresen elfelejtettem mindent és a Code::Blocks-ra esett a választásom (megpróbáltam az Eclipse és a Netbeans monstrumokat is, de azok már végképp nem alkalmasak egy kezdő számára). Eddig minden programot meg tudtam írni vele, bár voltak gondjaim, de azok nem az IDE miatt. Aki tanulja a nyelvet, az IDE-től függetlenül kell hogy megtanulja. De az egyetemen például Blodshed Dev-C++-t használunk (mert nehogy már platformfüggetlen vagy bárki által támogatott, befejezett, stabil legyen az IDE)... na az tényleg katasztrófa. Rosszak az automatikus behúzások, vacakolni kell, hogy lehessen pontosvesszőt tenni (meg sem találja az ember, hogy mi a baj, ha nem mondják meg neki), nincs automatikus kiegészítés, nincs színezés... pedig elvileg IDE... lényegében csak egy túlbonyolított szövegszerkesztő egy beépített fordítóval. A gedit+GCC alkalmasabb a feladatra. A Code::Blocks meg szimplán első telepítésre működik, ahogy kell, konfigurálás nélkül. Nekem legalábbis nem kellett semmit beállítanom, csak telepíteni. Persze lehet majd bonyolultabb projekteknél kelleni fog egyfajta konfigurálás, de amire az ember eljut odáig, hogy összetett projektet hozzon létre, amihez a C jóval mélyebb ismerete szükséges, az IDE beállítása lesz a legkisebb problémája.
    Szerintem.

  • Rickazoid
    addikt

    Üdv!

    C-ben szeretnék két dimenziós tömbben eltárolni különböző típusú értékeket. Lehetséges ez? Ha igen, hogy, ha nem, hogy lehetne ugyanezt az eredményt elérni? Lényegében egy adatbázist kéne csinálnom, de minél többet gondolkodok rajta, mintha annál távolabb kerülnék a megoldástól. Talán csak túl bonyolítom, nem tudom.
    Illetve hogy tudom az előbbi módon eltárolt értékeket eltárolni a programban annak kilépése után is azok fájlba írása nélkül?

    ui.: ANSI C-ben kellene.

  • Rickazoid
    addikt

    Ahogy Jester01 ajánlotta sort olvass be, amit az atoi-val (ascci to int) alakíts át számmá és ennek az eredményét vizsgáld a switch-ben. Elötte persze ellenőrizni kell, hogy mit adott vissza az atoi: pl 11a esetén 11-t, a esetén 0-t (de 0 esetén is 0-t ad vissza, ami jó!), ilyenkor nyilván újra be kell kérni.

    atoi, köszönöm! Akkor meg is van egyelőre, egy !c[1] feltétellel pedig azt is elértem, hogy például az 1a-t ne tekintse 1-nek és ne fogadja el. Eszerint már tudom módosítani, ha később kétjegyű számok is bekerülnek a képbe.

  • Rickazoid
    addikt

    Igaz én is csak kezdő vagyok, de azt hiszem a fflush(stdin) parancs erre jó. Ha mégsem, valaki javítson pls.

    Windows alatt működik, de Linuxon nem.

  • Rickazoid
    addikt

    De, a te C kódodat futtattam. Egy debuggert mihamarabb meg kellene tanulnod, mert azzal tudod a saját programhibáidat felderíteni. gdb-ben nagyjából 8 paranccsal kiválóan el lehet boldogulni (break, run, step, next, continue, print, x, exit) vagy használhatsz valamilyen grafikus felületet.

    Jelen esetben abba futottál bele, hogy a standard input az soronként pufferelt továbbá a getchar szorgalmasan visszaadja a sorvég jelet is. Én például azt írtam be, 5<enter>. Ezt a gép úgy dolgozza fel, hogy az első getchar hívásnál látja, hogy nincs semmi a bemeneti pufferben, tehát beolvas egy egész sort, majd visszaadja az első karaktert (az 5-öt). Erre lefut a switch-ed majd visszamegy a ciklus miatt a getchar-hoz. Ezúttal viszont van még a pufferben valami, mégpedig a sorvég jel, tehát a getchar nem vár és azt adja vissza. Ez ismétcsak a default ágra jut. Hasonló történik akkor is ha másik ágra futsz, a pufferben még mindig benne lesz a sorvég illetve bármi amit a felhasználó még elé írt. Ezt a következő beolvasás vissza is fogja adni.

    Ezért tehát mindig célszerű a teljes sort beolvasni majd igény szerint feldolgozni. Például mi legyen, ha a felhasználó 11-et ír be.

    Értem már! Windows alatt ezt egy _flushall() megoldja, de Linux alatt nem ismeri, és ahogy nézem Google-ben, nem is létezik hasonló. Vagy igen?
    Egyelőre viszont akkor megoldottam úgy, hogy if(c!='\n'), ebbe ment a switch, utána pedig bekerült egy while(getc(stdin)!='\n'){}, így csak az első karakter marad.
    Nem szép és nem dolgoz fel több karaktert, hogy azt is visszajelezze hibás megadásként, de ezzel megkerültem a hibát. Persze jó kérdés mi lenne akkor, ha egy stringet kéne így feldolgoznom. Próbáltam átírni úgy, de valamiért minden karaktere a string-nek (null) lett. De erről még úgyis olvasok később, egyelőre egy karakter elég.

  • Rickazoid
    addikt

    Használnod kellett volna egy debuggert és jól megnézhetted volna, mi a c értéke:

    Breakpoint 3, main () at t.c:10
    10 switch(c)
    (gdb) p c
    $1 = 53 '5'
    (gdb) c
    Continuing.

    Breakpoint 3, main () at t.c:10
    10 switch(c)
    (gdb) p c
    $2 = 10 '\n'

    Így már érted, vagy magyarázzam még?

    Azt hiszem fogalmam sincs, hogy mit is írtál, de azt látom, hogy nem C kód, debuggerekről meg eddig csak hallottam (és még érthető leírás sincs semelyik használatáról sehol). C-vel sem volt dolgom múlt hétig, csak Turbo Pascallal és Pythonnal (előbbiből emelt szintű érettségiig, utóbbival autodidakta módon), de sose használtam semmilyen debuggert.
    Szóval ebben a formában ha csak nem adsz egy leírást a debbuggerek használatáról az alapoktól, nem veszem hasznát egy breakpointnak.
    Egyébként megnéztem a gdb-t, de magas.

    Arra viszont rájöttem, hogy ha a default eset fut le, a c értéke kiürítődik ahelyett, hogy bekérné a getchar() és emiatt a második default futás, hisz a c üres. De hogy az elsőnél miért ugorja át a getchar()-t, azt lenne jó tudni. A c értéke ettől független, az egészen addig a pontig pont annyi, amit a getchar() bekér, amíg a default eset végre nem hajtódik, ott válik valahogy üressé (nincs törlésre utasítás, sőt ha értéket adok neki a printf előtt, akkor az az érték megmarad, de mégis duplán fut a ciklus), majd a ciklus újrafutása mellőzi a getchar()-t. Az alapján, amit a programozásról tudok, ez lehetetlen, egy program nem hagyhat ki csak úgy parancsokat, ha csak utasítást nem kap rá. De itt nincs ilyen, a default esettel vissza kéne mennie a ciklus elejére, ahol a getchar()-nak ismét kérnie kéne a karakterét. De ez nem történik meg egyszer, csak második futásra.

  • Rickazoid
    addikt

    Írnék egy C programot, de van egy hiba, aminek nem találom az okát már vagy másfél órája.
    Itt a forrás (egyelőre csak egy példa, úgymond vázlat program, erre épülne majd egy jóval bonyolultabb):

    ...
    int b=1;
    char c;
    ...
    while(b==1)
    {
    c=getchar();
    switch(c)
    {
    case '1':
    {
    i=1;
    printf("The number is %i\n",i);
    b=0;
    break;
    }


    case '2':
    {
    i=2;
    printf("The number is %i\n",i);
    b=0;
    break;
    }

    case '3':
    {
    i=3;
    printf("The number is %i\n",i);
    b=0;
    break;
    }

    case '4':
    {
    i=4;
    printf("The number is %i\n",i);
    b=0;
    break;
    }

    default:
    {
    printf("That is not a menu option, please try again: ");
    b=1;
    break;
    }

    }
    }

    A problémám az lenne, hogy a default parancsai duplán hajtódnak végre. Mindig duplán írja ki a "That is not a menu option, please try again: " szöveget. Megpróbáltam írni a getchar() elé és mögé egy szöveget printf-fel, de a defaultra azokat is duplán írta ki, jól láthatóan egyszer átugrotta a getchar()-t. Próbáltam kivenni a ciklusból a ciklus elé és újra betenni a defaulthoz, de úgy is szimplán átugrotta egyszer. Nem értem, de nagyon nem. Próbáltam getchar() helyett scanf()-et is, de azt is átugorja egyszer, így annál is dupla lesz a default végrehajtódása. Mitől lehet ez?

Új hozzászólás Aktív témák