PDA

View Full Version : [c] ottenere frasi con scanf() come si fa?


PaSteam
14-05-2008, 10:55
salve ho un problemino
dovrei prendere da imput un frase composta da più parole e da spazi

usando scanf() mi sono accorto però che legge solo la prima parola della frase perchè incontrando lo spazio termina automaticamente l' acquisizione

come devo fare per ottenere una frase con diversi spazi da imput in c? (anche non utilizzando scanf va bene qualsiasi altra funzione che serva allo scopo)

compilatore usato gcc 4.1

71104
14-05-2008, 12:19
prova così:

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

int main()
{
char sz[32];
if (scanf("%32[^\n]", sz) != 1)
{
// gestione dell'errore
}

// ...

return 0;
}

PaSteam
14-05-2008, 13:36
grazie per l' aiuto cosi funziona ma poi viene prodotto un errore riprendo il tuo esempio

devo ottenere 2 frasi da input la prima va a buon fine ma la seconda frase non la fa inserire

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

int main()
{
char sz[32];
char sz1[20];

printf("inserisci la prima frase\n");
if (scanf("%32[^\n]", sz) != 1)
{
printf("\nerrore1\n");
}
printf("%s" , sz);
printf("\n inserisci la seconda frase");

//non mi fa scrivere la seconda frase il programma termine con errore2!!!!

if (scanf("%20[^\n]", sz1) != 1)
{
printf("\nerrore2\n");
}
printf("%s" , sz1);
// ...

return 0;
}

qualche soluzione?

dreadknight
14-05-2008, 18:43
Per leggere da tastiera una frase basta semplicemente usare una stringa e poi la funzione gets:

int main()
{
char s[50];

printf("Inserisci frase: "); /*termina l'inserimento dando l'invio*/
gets(s);


return 0;
}

PaSteam
14-05-2008, 19:21
perfetto utilizzando gets funziona tutto ma c'è un problema viene segnalato
un warning dove si dice che l' utilizzo di gets è pericoloso :muro:
purtroppo il mio programma non deve generare warning :muro:
il prof vuole cosi altrimenti non me lo accetta!!!

dreadknight
14-05-2008, 22:19
perfetto utilizzando gets funziona tutto ma c'è un problema viene segnalato
un warning dove si dice che l' utilizzo di gets è pericoloso :muro:
purtroppo il mio programma non deve generare warning :muro:
il prof vuole cosi altrimenti non me lo accetta!!!

di preciso che messaggio di warning ti dice?

io uso visual c++ e non mi dà nessun warning

khelidan1980
15-05-2008, 08:30
perfetto utilizzando gets funziona tutto ma c'è un problema viene segnalato
un warning dove si dice che l' utilizzo di gets è pericoloso :muro:
purtroppo il mio programma non deve generare warning :muro:
il prof vuole cosi altrimenti non me lo accetta!!!

più che altro devi stare attento che la stringa non superi i 50 caratteri(in questo esempio)

dreadknight
15-05-2008, 08:56
più che altro devi stare attento che la stringa non superi i 50 caratteri(in questo esempio)

quoto. e aggiungo che nel conteggio dei caratteri va anche aggiunto il terminatore di stringa ( '\0' ), che viene inserito automaticamente dal compilatore. Quindi, in quell'esempio, il numero di caratteri disponibili sono 49: se è questo il problema, basta sovradimensionare la stringa oppure usare l'allocazione dinamica, ma quest'ultima è una tecnica un po' più complessa e mi sembra che tu sia alle prime armi, quindi la lascerei perdere.

71104
15-05-2008, 10:05
quoto. e aggiungo che nel conteggio dei caratteri va anche aggiunto il terminatore di stringa ( '\0' ), che viene inserito automaticamente dal compilatore. Quindi, in quell'esempio, il numero di caratteri disponibili sono 49: se è questo il problema, basta sovradimensionare la stringa oppure usare l'allocazione dinamica, ma quest'ultima è una tecnica un po' più complessa e mi sembra che tu sia alle prime armi, quindi la lascerei perdere. il compilatore non c'entra nulla, il terminatore finale viene inserito dalla gets stessa.
gets è insicura perché non permette di stabilire una dimensione massima del buffer, e la deprecazione non dipende dalla versione di Visual C++ ma da quella del Windows SDK.

@PaStream: usa scanf che è più sicura; ora do un'occhiata al codice e vedo come mai da' errore.

71104
15-05-2008, 10:08
ho visto; non la fa inserire perché nello standard input è rimasto ancora il newline bufferizzato; solito odioso problema che non ho mai capito come risolvere.

edit - ho fatto una prova e ora sembra funzionare; la seconda scanf falla così:
scanf("\n%20[^\n]", sz1)

dreadknight
15-05-2008, 10:24
il compilatore non c'entra nulla, il terminatore finale viene inserito dalla gets stessa.


se non compili il codice, è difficile che ti appaia il terminatore :stordita:

PaSteam
15-05-2008, 11:22
di preciso che messaggio di warning ti dice?

io uso visual c++ e non mi dà nessun warning

io ottengo questo warning
utilizzando il compilatore gcc 4.1 con ubuntu

(.text+0x18b): warning: the `gets' function is dangerous and should not be used

.


più che altro devi stare attento che la stringa non superi i 50 caratteri(in questo esempio)

si ho fatto attenzione a questo la stringa inserita è + piccola

ho visto; non la fa inserire perché nello standard input è rimasto ancora il newline bufferizzato; solito odioso problema che non ho mai capito come risolvere.

edit - ho fatto una prova e ora sembra funzionare; la seconda scanf falla così:
scanf("\n%20[^\n]", sz1)

adesso si che funziona!!!! grazie tante
ma che spiegazione c'è?

71104
15-05-2008, 11:42
adesso si che funziona!!!! grazie tante
ma che spiegazione c'è? quando scrivi la prima stringa premi invio; la pressione non fa solo in modo che i caratteri bufferizzati (scritti sul terminale) fino a quel momento vengano dati in pasto alla scanf, ma ha anche l'effetto di bufferizzare un nuovo carattere \n (newline) che non viene consumato dalla prima scanf; quindi deve essere consumato dalla seconda prima che essa legga la seconda stringa, e quindi ho messo un \n come primo carattere del secondo format string.
può darsi che ci sia un sistema più ortodosso :stordita: