Cos'è ElectroYou | Login Iscriviti

ElectroYou - la comunità dei professionisti del mondo elettrico

[C] Informazione su getchar e vettori

Linguaggi e sistemi

Moderatori: Foto UtentePaolino, Foto Utentefairyvilje

0
voti

[1] [C] Informazione su getchar e vettori

Messaggioda Foto Utentetecfil » 25 ago 2013, 22:05

Ciao a tutti e buona serata!

Vorrei chiedervi un'informazione riguardo la funzione getchar del codice c.

Non ho ancora capito bene come funziona l'acquisizione dei caratteri nel vettore, e come far terminare il vettore con un carattere prefissato.

Prendiamo un esempio:
Acquisire da tastiera al massimo 10 numeri e memorizzarli in un vettore. Per terminare l'acquisizione digitare /. Il vettore deve inoltre terminare con il carattere nullo \0

Ho provato a scrivere il codice:
Codice: Seleziona tutto
#include <stdio.h>
#define DIM 10

int main ()
{
   
    char c, numeri[DIM];
    int i=0;

    while ((c=getchar())!='/' && i<DIM)
    {
        numeri[i++]=c;
    }
    numeri[i+1]='0';
   
    printf("Numeri: %s", numeri);
   
    return 0;
}


Tre cose non mi sono chiare!
1) perché se inserisco la sequenza: 123456 mi viene stampato 123456 e se invece inserisco la sequenza 0123456789/ mi viene stampato: 0123456789/0?
2) Come posso fare per non memorizzare il carattere di fine immissione /?
3) Se io inserisco la sequenza: 012345678912/ come mai mi viene stampato 012345678910, non dovrebbe essere sbagliato, in quanto il vettore numero ha dimensione 10, in questo caso invece mi viene stampato un vettore con dimensione 12!

Grazie mille, scusate ma ho un bel po' di confusione su questo argomento! Se un vettore ha dimensione 10, e chiedo di immettere numeri fino a quanto i è minore di 10, il programma non dovrebbe scartare tutti i numeri che non rientrano più nel vettore?

Ciaoo :-)
Il colmo per un elettricista? Essere isolato :D
Avatar utente
Foto Utentetecfil
327 1 5 6
Stabilizzato
Stabilizzato
 
Messaggi: 440
Iscritto il: 2 lug 2013, 21:41

3
voti

[2] Re: [C] Informazione su getchar e vettori

Messaggioda Foto UtenteDirtyDeeds » 25 ago 2013, 23:31

tecfil ha scritto:il programma non dovrebbe scartare tutti i numeri che non rientrano più nel vettore?


Il programma fa quello che gli dici di fare tu, quindi se ti sembra che non funzioni... don't blame the program! :mrgreen:

Innanzitutto, se tu vuoi poter immettere fino a 10 caratteri e poi vuoi terminare la sequenza di caratteri con un carattere nullo, il vettore deve poter contenere almeno 11 elementi, non 10 :!: (E con questa, è la terza volta che te lo dico "[#]" ).

Adesso, vediamo il ciclo while che hai scritto:

Codice: Seleziona tutto
   
while ((c=getchar())!='/' && i<DIM)
{
        numeri[i++]=c;
}


Innanzitutto, c'è un errore che ti avevo fatto già notare, c deve essere di tipo int, non di tipo char :!:
Poi, alla fine del ciclo, dopo aver letto il carattere '/', quanto vale i? Ogni volta che viene fatta l'assegnazione

Codice: Seleziona tutto
numeri[i++]=c;


i viene incrementata di 1, quindi dopo che viene letto l'ultimo numero numeri[i] è il carattere successivo all'ultimo numero immagazzinato. Ora se tu scrivi

Codice: Seleziona tutto
numeri[i+1]='0';


fai (ben) due errori: il primo è che numeri[i+1] si riferisce a due caratteri successivi all'ultimo immagazzinato, e il secondo è che tu stai memorizzando il carattere '0', non il carattere nullo '\0'. Cosa capita, allora? Inizialmente il vettore, non inizializzato, contiene immondizia, tra cui, magari, c'è anche qualche carattere nullo. Quando tu scrivi 123456/, nella stringa rimane memorizzato

Codice: Seleziona tutto
123456?0


dove il ? sta per qualunque carattere, che potrebbe anche essere il carattere nullo. Quando capita questo -per caso, non è garantito- il programma ti stampa 123456.

Quando scrivi 0123456789/, rischi che capiti un casino, potrebbe anche piantarsi il programma o formattarsi l'HD ( :mrgreen: ). Il motivo? In questo caso la sequenza memorizzata diventa

Codice: Seleziona tutto
0123456789?0


Ma: il carattere ignoto ? si trova oltre la fine del vettore e l'accesso oltre la fine di un vettore causa un comportamento indefinito. Ti è andata bene che non si è generato un errore grave, ma così non va.

Comunque, per effettuare input più sofisticati da tastiera o da file, può convenire usare la fgets, eventualmente in congiunzione con la sscanf.
It's a sin to write sin instead of \sin (Anonimo).
...'cos you know that cos ain't \cos, right?
You won't get a sexy tan if you write tan in lieu of \tan.
Take a log for a fireplace, but don't take log for \logarithm.
Avatar utente
Foto UtenteDirtyDeeds
55,9k 7 11 13
G.Master EY
G.Master EY
 
Messaggi: 7012
Iscritto il: 13 apr 2010, 16:13
Località: Somewhere in nowhere

0
voti

[3] Re: [C] Informazione su getchar e vettori

Messaggioda Foto Utentetecfil » 26 ago 2013, 11:37

Ciao!

Grazie come sempre per l'ottima spiegazione, mi rimangono solo due domande :mrgreen:

Ho aumentato la dimensione del vettore a 11, così posso memorizzare come ultimo carattere \0, ed inoltre interrompo il ciclo quando la i arriva a 10 (DIM-1).

La c deve essere di tipo int perché io voglio acquisire dei numeri giusto? Altrimenti se volevo acquisire dei caratteri dovevo lasciare la variabile di tipo char?

Ho tolto anche il +1, in effetti mi son dimenticato che avevo già incrementato la variabile :-) ed ho cambiato anche lo 0 con \0

Codice: Seleziona tutto
#include <stdio.h>
#define DIM 11

int main ()
{
   
    char numeri[DIM];
    int c, i=0;

    while ((c=getchar())!='/' && i<DIM-1)
    {
        numeri[i++]=c;
    }
    numeri[i]='\0';
   
    printf("Numeri: %s", numeri);
   
    return 0;
}


Adesso il programma dovrebbe essere giusto. Una sola cosa non mi è chiara, mettiamo il caso che voglia aggiungere in fondo al vettore un numero, ad esempio il 2. Ho già visto che cambiando \0 con 2 non va bene, che codice bisogna utilizzare in questo caso?

Grazie mille per l'aiuto
Ciaoo :-)
Il colmo per un elettricista? Essere isolato :D
Avatar utente
Foto Utentetecfil
327 1 5 6
Stabilizzato
Stabilizzato
 
Messaggi: 440
Iscritto il: 2 lug 2013, 21:41

2
voti

[4] Re: [C] Informazione su getchar e vettori

Messaggioda Foto UtenteDADO91 » 26 ago 2013, 12:02

tecfil ha scritto:La c deve essere di tipo int perché io voglio acquisire dei numeri giusto? Altrimenti se volevo acquisire dei caratteri dovevo lasciare la variabile di tipo char?

c deve essere di tipo int perché è quello il tipo che ritorna, basta che fai riferimento al manuale:
http://www.cplusplus.com/reference/cstdio/getchar/

If the standard input was at the end-of-file, the function returns EOF and sets the eof indicator (feof) of stdin.
If some other reading error happens, the function also returns EOF, but sets its error indicator (ferror) instead.

Il carattere EOF (End Of File) è definito come macro nella libreria stdio.h e solitamente corrisponde a -1.

tecfil ha scritto:mettiamo il caso che voglia aggiungere in fondo al vettore un numero, ad esempio il 2. Ho già visto che cambiando \0 con 2 non va bene, che codice bisogna utilizzare in questo caso?

Se nel vettore c'è ancora spazio, cioè c'è almeno una posizione libera dopo il fine stringa, basta che scrivi il numero al posto del finestriga e scrivi nuovamente il finestringa nella posizione successiva. Il punto è che se devi usare un array come stringa, per essere corretto, deve sempre contenere il finestringa (\0) altrimenti rischi dei segmentation fault.
Arduino + Meteo = TempDuino (Articoli)
www.dmdevs.com
Avatar utente
Foto UtenteDADO91
3.552 3 12 13
Expert EY
Expert EY
 
Messaggi: 965
Iscritto il: 27 feb 2009, 18:19
Località: Prov. di Firenze

0
voti

[5] Re: [C] Informazione su getchar e vettori

Messaggioda Foto UtenteDirtyDeeds » 26 ago 2013, 16:19

tecfil ha scritto:La c deve essere di tipo int perché io voglio acquisire dei numeri giusto? Altrimenti se volevo acquisire dei caratteri dovevo lasciare la variabile di tipo char?


Te l'avevo già spiegato qui ||O
It's a sin to write sin instead of \sin (Anonimo).
...'cos you know that cos ain't \cos, right?
You won't get a sexy tan if you write tan in lieu of \tan.
Take a log for a fireplace, but don't take log for \logarithm.
Avatar utente
Foto UtenteDirtyDeeds
55,9k 7 11 13
G.Master EY
G.Master EY
 
Messaggi: 7012
Iscritto il: 13 apr 2010, 16:13
Località: Somewhere in nowhere

0
voti

[6] Re: [C] Informazione su getchar e vettori

Messaggioda Foto Utentetecfil » 26 ago 2013, 21:58

Grazie mille :D

Chissà se per l'anno nuovo riuscirò a prendere mano con questo C :mrgreen:

Grazie per l'aiuto!
Ciao :-)
Il colmo per un elettricista? Essere isolato :D
Avatar utente
Foto Utentetecfil
327 1 5 6
Stabilizzato
Stabilizzato
 
Messaggi: 440
Iscritto il: 2 lug 2013, 21:41


Torna a PC e informatica

Chi c’è in linea

Visitano il forum: Nessuno e 13 ospiti