C kezdő vagyok

Fórumok

Sziasztok!

Van egy C-ről szóló könyvem! The C Programming Language 2nd Ed.

Az első néhány programot még szépen meg tudtam csinálni ahogy azt leírták! Azonban eljutottam egy olyan feladathoz, ahol elakadtam!

Eleinte ha valamelyik program nem futott le, akkor leellenőriztem, a könyvben lévőt. Ha copy-paste-val bemásoltam, s ott futott, akkor csak én üthettem el.

Azonban most eljutottam két olyan programhoz is, amiket hiába másolok be, nem fut. Mutatom:

#include < stdio.h >
#define IN 1 /* inside a word */
#define OUT 0 /* outside a word */
/* count lines, words, and characters in input */
main()
{
int c, nl, nw, nc, state;
state = OUT;
nl = nw = nc = 0;
while ((c = getchar()) != EOF) {
++nc;
if (c == '\n')
++nl;
if (c == ' ' || c == '\n' || c = '\t')
state = OUT;
else if (state == OUT) {
state = IN;
++nw;
}
}
printf("%d %d %d\n", nl, nw, nc);
}

A hibaüzenetem pedig a következő:
word.counting.c:1: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘<’ token

Egyébként a könyv úgy tanítja, hogy:
cc fájlneve.c
majd
./a.out

De úgy tudom hogy van másik megoldás is a gcc-vel (linux alatt vagyok), ami kicsit modernebb.
Azt valaki el tudná magyarázni, hogy működik? A hiba megoldásán túl?

Előre is köszi

Péter

Hozzászólások

stdio.h kore nem kellenek space-ek az elso sorban

#include < stdio.h >

szunetet hagytal benne az stdio.h korul
igy " stdio.h "-t akar nekem include-olni

if (c == ' ' || c == '\n' || c = '\t')

helyesen:

if (c == ' ' || c == '\n' || c == '\t')

ez gondolom csak typo

--
When in doubt, use brute force.

Köszi a segítséget!

Bocs, azt nem írtam hozzá, de a stdio.h-nál direkt van space, mert valamiért első beküldésre nem volt hajlandó megjeleníteni! Ezért tettem bele, mert úgy már látszott. Bár nem értem miért.

Nem tudom mit értesz typo alatt. Mindenesetre amit bemásoltam a könyvből másoltam. Mivel nem értek hozzá ezért nem is érthettem miért nem megy! Megpróbálom és visszajelzek! Köszi

Na pl. a -Wall paraméter emiatt is jó: szól, hogy tegyünk már egy zárójelet az értékadás köré (azért azt tisztelettel nem feltételezi, hogy véletlenül hagytuk le az egyik egyenlőségjelet, pedig nyugodtan feltételezhetné, szerintem az esetek 99,9 százalékában).

A typo meg olyan, mint a hypo, csak nyomdahibát jelent.

Fordításhoz gcc-vel:

gcc   -c   -Wall -ggdb   -o fajlneve.o   fajlneve.c

Linkeléshez:

gcc   -o fajlneve   fajlneve.o

Ha az elsőből elhagyod a -c paramétert, akkor rögtön linkeli is. Ha elhagyod a ,,-o kimeneti_fajl'' paramétert, akkor a.out-ot generál.
-Wall: minden warningot írjon ki, tudom ajánlani.
-ggdb: debug-hoz szimbólumtáblát + egyebeket tegyen bele; fejlesztéskor ajánlom, kész programhoz nem feltétlenül kell

Meg lehet nézni, hogy csak a preprocesszor mit csinál:

gcc   -E   -o fajlneve.o   fajlneve.E.c

Meg lehet nézni, hogy milyen assembly kimenetet kapunk:

gcc   -S   -Wall   -o fajlneve.o   fajlneve.S

A ,,jobb megoldás'' a makefile használata. Példa-makefile itt. Ha kérdés van, szólj csak.

"Van egy C-ről szóló könyvem! The C Programming Language 2nd Ed."

Szabadjon megjegyeznem, hogy az a könyv nem éppen tankönyv. Félreértés ne essék, a tartalma természetesen kiváló, csak saját tapasztalataim alapján tanulni elég nehéz belőle.

[Szerk.]

Azt azért talán hozzá kell tennem, hogy én az első kiadását olvastam cirka 20 éve.

---
Science for fun...

No akkor... ezt üzeni tehát:

word.counting.c:1: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘<’ token

A word.counting.c:1 azt jelenti, hogy a fájl 1. sorában van a hiba. Innentől nem lesz nehéz megtalálni.

Ha C-s jeleket keres, pl. = , ; asm < stb., akkor nem a preprocesszor szólt hozzánk, hanem a C-fordító. Ennek oka lehet pl., ha lehagytad a # jelet.

A # jellel kezdődő sorok a preprocesszornak szólnak, ami fordítás előtt lefut, és cimkéket vagy makrókat helyettesít be, fájlokat szúr be, stb.

Ha leveszem a # jelet, nekem pont ezt a hibát dobja.

Milyen distro (egyáltalán linux?), milyen fordító?
Nekem Ubuntun, gcc 4.3.2-vel simán fordul.

"If you must mount the gallows, give a jest to the crowd, a coin to the hangman, and make the drop with a smile on your lips" The Wheel of Time series

Próbáld meg így:


#include < stdio.h >
/* inside a word: */
#define IN 1 
/* outside a word: */
#define OUT 0 

/* count lines, words, and characters in input */
int main() {
    int c, nl, nw, nc, state;
    state = OUT;
    nl = nw = nc = 0;
    while ((c = getchar()) != EOF) {
        ++nc;
        if (c == '\n')
            ++nl;
        if (c == ' ' || c == '\n' || c == '\t')
            state = OUT;
        else if (state == OUT) {
            state = IN;
            ++nw;
        }
    }
    printf("%d %d %d\n", nl, nw, nc);
    return 0;
}

Amire figyelj: A #define részeknél külön sorba írtam a megjegyzéseket!
A main() függvényt int típusúvá tettem, és a végén beleírtam, hogy "return 0;"

Annyit még, hogy amikor kipróbálod a programot a "Ctrl-D" hatására fejeződik be az adatbevitel. Ez a "Ctrl-D" jelenti az EOF (fájl vége) karaktert.

Rossz irányba akarod vezetni. A preprocesszor segít, de ugyanakkor bizonyos esetekben gátol is, leginkább hibakeresésben. A konkrét példában az állapot lehetne egy felsorolási típus, amely kétértékkel bír:


....
/* névtelen típus */
typedef enum {
  IN, /* vagy ST_IN */
  OUT,
} state_t;

int main()
{
    int c, nl, nw, nc;
    state_t state = OUT;
...

Az értékadást is illik a definícióhoz kötni, különben valamilyen értékkel rendelkezik, de nem feltétlenül definiált, hogy mivel. Ráadásul például C++-ban kétszer kap értéket: egyszer kezdetben, egyszer pedig amikor az értékadás bal oldalán van.