[ EmmaR @ 13.11.2012. 20:41 ] @
Code:

#include <stdio.h>                

#define IN 1    /* unutar riječi */
#define OUT 0    /* van riječi */

// "glavni" program
int main (int argc, char *argv[])
{
    printf ("Hello world!\n");
    
    int broj;
    char slovo[15]; 
    const char rec[]="ZDRAVO1";
    char *reci="zdravo";
    
    
    printf("uvodna rec ... %s ... \n",rec);
    printf("uvodna rec ... %s ... \n\n",reci);
    //izmenjene reci
    printf("unesi neke reci ... ");
    scanf("%10s",&reci); //ovo zbog necega ne radi
    reci="asd"; // radi nova dodela - privremeni red da ne bi program stao
    printf("uvodna rec ... %10s ... \n\n",reci);

    printf("unesite neki broj ...");
    scanf("%d",&broj);
    printf("\nuneto je %d\n",broj);

    
    printf("\nUnesi neko slovo...");
    scanf("%15s",&slovo);
    printf("\nuneto je %15s \n",slovo);
    
    // deo koji kod mene nista ne radi sem sto uleti u beskonacnu petlju
        /* zbraja linije, riječi i znakove na ulazu */     
    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;
        }
    }    
    
    return 0;
}




Non-stop mi prijavljuje grešku (upozorenje) kod scanf:
Code:
 scanf("%10s",&reci); 

format '%10s' excepts type 'char *', but argument 2 has type 'char **'
Program se izvršava bez problema (u tom delu). Kada je iskompajlirano pod Win, radi bez ikakvog upozorenja
Takođe, deo
Code:
printf("unesi neke reci ... ");
    scanf("%10s",&reci); //ovo zbog necega ne radi
    printf("uvodna rec ... %10s ... \n\n",reci);

neće da stampa direktno dodeljen string, već izbacuje poruku o grešci i zaustavlja izvršavanje programa
bash: line 1: 4236 Segmentation fault / .... /KonzolaC

deo sa getchar() - rezultira beskonačnom petljom. To nije moj kod, već iz tutorijala. šta tu ne valja?
Ispravka: Sve je OK sa ovim delom koda. Kretala sam od pogrešne pretpostavke da je kraj unosa/izvršavanja CTRL+Break a treba CTRL+D za Unix/Linux, CTRL+Z za Win



[Ovu poruku je menjao EmmaR dana 13.11.2012. u 22:35 GMT+1]
[ Mihajlo Cvetanović @ 14.11.2012. 06:38 ] @
Dešava se ono što se u knjizi u kojoj je opisan jezik C zove undefined bahavior. Kod je pogrešno napisan i C standard kaže da ako je kod pogrešno napisan onda bilo šta može da se desi: kod se izvršava kako osoba A očekuje, kod se izvršava kako osoba B očekuje, kod se izvršava kako niko ne očekuje, kod se uopšte ne izvršava, ili drugačiji ishod svaki put po pokretanju.

Parametri za scanf tip funkcija treba da budu adrese. Ako je tip promenljive X neki integralni (int, float) onda adresu daješ sa ampersandom (&X). Ako je tip promenljive pointer na char, i učitavaš niz znakova, onda je taj pointer na char već sama po sebi adresa, i neophodno je da adresa ukazuje na postojeći bafer koji će moći da prihvati znakove koji se učitavaju. Sledeći kod je pogrešan:

Code:
    char *reci="zdravo";
    printf("uvodna rec ... %s ... \n\n",reci);
    scanf("%10s",&reci);


Umesto prethodnog treba da stoji sledeće:

Code:
    char reci[11] = "zdravo";
    printf("uvodna rec ... %s ... \n\n", reci);
    scanf("%11s", reci);


Tri izmene: prvo, nije char *reci nego char reci[11], jer mora da postoji bafer koji će prihvatiti podatke, i sa ovim brojem 11 rezervišemo mesto za 11 znakova (zapravo za 10 i terminator stringa). Drugo, u pozivu scanf umesto &reci stoji samo reci, jer sama promenljiva reci je već adresa na bafer, i to je ono upozorenje koje ti javlja kompajler. Treće, zaboravio sam sad kako se koristi scanf, i nisam siguran da ovaj broj za ograničenje stringa na 10 znakova uopšte radi tako kako ti i ja mislimo, ali ako hoćeš da ograničiš string na 10 znakova onda moraš da staviš 11, jer ti treba još jedno mesto za string terminator.

[Ovu poruku je menjao Mihajlo Cvetanović dana 16.11.2012. u 10:39 GMT+1]
[ Nedeljko @ 14.11.2012. 12:54 ] @
EmmaR

Imali smo nesuglasica na MZ, ali mi je vrlo drago što vidim da želiš da naučiš nešto novo i sa zadovoljstvom bih ti pomogao koiko mogu, kao i drugima.

Prvo mi nije jasno zašto pokušavaš da pišeš programe u C-u korišćenjem MonoDevelop-a, koji nije za to. Preporučio bih ti za početak Eclipse for C++ developers. Možeš koristiti i Code::Blocks, kao i Qt Creator (mada je on za C++ koji uspešno prevodi i izvršava 99,9% C programa). No, ako si početnik koji planira da postane profesionalac, preporučio bih ti da izbegavaš bilo kakva okruženja, već da koristiš običan editor (valjda se u mintu zove Text Editor, a možda i gEdit, KWrite, Kate, mada može i mc-ov editor (Midnight Commander) odlično da posluži) dok ne naučiš da kompajliraš iz komandne linije i da praviš Makefile za automatizaciju prevođenja. To nije ništa teško, a vrlo je korisno razumeti projektne datoteke i proces prevođenja. No, to nema nikakve veze sa pitanjem koje si postavila.

char je znakovni tip u C-u. U memoriji zauzima jedan bajt (zaboravi na neengleska slova sa njim) i u njega se može smestiti jedan znak. Da bi se smestio string, tj. niska znakova, kao što je "Dobar dan!", potrebno je rezervisati u memoriji najmanje broj bajtova koji je broj znakova niske uvećan za 1. Kao odgovarajući tip se koristi char*, što je zapravo pokazivač na jedan znak, u ovom slučaju prvi znak niske. Taj jedan bajt više je rezervisan za terminator (bajt vrednosti 0), koji označava kraj niske. Drugim rečima, u memoriji može da bude rezervisano i više prostora, ali se kao sadržaj niske računa ono što ide do terminatora.

scanf funkcija mora da zna gde je u memoriji mesto u koje treba da upiše ono što je ukucano preko tastature. Da je n celobrojna promenljiva, njena adresa bi se označavala sa &n, ali niska znakova se već prenosi kao pokazivač na prvi znak niske, tako da se znak "&", ne stavlja. Zapravo, u tvom primeru je &reci pokazivač na promenljivu reci, koja je pokazivač na prvi znak niske, a to nije ono što treba.

Takođe, sa char *reci = "zdravo" je rezerisano najmanje onoliko prostora koliko je potrebno za smeštaj niske "zdravo" (7 bajtova). Možda i više (zbog poravnavanja koje prevodilac može da radi u cilju optimizacije), ali to u principu ne znaš.

Sa druge strane, sa char reci[11] = "zdravo" se rezerviše dovoljno prostora za ono što tebi treba, a to je unos niske duge najviše 10 znakova.
Citat:
Mihajlo Cvetanović: nisam siguran da ovaj broj za ograničenje stringa na 10 znakova uopšte radi tako kako ti i ja mislimo, ali ako hoćeš da ograničiš string na 10 znakova onda moraš da staviš 11, jer ti treba još jedno mesto za string terminator.

Zavisi od implementacije. Kod nekih može, a kod nekih ne može.
[ EmmaR @ 15.11.2012. 21:24 ] @
Znači, ovako:
Code:

char string[11]; //10 char + 1 znak za adresu
scanf("%s", string);
printf("%s", string);


ili

Code:

char *string;   //Da li je ovo preporučljivo ili mora char string[ n+1 ] ???
scanf("%s", string);
printf("%s", string);


je u redu.
Ispravka (from Mint): Drugu varijantu Linux ne prihvata: Traži da se explicitno navede dužina stringa.

A za brojeve (celobrojne, realne) važi:

Code:

int broj;
scanf("%d", &broj);
printf("%d", broj);


Nisam baš nova u ovome. Problem je u tome da ono što sam zvanično učila bilo je nekako zbrkano i više na nekakvom industrijskom nivou. Umela bih da napišem program koji radi sa ulazom sa tastature i obrađuje ga, ali povezivanje sa DB nije rađeno a do skora nisam ni imala pristup nekoj literaturi (verovali ili ne; no to nije tema za ovaj deo foruma).
Mada, izgleda da ni to što sam učila nije bilo baš iscrpno i tačno (kao što je ovo u vezi scanf i stringova, i da za string treba rezervisati jedno mesto više); možda ima veze sa kompajlerom - radilo se o TurboBorland C++ 2.0 (a OS verovatno pogađate koji je bio).
Proveriću sutra na Linuxu, kako radi. Kao što napisah u prethodnom postu, Win se nije bunio za scanf("%s", &string);, a ne buni se ni za scanf("%s", string); (Borland C++ 3.1 for Win)

Mihaljo, sa char *reci = "zdravo" pokušala sam da izbegnem ograničenje u konačnoj dužini stringa.

Nedeljko, imam i Eclipse i Code::Blocks, ali nekako mi više leži MonoDevelop a za sada sam suviše lenja da radim iz terminala: ulenjili me "prozori". Inače, ako sam dobro ukapirala MonoDevelop poziva gcc za C/C++ - jedina je razlika u tome što ne treba da zasebno otvaram editor pa kada završim pozovem kompajler, pa kada on iskompajlira pozovem izvršnu datoteku.



[Ovu poruku je menjao EmmaR dana 16.11.2012. u 00:07 GMT+1]