Newsgroup: it.comp.lang.c
Titolo: aiutino a un newbie

ciao ragazzi,
    e' veramente poco che "provo" a programmare in c. Ho letto una guida su
programmazione.it
 e ora sto proseguendo con il K&R. Ho visto che qui in ng
non se ne parla molo bene, ma avendolo a casa... Lurkando i vari post ho
imparato e mi sono chiarito diversi concetti ma e' da diversi giorni che mi
sono inpuntato su di una cosa e non riesco a venirne fuori per quanto banale
sia:
#include <stdio.h>
main() {
char pippo[100];
    pippo[0]='Ciao a tutti\0';
    printf("%s",pippo);
}
quello che vorrei fare e' stampare semplicemente Ciao a tutti. Da quello che
ho capito, pippo e' un vettore di caratteri di dimensione
100(100x1byte=100byte allocati in memoria), significa che posso caricare 100
caratteri. Visto che "il terminatore di stringa" e' 0 per i vettori di
caratteri, io carico su pippo a partire dalla posizione 0 la mia frase, e la
limito con \0 (Da cio' che ho studiato, se non mettessi il \0 il printf mi
stamperebbe dalla locazione di memoria di pippo[0] all'infinito finche' non
trova lo 0... spero sia giusto). Quello che non capisco, e' perche' poi la
printf mi stampi solo la "o"! Ho provato anke a dirli printf("%s",
&pippo[0]) ma questo mi fa comparire la schermata "questo programma ha
generato un errorre e bla bla bla" (dimenticavo, sono su windows con il
dev-cpp)
ho perfino provato printf("%10s",pippo) ma nada...
so che e' una banalita' per voi, ma io non riesco a comprenderne il
concetto.
grazie 1000 a chi sara' arrivato a leggere fin qui :)
Dade

 
Persino il K&R dovrebbe aiutarti....
ricomincia a leggerlo....
allora
1) il singolo apice serve per denotare i singoli caratteri,
  quindi ad esempio
char uncarattere  = 'X';
Per le stringhe devi usare il doppio apice
"questa e' una stringa e il terminatore 0 e' automatico"
e il carattere a 0 in fondo lo mette gia' il compilatore.
Siccome pippo e' un array di caratteri pippo[0] indica
semplicemente il primo carattere.
Al limite avresti potuto usare
char pippo[100] = "ciao a tutti";
che definisce e inizializza pippo a tempo di compilazione.
Ma non puoi invece fare
char pippo[100];
e poi in un secondo tempo
pippo = "questo essere errore";
perche' non puoi cambiare l'indirizzo di
pippo, e il C non prevede come operazione
l'assegnazione di stringhe.
Per evitare confusione includi string.h
e usa la funzione strcpy(char *dest, char *src);
che copia array di caratteri terminanti con 0
e ti permette di assegnare stringhe anche
dopo l'inizializzazione degli array di char corrispondenti:
esempio
char pippo[100];
strcpy(pippo,"va bene se contengo al massimo 99 caratteri");
ciao,
g.

 
il problema sta nell'assegnamento che fai: scrivendo pippo[0]= tu assegni
al primo elemento (byte) del vettore un valore (essendo un byte max un
char). in C non puoi (mi sembra) assegnare direttamente una stringa, puoi
usare tre modi (che mi vengono in mente):
1) dichiari pippo così: char pippo[]="Ciao a tutti";
mi sembra che pur essendo facile ed immediato presenti alcuni problemi cioè
il fatto che non sai in che area di memoria effettivamente sia scritto il
testo, potrebbe essere stato memorizzato in un'area a sola lettura. Potrei
sbagliarmi.
2) assegni manualmente un char a ogni byte:
pippo[0]='C';
pippo[1]='i';
pippo[2]='a';
...ecc ecc..
ricordati però
...
pippo[10]=0;      (mmm giusto no?)
per i motivi che già sai
3) usi strcpy, una funzione che ti copia una stringa in un vettore (o area
di memoria). beh in pratica questa funzione non fa altro che fare
automaticamente quello che potresti fare manualmente al punto 2)
ultima cosa: ricordati che gli apici si usano solo per i caratteri ('a')
mentre per le stringhe si usano le doppie virgolette ("Ciao")
spero di averti aiutato
ciao
Luca

#include <stdio.h>
int main(void)
{
	char pippo[100] = "Ciao a tutti";
	printf("%s\n",pippo);
	return 0;
}
Gli ci ho messo un qualche pezza che è buona cosa 
tu prenda in considerazione quando scrivi del codice :)
Ciao Max
-- 
+-----------------------------------------------------------+
| Secondo alcuni autorevoli testi di tecnica Aeronautica,   |
| il calabrone non può volare, a causa della forma e del    |
| peso del proprio corpo in rapporto alla superficie alare. |
| Ma il calabrone non lo sa e perciò continua a volare.     |
|					     Igor Sikorsky  |
+-----------------------------------------------------------+

 }
In generale, ti direi: prendi un libro e/o tutorial di C, e leggiti il 
capitolo sulle stringhe - direi che ti mancano un po' le basi :P
Anyway...
le virgolette singole sono per i caratteri: 'c', 'z', ':'
le virgolette _doppie_ sono per le stringhe: "Ciao a tutti". In questo 
caso, il \0 viene incluso in automatico. Ovvero, "Ciao a tutti" e' un 
array costante: { 'C', 'i', 'a' 'o', ' ', 'a', ' ', ' ', 't', 'u', 't', 
't', 'i', '\0' }
pippo e'un char[100] (che puo' decadere ad un char*). pippo[0] e' quindi 
un char. Quindi, al max:
pippo[0] = 'C';
pippo[1] = 'i';
...
ma sicuramente il modo migliore e':
char pippo[100] = "Ciao a tutti";
-- 
/**
  * Mattia Belletti - Undergraduate student @ 
cs.unibo.it
  * ICQ: 33292311   - email: 
mbel...@cs.unibo.it
  * IRC: BluShine   - site(s): 
http://cs.unibo.it/~mbellett
  * Linux registered user 299762 @ Linux registered machine 213003
  */


Ciao e grazie e... vista l'ora buon pranzo :)
Dade

 sbagliarmi.
Dipende dal compilatore.
Alcuni possono sistemare una variabile di tipo char * inizializzata nel 
suddetto modo, in una zona di memoria dove, poi, non si possa 
modificarla, ma per quanto ne so, la tua considerazione è da ritenersi 
appropriata solo nel caso di variabili di tipo char *, non nel caso 
degli array di caratteri.
In altre parole, se dichiari una array di caratteri con la riga:
char str[] = "Ciao";
puoi star certo che il compilatore sistema il vettore in una zona di 
memoria in cui, eventualmente, puoi modificarlo.
Se, invece, inizializzi una variabile di tipo char * con la riga:
char *strPtr = "Ciao";
non puoi essere certo che il compilatore la sistemi in una zona di 
memoria dove, poi, puoi modificarla.
Marcello

 
be.. per i tipi primitivi e' cosi'.. ma per gli array la situazione
e' un po' diversa.. a grandi linee li puoi considerare come fossero
dei puntatori constanti.. puntatori, quindi.. e come tali non sono
altro che un indirizzo di memoria. Nel caso in cui l'area di
memoria a cui si riferisce questo puntatore contiene una sequenza
di caratteri, le cose si complicano un attimino.. infatti in C non
esiste un tipo primitivo per rappresentare le stringhe.. per questo
motivo non puoi assegnare una stringa ad un array di caratteri
(perche' costante), ma
devi usare una funzione per copiare ogni carattere formante la
stringa da una locazione all'altra.. strcpy (o un'altra funzione
della stessa famiglia)..
qualche esempio:
char *charpointer = null;
char chararray[100];
charpointer = chararray;   /* valido */
chararray = charpointer    /* non valido */
*charpointer = 'A';        /* valido */
*charpointer = "AAA";      /* non valido */
charpointer[3] = 'A';      /* valido */
++charpointer;             /* valido */
++chararray;               /* non valido */
-- 
                Roberto Nunnari -software engineer-
                     mailto:
ro...@nunnisoft.ch
 
http://www.nunnisoft.ch
   Residenza Boschetto 12           tel/fax: 
+41-91-6046511
   6935 Bosco Luganese        """    mobile: 
+41-76-3208561
   Switzerland               (o o)
========================oOO==(_)==OOo========================

 (perche' costante), ma
Puoi, ma solo in inializzazione.

 sbagliarmi.
No, per il vettore gli elementi sono SEMPRE modificabili.
Il caso a cui ti riferisci è, invece:
char *pippo = "Ciao a tutti";

 suddetto modo,
Assolutamente no.

compilatore che fa' questo?
   Con gcc su Solaris/Sparc si verifica sicuramente un 'segmentation
fault'. Comunque "Ciao" e` un 'const char *', il fatto che si possa
assegnarlo a un 'char *' senza warning o errori da parte del
compilatore dipende dalla storia del C...
   Modificare l'area puntata puo` funzionare oppure no, il fatto che
su alcune architetture sia consentito, non da` alcuna garanzia di
portabilita`.
   Per evitare simili errori, che possono capitare per distrazione,
sarebbe bene abituarsi a scrivere:
const char *strPtr = "Ciao";
   in maniera da essere avvisati dal compilatore, quando si tenta di
fare strPtr[0] = 'M', anche su architetture sulle quali puo`
funzionare.
-- 
S.L.

 
e allora spiegami questo:
-bash-2.05b$ cat prova4.c
#include <stdio.h>
int main() {
   char a[] = "paperino";
   printf( "*a: %c\n", *a );
   return 0;
}
-bash-2.05b$ gcc -o prova4 prova4.c
-bash-2.05b$ ./prova4
*a: p

    printf( "*a: %c\n", *a );
In questo caso, invece, a decade nel puntatore al primo elemento e
quindi il valore *a contiene il valore puntato.

 
hehehe.. non si finisce mai di imparare..  ;)

 
corretto.. e qui l'analogia calza.. ;) hehe
Comunque hai ragione tu.. la mia spiegazione contiene
affermazioni false. punto.
Ciao Andrea




ah bene, pensa che mi ricordavo il contrario... in effetti sono un po'
arrugginito
grazie del chiarimento!
ciao
Luca

 Assolutamente no.
Ma ultimamente vanno di moda gli array? <g>
Luca
-- 
Home: 
http://kronoz.cjb.net
"Ci sono le balle , le megaballe e le statistiche".
 Mark Twain

> Ma ultimamente vanno di moda gli array? <g>
Infatti....;-) mi sono rotto nel ripetere sempre le stesse cose.... mi
sa che mi faccio un HTML di spiegazione e lo pubblico sul mio sito ;-)

Andrea Laforgia wrote:

Assolutamente no... Cosa?
Marcello

Andrea Laforgia wrote:

E' la stessa cosa che ho detto io.
Marcello

 in una zona di memoria dove, poi, non si possa... 
Marcello

Andrea Laforgia wrote:

E che aspetti?
Marcello

 E' la stessa cosa che ho detto io.
Bravo ;-)
Mah....
Ad ogni modo avevi anche detto (per la parte prima) che dipendeva dal
compilatore :-(
Tommy

> E' la stessa cosa che ho detto io.
Non lo è.  A me è sembrato di capire che, rispondendo a Unlucky Luke,
circa l'allocazione di un vettore di caratteri e la sua
modificabilità, tu dicessi:
"Dipende dal compilatore.
Alcuni possono sistemare una variabile di tipo char * inizializzata
nel
suddetto modo, in una zona di memoria dove, poi, non si possa
modificarla,"
E questo non è vero.
"ma per quanto ne so, la tua considerazione è da ritenersi
appropriata solo nel caso di variabili di tipo char *, non nel caso
degli array di caratteri."
E questo è vero, ma contraddice quanto detto prima.

 E questo è vero, ma contraddice quanto detto prima.
Ammetto di non essere stato il re della chiarezza, ma anche sopra
parlavo di puntatori a carattere e non di array.
Cercherò di essere più sintetico e chiaro possibile:
chra * strPtr = "CIAO";
In questo caso si parla di mancato raggiungimento dell'obiettivo 
portabilita'.
char strV[] = "CIAO";
In questo caso l'obiettivo portabilita' è stato pienamente raggiunto.
Marcello

 compilatore :-(
E, AFAIK, lo confermo.
Marcello

 chra * strPtr = "CIAO";
Si deve sempre pensare che questa stringa sia non modificabile, anche
se alcuni compilatori te la lasciano modificare.

 Confondi solo le cose.
Mi spiace di averti confuso...
Marcello

 Mi spiace di averti confuso...
ROTFL ;-) Non confondi me: i concetti riguardo al C mi sono
chiarissimi.
Confondi chi pone le domande per avere dei chiarimenti.

 Confondi chi pone le domande per avere dei chiarimenti.
ROFTL.
La mia era una battuta, ma, se vuoi, la prossima volta, ti segnero' la
parte ironica delle frasi con delle faccine. ;)
Marcello

 spiegando qualcosa...
Io non riesco a capire su cosa hai da ridire.  Io NON STO dicendo le
STESSE cose.
Ti sto spiegando che rispondere, dicendo:
<quote>
"Dipende dal compilatore.
Alcuni possono sistemare una variabile di tipo char * inizializzata
nel
suddetto modo,"
</quote>
Ad una richiesta di chiarimenti su come è allocato una array è errato.

 Io non riesco a capire su cosa hai da ridire.
Non ho da ridire su nulla.
Il tutto, credo, sia nato da un malinteso originatosi da un mio 
scorretto modo di esprimermi.
Essere scortese e'l'ultima cosa che desidero.
Marcello

 Non vedo cosa ci sia di "fuori tema" o di "confusionale" in questa
risposta.
Non quotare quello che ti piace e charisci meglio quello che vuoi
dire, la prossima volta.  Nelle prime righe della tua risposta c'è
scritto "Dipende dal compilatore" e questo lascia presupporre che la
modificabilità di un *ARRAY* dipenda dal compilatore, cosa ovviamente
non vera.

 non vera.
Occhio Andrea...
Per un attimo ti si e' attivato il caps...
In ogni caso, credo che possa bastare.
Questa disucussione non porta da nessuna parte tantomeno alla chiarezza.
Oltretutto il tono che via, via utilizzi sta diventando ancor piu' 
ingiustificatamente ostile del tuo tono abituale.
Non trovo alcun piacere nel mostrare ostilita' nei confronti di nessuno.
Marcello

 Io te l'ho solo mostrato.
Tanto per chiarire.
Non era di quello che si parlava nei post *ORIGINALI*.
Punto e basta.