DOMANDA Come evitare che premendo un carattere il programma di creazione di una matrice non vada in loop

imparoilc

Nuovo Utente
2
0
Ciao a tutti, tra qualche tempo ho l'esame di fondamenti di informatica, e volevo sapere come posso fare in modo che se l'utente prema ad esempio 'a' al posto di inserire un numero intero, il programma non vada in loop in un ciclo for.

Perché come ben sapete con un programma del genere:

C++:
/*
Mostrare il valore inserito
*/

#include <iostream>

using namespace std;

int main () {

int a;

cout<<"\nInserire un valore intero.\n\n";

cin>>a;

cout<<"\n\nIl valore inserito \x8A: "<<a;


cout<<"\n\n\n";

system("pause");

}

Oppure uno del genere:

C++:
/*
Mostrare il valore inserito
*/

#include <iostream>

using namespace std;

int main () {

int a [5];

cout<<"\nInserire un valore intero.\n\n";

cin>>a[5];

cout<<"\n\nIl valore inserito \x8A: "<<a;


cout<<"\n\n\n";

system("pause");

}


Se si immette una lettera al posto di un numero intero, nel primo caso, il programma ritorna un valore 0, mentre nel secondo caso il valore in esadecimale del carattere.

Io allora avevo pensato di risolvere così nel primo caso:

C++:
/*
Mostrare il valore inserito
*/

#include <iostream>
#include <math.h>
#include <ctype.h>
#include <string.h>
#include <cstdio>
#include <stdlib.h>

using namespace std;

int main () {

char a [20];
int b;

do{

cout<<"\nInserire un valore intero.\n\n";


            cin.getline(a,20);

            b=atoi(a); //estraggo un valore intero dalla stringa


            if ((b==0)&&(a[20]!='0')) {

                cout<<"\n\nInserire un valore valido.\n\n";
                
                cout<<"\n\n------------------------------------------------------\n\n";

            }else{
            cout<<"\n\nIl valore da lei inserito \x8A: "<<b;
            }
           }while((b==0)&&(a[20]!='0'));

cout<<"\n\n\n";

system("pause");

}

E così nel secondo caso:

C++:
/*
Mostrare il valore inserito
*/

#include <iostream>
#include <math.h>
#include <ctype.h>
#include <string.h>
#include <cstdio>
#include <stdlib.h>

using namespace std;

int main () {

char a [20];
int b[20];

do{

cout<<"\nInserire un valore intero.\n\n";


            cin.getline(a,20);

            b[20]=atoi(a); //estraggo un valore intero dalla stringa


            if ((b[20]==0)&&(a[20]!='0')) {

                cout<<"\n\nInserire un valore valido.\n\n";
                
                cout<<"\n\n------------------------------------------------------\n\n";

            }else{
            cout<<"\n\nIl valore da lei inserito \x8A: "<<b[20];
            }
           }while((b[20]==0)&&(a[20]!='0'));

cout<<"\n\n\n";

system("pause");

}

In poche parole, inserire un ciclo do while ed acquisire prima il valore con un vettore char, poi da quest'ultimo convertire la stringa in un numero intero, e porre la condizione.

Mentre se lo inserisco in un programma del genere (per esempio creare una matrice), il programma mi va in loop:

C++:
/*
Data una matrice di dimensione uguale a 4 righe
per 4 colonne contenente elementi reali, scrivere
un programma in linguaggio C che mostri la matrice inserita
*/

#include <iostream>
#include <math.h>
#include <ctype.h>
#include <string.h>
#include <cstdio>
#include <stdlib.h>
#define righe 4
#define colonne 4

using namespace std;

int main () {
    int mat [righe+1] [colonne+1];
    char vett [20];
    int v;
    int i;
    int j;

    for (i=1;i<=colonne;i++) {

        for (j=1;j<=righe;j++) {
           do {
            cout<<"\nInserire il valore: "<<i<<","<<j<<"\n";

            cin.getline(vett,i);

            v=atoi(vett);

            if ((v==0)&&(vett[i]!='0')) {

                cout<<"\n\nInserire un valore valido.\n\n";
                
                cout<<"\n\n------------------------------------------------\n\n";

            }else{
            mat [i][j]=v;
            }
           }while((v==0)&&(vett[i]!='0'));
        }


    }

cout<<"\n\nLa matrice da lei inserita \x8A: \n\n";

for (i=1;i<=colonne;i++) {

    cout<<"\n";
    for (j=1;j<=righe;j++) {

        cout<<" "<<mat [i] [j];

    }

}


cout<<"\n\n\n";

system("pause");

}

Perciò vi chiedo: come posso risolvere?

I miei compagni di corso non si pongono proprio il problema, inseriscono direttamente che la matrice è composta da interi, ma a me sembra assurdo che non venga fatta una verifica delle variabili inserite.
Spiegate in maniera semplice perché sono agli inizi della programmazione ed ho abbastanza difficoltà.
Grazie in anticipo
 

imparoilc

Nuovo Utente
2
0
guarda le funzioni dentro l'header cctype per trovare la risposta :)

Magari sarò io stupido, ma non sono riuscito a trovare una soluzione.

Nel caso riformulo la domanda.

Come posso evitare che il seguente programma vada in loop? E perché va in loop?

C++:
/*
Data una matrice di dimensione uguale a 4 righe
per 4 colonne contenente elementi reali, scrivere
un programma in linguaggio C che mostri la matrice inserita
*/

#include <iostream>
#include <math.h>
#include <ctype.h>
#include <string.h>
#include <cstdio>
#include <stdlib.h>
#define righe 4
#define colonne 4

using namespace std;

int main () {
    int mat [righe+1] [colonne+1];
    char vett [20];
    int v;
    int i;
    int j;

    for (i=1;i<=colonne;i++) {

        for (j=1;j<=righe;j++) {
           do {
            cout<<"\nInserire il valore: "<<i<<","<<j<<"\n";

            cin.getline(vett,i);

            v=atoi(vett);

            if ((v==0)&&(vett[i]!='0')) {

                cout<<"\n\nInserire un valore valido.\n\n";
                
                cout<<"\n\n------------------------------------------------\n\n";

            }else{
            mat [i][j]=v;
            }
           }while((v==0)&&(vett[i]!='0'));
        }


    }

cout<<"\n\nLa matrice da lei inserita \x8A: \n\n";

for (i=1;i<=colonne;i++) {

    cout<<"\n";
    for (j=1;j<=righe;j++) {

        cout<<" "<<mat [i] [j];

    }

}


cout<<"\n\n\n";

system("pause");
 

rodhellas

Utente Èlite
1,522
427
CPU
Ryzen 5 3600
Dissipatore
GELID Phantom
Scheda Madre
MSI B450 Gaming Plus Max
HDD
500GB m.2 + 2TB HDD
RAM
16GB Corsair LPX 3000mhz
GPU
Gigabyte GTX 960 OC
Audio
Integrata
Monitor
SyncMaster 223BW
PSU
Antec HCG-520M
Case
Meshify C
Net
Gigabit Fastweb
OS
Windows 10 64bit
Di cctype devi usare il metodo isdigit(variabile desiderata).
Giusto @Marcus Aseth ?
 
  • Mi piace
Reazioni: Marcus Aseth

Marcus Aseth

Utente Attivo
404
138
OS
Windows 10
come dice @rodhellas , se l'user preme 'a' siccome non è un numero e tu vuoi che inserisca un numero, puoi controllare con quella funzione se si tratta di un numero o meno.

Inoltre se programmi in c++ sarebbe meglio se cambi i tuoi #include, ad esempio <ctype.h> cambialo con <cctype>, <string.h> cambialo con <string>, <math.h> con <cmath> e <stdlib.h> con <cstdlib>

Al momento non ho voglia di leggere il codice, ma posso dirti che cin è un oggetto di tipo std::istream , guarda la pagina in quel link per vedere quali funzioni puoi chiamare su quell'oggetto, in particolare peek(), fail(), eof(), ignore(), getline(), clear()

In particolare il problema che penso tu abbia sia quando fai il "cin >> n" e l'utente passa una cosa che non è un numero, in quel caso cin setta una flag interna che se non erro si chiama "failbit", che indica che l'input stream è corrotto e non funziona più come deve, puoi controllare lo stato di quella flag con cin.fail().
E se lo stream risulta essere corrotto, puoi "ripararlo" svutando gli input rimasti nel cin e poi usando clear(), che resetta il failbit allo stato "false", in questo modo il cin funziona di nuovo e probabilmente quella è la causa dei tuoi loop infiniti.
Ancora meglio, se usi cin.peek() in combo con isdigit(), puoi controllare il prossimo input dentro il tuo stream (peek vuoi dire sbirciare) senza però inserirlo in n e quindi evitando di compromettere lo stream nel caso l'input non sia un numero. Puoi usarla come condizione per costringere l'utente a ripetere fino a che non dà un input numerico.
 
Ultima modifica:

Hobet

Utente Attivo
609
222
CPU
i5 6600k
Dissipatore
AIO H100
Scheda Madre
ASUS z170 Deluxe
HDD
1 WD Blue 1 TB; evo 850 500gb
RAM
Vengeance 4x4
GPU
GTX 1070ti MSI
Audio
Nope
Monitor
MG278Q
Case
750D Corsair
Net
Fastweb 200/30
OS
PucyBuntu
Ciao a tutti, tra qualche tempo ho l'esame di fondamenti di informatica, e volevo sapere come posso fare in modo che se l'utente prema ad esempio 'a' al posto di inserire un numero intero, il programma non vada in loop in un ciclo for.

Perché come ben sapete con un programma del genere:

C++:
/*
Mostrare il valore inserito
*/

#include <iostream>

using namespace std;

int main () {

int a;

cout<<"\nInserire un valore intero.\n\n";

cin>>a;

cout<<"\n\nIl valore inserito \x8A: "<<a;


cout<<"\n\n\n";

system("pause");

}

Oppure uno del genere:

C++:
/*
Mostrare il valore inserito
*/

#include <iostream>

using namespace std;

int main () {

int a [5];

cout<<"\nInserire un valore intero.\n\n";

cin>>a[5];

cout<<"\n\nIl valore inserito \x8A: "<<a;


cout<<"\n\n\n";

system("pause");

}


Se si immette una lettera al posto di un numero intero, nel primo caso, il programma ritorna un valore 0, mentre nel secondo caso il valore in esadecimale del carattere.

Io allora avevo pensato di risolvere così nel primo caso:

C++:
/*
Mostrare il valore inserito
*/

#include <iostream>
#include <math.h>
#include <ctype.h>
#include <string.h>
#include <cstdio>
#include <stdlib.h>

using namespace std;

int main () {

char a [20];
int b;

do{

cout<<"\nInserire un valore intero.\n\n";


            cin.getline(a,20);

            b=atoi(a); //estraggo un valore intero dalla stringa


            if ((b==0)&&(a[20]!='0')) {

                cout<<"\n\nInserire un valore valido.\n\n";

                cout<<"\n\n------------------------------------------------------\n\n";

            }else{
            cout<<"\n\nIl valore da lei inserito \x8A: "<<b;
            }
           }while((b==0)&&(a[20]!='0'));

cout<<"\n\n\n";

system("pause");

}

E così nel secondo caso:

C++:
/*
Mostrare il valore inserito
*/

#include <iostream>
#include <math.h>
#include <ctype.h>
#include <string.h>
#include <cstdio>
#include <stdlib.h>

using namespace std;

int main () {

char a [20];
int b[20];

do{

cout<<"\nInserire un valore intero.\n\n";


            cin.getline(a,20);

            b[20]=atoi(a); //estraggo un valore intero dalla stringa


            if ((b[20]==0)&&(a[20]!='0')) {

                cout<<"\n\nInserire un valore valido.\n\n";

                cout<<"\n\n------------------------------------------------------\n\n";

            }else{
            cout<<"\n\nIl valore da lei inserito \x8A: "<<b[20];
            }
           }while((b[20]==0)&&(a[20]!='0'));

cout<<"\n\n\n";

system("pause");

}

In poche parole, inserire un ciclo do while ed acquisire prima il valore con un vettore char, poi da quest'ultimo convertire la stringa in un numero intero, e porre la condizione.

Mentre se lo inserisco in un programma del genere (per esempio creare una matrice), il programma mi va in loop:

C++:
/*
Data una matrice di dimensione uguale a 4 righe
per 4 colonne contenente elementi reali, scrivere
un programma in linguaggio C che mostri la matrice inserita
*/

#include <iostream>
#include <math.h>
#include <ctype.h>
#include <string.h>
#include <cstdio>
#include <stdlib.h>
#define righe 4
#define colonne 4

using namespace std;

int main () {
    int mat [righe+1] [colonne+1];
    char vett [20];
    int v;
    int i;
    int j;

    for (i=1;i<=colonne;i++) {

        for (j=1;j<=righe;j++) {
           do {
            cout<<"\nInserire il valore: "<<i<<","<<j<<"\n";

            cin.getline(vett,i);

            v=atoi(vett);

            if ((v==0)&&(vett[i]!='0')) {

                cout<<"\n\nInserire un valore valido.\n\n";

                cout<<"\n\n------------------------------------------------\n\n";

            }else{
            mat [i][j]=v;
            }
           }while((v==0)&&(vett[i]!='0'));
        }


    }

cout<<"\n\nLa matrice da lei inserita \x8A: \n\n";

for (i=1;i<=colonne;i++) {

    cout<<"\n";
    for (j=1;j<=righe;j++) {

        cout<<" "<<mat [i] [j];

    }

}


cout<<"\n\n\n";

system("pause");

}

Perciò vi chiedo: come posso risolvere?

I miei compagni di corso non si pongono proprio il problema, inseriscono direttamente che la matrice è composta da interi, ma a me sembra assurdo che non venga fatta una verifica delle variabili inserite.
Spiegate in maniera semplice perché sono agli inizi della programmazione ed ho abbastanza difficoltà.
Grazie in anticipo

1)Fermo restando che sistem("PAUSE") non va usato, stai dando per scontato che starai su windows all'esame.
2)Smettila di usare using namespace, tanto quando inizierai a lavorare te lo proibiranno dunque perchè non iniziare da adesso?
3)L'esercizio dice chiaramente di scriverlo in C ma lo hai scritto in C++ l'esame non te lo convalidano lo se fai cosi

Ritornando alla radice del problema. Molto spesso non è consentito usare librerie esterne all'esame, devi crearti tu una funzione che controlli l'input, l'approccio più semplice e logico per far ciò e basarsi sulla risposta dello scanf, visto che se non è un interno ritornerà zero, ti fai un loop infinito fin quando scanf non smette di ritornarti 0 e naturalmente ti pulisci il buffer. @rodhellas isdigit è errata usarla, perchè come parametro accetta un char dunque l'input non può superare le unità, perciò darà errore con numeri superiori a 9.

Il programma va in loop infinito perchè quando gli dai 'a' come carattere alla funzione scanf ti ritorna 0, ma mantiene il carattere 'a' nel buffer dunque alla prossima scanf si attiverà un effetto domino.

C:
#include "stdio.h"

void deflush(int ogg){
  while(ogg != '\n' && getchar() != '\n');
}

int main(void) {

  int a = 0;
  int check = 1;

  while(check){
    puts("inserici un intero");
    if(scanf("%d", &a) == 1){
     check = 0;
    }else {
      puts("\nti ho detto intero !!!!\n");
    }
    deflush(a);

  }



  return 0;
}
 
Ultima modifica:
  • Mi piace
Reazioni: Mursey

Ci sono discussioni simili a riguardo, dai un'occhiata!

Entra

oppure Accedi utilizzando
Discord Ufficiale Entra ora!

Discussioni Simili