PDA

Visualizza la versione completa : [C] Stringhe in input da tastiera


cristianc
17-05-2008, 12:01
Salve ho un problema con un pezzo di codice:

Devo prendere in input una stringa da tastiera,allora faccio questo semplice ciclo come ho visto da esempi:

int indice;
char str[512];
for (indice=0;( str[indice]=getchar() )!='\n';indice++);

ma pur non ricevendo errori in compilazione ed esecuzione,non mi viene permesso di inserire la stringa,nel senso che getchar e' come se fosse ignorato e passa al pezzo di codice successivo.Se fosse corretto mi permetterebbe di dare in input la stringa e semmai fare cose che non deve dopo averla digitata,non impedirmi di scriverla.

Secondo voi come mai succede questo.
Se conoscete un altro modo di ricevee la stringa in input da tastiera,ditemelo.
Ho provato gets ma da problemi in compilazione e fgets invece fa la stessa cosa di getchar.

menphisx
17-05-2008, 12:25
Prova cosė:


int indice;
char str[512];

/*"Svuota" stdin*/
while(!getchar());

for (indice=0;( str[indice]=getchar() )!='\n';indice++);


oppure:


int indice;
char str[512];

/*"Svuota" stdin*/
fflush(stdin);

for (indice=0;( str[indice]=getchar() )!='\n';indice++);

oregon
17-05-2008, 13:52
Devi inserire il terminatore nella stringa, ma il codice funziona



int main()
{
int indice;
char str[512];

for (indice=0;( str[indice]=getchar() )!='\n';indice++);
str[indice]=0;

printf("%s\n", str);

return 0;
}


Se hai altro codice prima o dopo che puo' influire, devi mostrarlo ...

cristianc
31-05-2008, 10:15
Ho eseguito il programma con le modifiche suggerite e non ricevo messaggi di errore ne' in compilazione ne' in esecuzione.
Quando il programma parte pero' con fflush(stdin) il programma non funziona,mentre con
/*"Svuota" stdin*/
while(!getchar());

l'istruzione while ottengo dei problemi e degli errori,insomma e' un po' buggoso,e quindi non fa proprio quello che deve fare.Pero' se lo tolgo il programma si non da errori ma ricomincia a non funzionare.
Qual'e' il significato esatto di quel while cosa fa di preciso analiticamente?
C'e' un modo alternativo per risolvere il problema?

(leggendolo cosi' mi sembra che si compia un ciclo che non fa niente che viene attivato fino a quando getchar()=0.)

oregon
31-05-2008, 10:41
Originariamente inviato da cristianc
Ho eseguito il programma con le modifiche suggerite e non ricevo messaggi di errore ne' in compilazione ne' in esecuzione.

Quale programma? Mostra sempre il codice piu' recente ...



Quando il programma parte pero' con fflush(stdin) il programma non funziona

Al solito ... "non funziona" non significa nulla ... cerca di essere preciso ...



mentre con
/*"Svuota" stdin*/
while(!getchar());

l'istruzione while ottengo dei problemi e degli errori

Ancora ... quali problemi? Quali errori?



insomma e' un po' buggoso

Buggoso?????


e quindi non fa proprio quello che deve fare.

Cioe'?


Pero' se lo tolgo il programma si non da errori ma ricomincia a non funzionare.

Non funzionare ... non significa nulla ...


Qual'e' il significato esatto di quel while cosa fa di preciso analiticamente?

Il while ripete la chiamata a getchar finche' la getchar restituisce un valore, ovvero c'e' un tasto nel buffer. Termina quando il buffer e' vuoto ...


C'e' un modo alternativo per risolvere il problema?

Ma QUALE problema?

cristianc
31-05-2008, 13:19
printf("In esecuzione l'opzione a..\n");
printf("Immettere dei numeri interi(separati da uno spazio): ");
for(indice=0;
( str[indice]=getchar() )!='\n';
indice++);
...
else printf("Input non valido.\n");
break

Questo pezzo di codice che e' all'interno di un programma piu grande produce dei problemi.Sospetto che quel while sia la causa di tutti i bug.Infatti se metto fflush(stdin) al suo posto ottengo il messaggio "input non valido".
Se tolgo while ecc.. ,e non scrivo nulla ottengo ancora "input non valido".
Se invece rimane il while ottengo dei risultati inaspettati nel programma.
La stringa di caratteri viene accettata ma si producono degli errori del tipo:

-per esempio eseguendo altre porzioni di codice viene riprodotta un'istruzione che fa parte sempre del programma ma che e' esterna ad esse.L'istruzione e':

default:
printf("Opzione inesistente\n");
break;

mentre se eseguo il codice in cima al post questo non succede,Mentre invece vorrei che non lo facesse anche per le altre parti del programma.

-del vettore di numeri che inserisco nella stringa,se provo a ordinarli tramite una parte di codice con quel while compare uno 0 mai digitato e scompare l'ultimo numero inserito

oregon
31-05-2008, 13:38
Lo mostri TUTTO il codice o no?

cristianc
31-05-2008, 17:07
Il while ripete la chiamata a getchar finche' la getchar restituisce un valore, ovvero c'e' un tasto nel buffer. Termina quando il buffer e' vuoto ...
Io ho capito che la funzione getchar,che non prende parametri,o meglio,come parametro usa void,blocca il programma e aspetta un carattere da tastiera mettendolo in un buffer.
Qualunque altro carattere segue viene messo nel buffer fino a quando non si digita invio.
A quel punto la funzione cede il controllo al programma e restituisce un intero che corrisponde al primo carattere digitato.Pero' ancora non ne ho capito l'uso nella condizione. !getchar equivale a non getchar.Oppure !getchar significa getchar=0.
Ma getchar=0 in realta' a quale corrisponde,dato che e' gia presente nel ciclo for?

Di seguito riporto il contenuto di quello che fa il programma:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <malloc.h>
#include <ctype.h>
void reverse(char s[]) {
int c, i, j;
for (i = 0, j = strlen(s)-1; i<j; i++, j--) {
c = s[i];
s[i] = s[j];
s[j] = c;
}
}

void itoa(int n,char s[]) {
int i,segno;
if ((segno=n) < 0)
n= -n; i=0; do {
s[i++]= n % 10 + '0';
} while ((n /= 10) > 0);
if (segno < 0) s[i++]= '-';
s[i]= '\0'; reverse(s);
}

int ParseString(char * s, int * a, int * nMin, int * nMax) {
int nRet = 0;
int i = 0;
int j = 0;
char strInt[12];
int num;
while ( 1 ) {
/* if ( isdigit( *(s + i) ) ) {
*(strInt + j) = *(s + i);
++j;
} */
if ( isdigit( *(s + i) ) || *(s + i) == '-' ) {
if ( (*(s + i) == '-') && (i > 0) ) {
if ( *(s + i - 1) != ' ' ) return 0;
}
*(strInt + j) = *(s + i);
j++;
}
else if ( *(s + i) == ' ' || *(s + i) == '\n' ) {
*(strInt + j) = '\0';
if ( strlen(strInt) > 0 ) {
if ( a ) {
num = atoi(strInt);
a[nRet] = num;
if ( nRet == 0 ) {
*nMin = num;
*nMax = num;
}
else {
*nMin = num < *nMin ? num : *nMin;
*nMax = num > *nMax ? num : *nMax;
}
}
++nRet;
j = 0;
*strInt = '\0';
}
}
else {
return 0;
}
if ( *(s + i) == '\n' ) break;
++i;
}
return nRet;
}

void BubbleSort(int * pInt, int Count)
{
register int a, b;
register int temp;
for (a = 1; a < Count; ++a) {
for (b = Count; b >= a; --b) {
if ( pInt[b - 1] > pInt[b] ) {
temp = pInt[b - 1];
pInt[b - 1] = pInt[b];
pInt[b] = temp;
}
}
}
}

main()
{
int * pInt = NULL;
int Count = 0;
char str[512];
int nMin, nMax;
int indice,k;
char strArray[512];
char strNum[12];
char x;
printf("\n\tMENU DI PROVA\n\n\ta) Per immettere dati\n\tb) Per determinare il maggiore\n\tc) Per determinare il minore\n\td) Per ordinare\n\te) Per visualizzare\n\n");
printf("[PER USCIRE PREMERE q]\t\tScelta(a,b,c,d,e): ");
x=getchar();
do{
fflush(stdin);
switch(x) {
case 'a':
while(!getchar());
printf("In esecuzione l'opzione a..\n");
printf("Immettere dei numeri interi(separati da uno spazio):");
for(indice=0;( str[indice]=getchar() )!='\n';indice++);
Count = ParseString(str, NULL, NULL, NULL);
if ( Count > 0 ) {
if ( pInt ) free(pInt);
pInt = (int*)malloc(Count * sizeof(int));
if ( !pInt ) {
printf("Memoria insufficiente.\n");
break;
}
ParseString(str, pInt, &nMin, &nMax);
printf("Totale numeri immessi: %d\nUltimo numero immesso: %d\n", Count, pInt[Count - 1]);
}
else printf("Input non valido.\n");
break;
case 'b':
printf("In esecuzione l'opzione b..\n");
printf("Il maggiore é: %d",nMax);
break;
case 'c':
printf("In esecuzione l'opzione c..\n");
printf("Il minore é: %d",nMin);
break;
case 'd':
printf("In esecuzione l'opzione d..\n");
if ( Count > 0 ) {
BubbleSort(pInt, Count);
printf("Array ordinato:\n");
strcpy(strArray, "");
for ( k = 0; k < Count; k++ ) {
itoa(pInt[k], strNum);
strcat(strArray, strNum);
strcat(strArray, " ");
}
printf(strArray);
}
else {
printf("L'array e' vuoto.\n");
}
break;
case 'e':
printf("In esecuzione l'opzione e..\n");
if ( Count > 0 ) {
printf("Numeri immessi:\n");
strcpy(strArray, "");
for ( k = 0; k < Count; k++ ) {
itoa(pInt[k], strNum);
strcat(strArray, strNum);
strcat(strArray, " ");
}
printf(strArray);
}
else {
printf("L'array e' vuoto.\n");
}
break;
default:
printf("Opzione inesistente\n");
break;
}
printf("\n");
printf("\n\tMENU DI PROVA\n\n\ta) Per immettere dati\n\tb) Per determinare il maggiore\n\tc) Per determinare il minore\n\td) Per ordinare\n\te) Per visualizzare\n\n");
printf("[PER USCIRE PREMERE q]\t\tScelta(a,b,c,d,e): ");
x = getchar();
}
while(x!='q');
if(pInt) free(pInt);
}

oregon
31-05-2008, 17:14
Diciamo che ho copiato e compilato il tuo programma ... lo eseguo ... cosa devo fare per capire dove hai i problemi di cui lamenti ...?

cristianc
31-05-2008, 17:25
Il programma,almeno nelle mie intenzioni,fara' apparire un menu in cui necessariamente sceglieremo per prima l'opzione a che mi chiedera' di inserire degli interi.
Dopo aver digitato un numero arbitrario di numeri e aver premuto invio,si potranno usare anche le altre opzioni:b e c che permettono di ricevere in output il maggiore o il minore tra i numeri del vettore.
Gia si notera' che se si digita b e c(ma anche d ed e) compare la scritta opzione inesistente.
L'opzione e invece li visualizzera' ,scegliendo d invece verrano ordinati.Uno degli effetti indesiderato e' la scomparsa dell'ultimo numero digitato in immissione e la comparsa nel vettore invece del numero 0 che pero non e' stato digitato quando si e' scelto a.

Loading