PDA

View Full Version : [C] perchè questo semplice programma non funziona?


The-Revenge
11-11-2009, 12:11
ciao ragazzi, ho fatto questo semplice programma come esercitazione per il C, e l'ho compilato con devc++, su vista. Il programma serve a controllare il numero di vocali e di consonanti in una parola di 10 lettere. I dubbi sono 2 : il primo è perchè non funziona inserendo la parola lunga esattamente 10 lettere (mi restituisce un valore inesatto, mentre se inizializzo le variabili a 0 mi da un valore di vocali sempre uguali a 0, e questo non capisco come sia possibile dato che le variabili se non vengono inizializzate si inizializzano da sole a 0).
COme domanda "facoltativa" vorrei chiedervi perchè se inserisco un numero minore di 10 lettere il programma non funziona...ovvero non viene eseguito nemmeno il calcolo...
ecco il codice

#include<stdio.h>
#include<stdlib.h>
main(){
char v[10];
int count, cons;

printf("\n inserisci parola");
scanf("%c%c%c%c%c%c%c%c%c%c",&v[0],&v[1],&v[2],&v[3],&v[4],&v[5],&v[6],&v[7],&v[8],&v[9]);
for(int i=0;i<10;i++)if((v[i]='a')||(v[i]='e')||(v[i]='i')||(v[i]='o')||(v[i]='u'))count++;
cons=10-count;
printf("\n il numero delle vocali e' %d. Il numero delle consonanti e' %d",count,cons);
system("PAUSE");
return(0);
}

Torav
11-11-2009, 12:23
Allora, un paio di cose:


Le stringhe in C devono terminare col "carattere di fine stringa" ('\0') e quindi se dichiari un char[10] avrai solamente 9 lettere a disposizione
Se proprio vuoi utilizzare scanf (che ha qualche problemino) allora utilizza "%s" che legge da tastiera direttamente una stringa e ti inserisce alla fine dell'array di char il carattere di fine stringa di cui sopra:


scanf("%s", v);


Per fare il ciclo sull'array e controllare quante vocali contiene ti conviene utilizzare un while (che fa uscire dal ciclo quando il carattere che si sta controllando è quello di fine stringa, '\0'), oppure un for che va da 0 alla lunghezza della stringa che puoi ottenere dalla funzione strlen presente in <string.h>

The-Revenge
11-11-2009, 12:53
Allora, un paio di cose:


Le stringhe in C devono terminare col "carattere di fine stringa" ('\0') e quindi se dichiari un char[10] avrai solamente 9 lettere a disposizione
Se proprio vuoi utilizzare scanf (che ha qualche problemino) allora utilizza "%s" che legge da tastiera direttamente una stringa e ti inserisce alla fine dell'array di char il carattere di fine stringa di cui sopra:


scanf("%s", v);


Per fare il ciclo sull'array e controllare quante vocali contiene ti conviene utilizzare un while (che fa uscire dal ciclo quando il carattere che si sta controllando è quello di fine stringa, '\0'), oppure un for che va da 0 alla lunghezza della stringa che puoi ottenere dalla funzione strlen presente in <string.h>

ti ringrazio...ti speigo però, io le stringhe non le ho ancora fatte, quindi più che un fatto di efficenza volevo fare il rpogramma con le mie conoscenze fino a questo momento...e visto che l'esercizio è sul libro propio in quel punto, suppongo che nn abbia bisogno di altri strumenti se non quellic he già possiedo fino a quel punto del libro.
A quanto ho capito quindi per avere una parola di lungheza variabile devo usare le stringhe, che nn sò usare. Volendo quindi mantenere la parola fissa a 10 lettere, senza usare le stringe, cosa sbaglio nel programma?
Ho anche provato a stampare i valori dell'aray e non mi restutisce le lettere che ho inserito, ma dei numeri (che suppongo siano i numeri corrispondenti alle lettere nell'ascii).

Comunque, volevo tralasciare questo programma che comunque ha delle nozioni di stringhe che nn ho fatto, volevo farvi vedere uno più interessante che non capisco dove sia l'errore :

dato un vettore v1 e un numero K trovare l'elemento del vettore più prossimo a K.
La mia tecnica è stata quella di sottrarre K a ogni elemento di v1, prendere il valore assoluto e metterlo in una variabile temporanea, e poi confrontarlo con quella successiva, che se è minore (in valore assoluto) mi prendeva il corrispettivo elemento del vettore.
Tuttavia non mi esce il risultato, sebbene abbia fatto una prova su carta con delle tabella e mi esce.
Ecco il codice :
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
int dim();
main(){
const int n=dim();
int v1[n],k,prox;
unsigned int temp,min;
int max;
printf("\n inserisci massimo valore degli elementi del vettore");
scanf("%d",&max);
srand(time(NULL));
for(int i=0;i<n;i++)v1[i]=rand()%max;
printf("\n il vettore v1 e' : ");
for(int i=0;i<n;i++)printf("%d ",v1[i]);
printf("\n\n Inserisci il valore di K \n ");
scanf("%d",&k);
min=v1[0]-k;
for(int i=0;i<n;i++){
temp=v1[i]-k;
if(temp<min){
min=temp;
prox=v1[i];
}

}
printf("\n l'elemento di v1 piu vicino a K e' %d \n",prox);
system("PAUSE");
return(0);
}









int dim(){
int n;
printf("\n inserisci la lunghezza dei vettori");
scanf("%d",&n);
while(n<0){
printf("\n reinserisci la lunghezza dei vettori");
scanf("%d",&n);
}
return n;
}




EDIT : apposto mi è uscito, ho sostituito l'IF con un while...solo che non riesco a capire perchè funziona : io pensavo che il l'if facesse l'operazione quando la condizione è vera, mentre il while quando è falsa ed esce quando è vera, operando questa sostituzione senza cambiare il segno della disequazioni mi doveva comportare un errore, o sbaglio?
EDIT2 : mi corrego di nuovo, non funziona. Non so se è problema di vista (devcpp nn è supportato da vista) però prima aveva iniziato a funzionare, l'ho rpovato 5 volte e funzionava, ora ho chiuso e riaperto e non funziona

The-Revenge
11-11-2009, 17:58
dai raga aiuto

Mesh89
11-11-2009, 19:03
su vista

Che sia questo? :P


Scherzi a parte, innanzitutto è fattibile che ti escano risultati a volte giusti a volte sbagliati: il contenuto dell'array creato con numeri casuali è sempre diverso, quindi potresti avere un bug che si verifica solo in determinate condizioni.

A una prima occhiata, noto che nel codice non usi il valore assoluto nel fare la differenza. Questo per cominciare potrebbe essere un problema.

Prova a compilare questo codice:

#include <iostream>

using namespace std;


int main() {
unsigned int n;

n = -3;

cout << n << endl;
}

e vedrai che non stamperà 3.

The-Revenge
11-11-2009, 19:46
Che sia questo? :P


Scherzi a parte, innanzitutto è fattibile che ti escano risultati a volte giusti a volte sbagliati: il contenuto dell'array creato con numeri casuali è sempre diverso, quindi potresti avere un bug che si verifica solo in determinate condizioni.

A una prima occhiata, noto che nel codice non usi il valore assoluto nel fare la differenza. Questo per cominciare potrebbe essere un problema.

Prova a compilare questo codice:

#include <iostream>

using namespace std;


int main() {
unsigned int n;

n = -3;

cout << n << endl;
}

e vedrai che non stamperà 3.

quindi che comando devo usare per il valore assoluto? abs?

wizard1993
11-11-2009, 19:50
quindi che comando devo usare per il valore assoluto? abs?

esattamente

The-Revenge
11-11-2009, 19:52
ho usato il comando ABS ma il problema si ripete, ho dei valori esatti a volte, e a volte sbagliati. Ecco il codice :

#include<stdio.h>
#include<stdlib.h>
#include<time.h>
int dim();
main(){
const int n=dim();
int v1[n],k,prox;
int temp,min;
int max;
printf("\n inserisci massimo valore degli elementi del vettore");
scanf("%d",&max);
srand(time(NULL));
for(int i=0;i<n;i++)v1[i]=rand()%max;
printf("\n il vettore v1 e' : ");
for(int i=0;i<n;i++)printf("%d ",v1[i]);
printf("\n\n Inserisci il valore di K \n ");
scanf("%d",&k);
min=v1[0]-k;
min=abs(min);
for(int i=1;i<n;i++){
temp=v1[i]-k;
temp=abs(temp);
if(temp<min){
min=temp;
prox=v1[i];
}

}
printf("\n l'elemento di v1 piu vicino a K e' %d \n",prox);
system("PAUSE");
return(0);
}









int dim(){
int n;
printf("\n inserisci la lunghezza dei vettori");
scanf("%d",&n);
while(n<0){
printf("\n reinserisci la lunghezza dei vettori");
scanf("%d",&n);
}
return n;
}

Mesh89
11-11-2009, 20:21
Mi sono permesso di riscriverlo in modo (a mio parere) più comprensibile:

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

int dim() {
int n;
printf("Inserisci la lunghezza dei vettori: ");
scanf("%d",&n);
while (n < 0) {
printf("Reinserisci la lunghezza dei vettori: ");
scanf("%d", &n);
}
return n;
}


int main() {
const int n = dim();
int v1[n], k, prox;
int temp, min;
int max;
srand(time(NULL));

printf("Inserisci massimo valore degli elementi del vettore: ");
scanf("%d",&max);

for (int i = 0; i < n; i++) {
v1[i] = rand() % max;
}

printf("Il vettore v1 e': ");
for (int i = 0; i < n; i++) {
printf("%d ", v1[i]);
}
printf("\n");

printf("Inserisci il valore di K: ");
scanf("%d", &k);
min = abs(v1[0] - k);

for (int i = 1; i < n; i++) {
temp = abs(v1[i] - k);
if (temp < min) {
min = temp;
prox = v1[i];
}
}

printf("L'elemento di v1 piu vicino a K e' %d \n", prox);
system("PAUSE");
return 0;
}

Ho provato a compilarlo ed eseguirlo (Ubuntu + GCC 4.4), ma non riesco a farlo sbagliare. Puoi segnarti i valori dell'array e k di un'esecuzione sbagliata?

The-Revenge
11-11-2009, 23:28
Mi sono permesso di riscriverlo in modo (a mio parere) più comprensibile:

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

int dim() {
int n;
printf("Inserisci la lunghezza dei vettori: ");
scanf("%d",&n);
while (n < 0) {
printf("Reinserisci la lunghezza dei vettori: ");
scanf("%d", &n);
}
return n;
}


int main() {
const int n = dim();
int v1[n], k, prox;
int temp, min;
int max;
srand(time(NULL));

printf("Inserisci massimo valore degli elementi del vettore: ");
scanf("%d",&max);

for (int i = 0; i < n; i++) {
v1[i] = rand() % max;
}

printf("Il vettore v1 e': ");
for (int i = 0; i < n; i++) {
printf("%d ", v1[i]);
}
printf("\n");

printf("Inserisci il valore di K: ");
scanf("%d", &k);
min = abs(v1[0] - k);

for (int i = 1; i < n; i++) {
temp = abs(v1[i] - k);
if (temp < min) {
min = temp;
prox = v1[i];
}
}

printf("L'elemento di v1 piu vicino a K e' %d \n", prox);
system("PAUSE");
return 0;
}

Ho provato a compilarlo ed eseguirlo (Ubuntu + GCC 4.4), ma non riesco a farlo sbagliare. Puoi segnarti i valori dell'array e k di un'esecuzione sbagliata?
ho provato a runnare il tuo programma nel mio PC ed effettivamente funziona...cosi ho letto le differenze tra il mio e il tuo, ma apparte qualche correzione di stile e di pulizia (come l'abs direttamente dopo l'uguale, che io nn avevo messo perchè ero nel dubbio che si potesse fare) non ci sono sostanizali differenze, anzi quasi direi nessun, se non che inizializzi la funzione dim() all'inizio e non alla fine...
non so perchè non dovrebbe funzionare...cmq ecco alcuni valori per cui mi restituisce un errore (col mi programma) :
il vettore v1 è 4 7 4 6 7
k è 5

l'elemento eccc ecc è 63

un altro :
0 4 0 2 0
k è 1
l'elemento ecc ecc è 63

però tra il primo e l'ultimo errore me ne ha fatto un sacco corrette...anche con numeri ripetuti...bhò

Mesh89
12-11-2009, 17:58
Devi inizializzare prox: nel caso l'elemento più vicino sia il primo, ha valore casuale.

The-Revenge
13-11-2009, 14:48
ok...per inizializzare dici metterlo =0?
Comunque non ci sto capendo più niente con devcpp, ho fatto un programma sul PC del mio amicoc he ha windows XP, mentre sul mio computer che ha windows vista mi dice che ha smesso di funzionare quando lo avvio,nonostante abbia cinluso delle libreria necessarie per windows vista (cercando con google)

Mesh89
15-11-2009, 10:00
No, dovresti inizializzarlo a v1[0]. Non so perchè su diversi SO si comporti in modi diversi, ma io fossi in te non starei a sbatterci più di tanto la testa ;)

The-Revenge
15-11-2009, 10:13
No, dovresti inizializzarlo a v1[0]. Non so perchè su diversi SO si comporti in modi diversi, ma io fossi in te non starei a sbatterci più di tanto la testa ;)
e si infatti...sono passato oltre e ho fatto altri esercizi...quello che mi fà arrabbiare e che ho fatto esercizi più difficili, l'ultimo dei quali con un vettore a 3 dimensioni, e funzionano perfettamente, invece questi danno qualche piccolo problema....che nn riesco a trovare....vabbè pazienza

ad esempio questo programma facilissimo io non capisco perchè non funziona, mi dà "inserire 2a lettere" e "inserire 3a lettera" tuttto attaccato e me ne fa inserire una sola...

#include<stdio.h>
#include<stdlib.h>
main(){
char v[10];
int count=0, cons=0,k=0;
for(int i=0;i<10;i++){
k=i;
printf("\n inserisci %da lettera: ",k+1);
scanf("%c",&v[i]);
}
printf("\n la parola e' :");
for(int i=0;i<10;i++)printf("%c",v[i]);
for(int i=0;i<10;i++)if((v[i]=='a')||(v[i]=='e')||(v[i]=='i')||(v[i]=='o')||(v[i]=='u'))count++;
cons=10-count;
printf("\n il numero delle vocali e' %d. Il numero delle consonanti e' %d",count,cons);
system("PAUSE");
return(0);
}

Mesh89
15-11-2009, 10:36
Fatti stampare il codice ASCII dei caratteri invece dei caratteri stessi, e capirai abbastanza presto il perchè.

The-Revenge
15-11-2009, 10:46
Fatti stampare il codice ASCII dei caratteri invece dei caratteri stessi, e capirai abbastanza presto il perchè.
e scusa la niubezza, come si fa? :stordita:

Mesh89
15-11-2009, 11:53
e scusa la niubezza, come si fa? :stordita:

Tranquillo. Lo devi stampare come fosse un intero, quindi con %d.