PDA

Visualizza la versione completa : [C] problema con grandezza stringa


cianeddu
12-12-2012, 19:47
salve a tutti..sono nuovo nel forum..mi sono iscritto perchè spero che qualcuno possa aiutarmi a risolvere un paio di problemi con un programma in C...il programma è questo :"Sia dato un file, il cui nome viene passato come parametro sulla linea di comando, che contiene la descrizione di un insieme di rettangoli posizionati su una matrice di punti. Sia definito sulla matrice un sistema di coordinate cartesiane dove ciascuna coordinata e' un numero intero che varia da 0 a N estremi inclusi, l’origine e' il punto in alto a sinistra e le coordinate aumentano da sinistra a destra e dall’alto al basso. N e' una costante nota a priori e definita attraverso una direttiva define. Ogni riga del file contiene la descrizione di un rettangolo nel seguente formato:
<x1> <y1> <x2> <y2>
dove (<x1>, <y1>) sono le coordinate del punto in alto a sinistra del rettangolo mentre (<x2>, <y2>) sono le coordinate del punto in basso a destra (quindi x1 x2 e y1 y2).
Il numero totale di rettangoli (ovvero di righe del file) non e' noto a priori. Non assumere alcun tipo di ordinamento delle righe stesse.
Scrivere un programma in C per verificare che tutti i rettangoli descritti nel file siano privi di sovrapposizioni (occupino cioè caselle della griglia disgiunte). Il programma deve controllare il file il cui nome viene passato sulla linea di comando, posizionare i rettangoli nella matrice e scrivere il messaggio “Nessuna sovrapposizione tra i rettangoli” se il file soddisfa il criterio oppure “I rettangoli hanno (almeno) una sovrapposizione” in caso contrario. In caso di errore nel formato del file (interi non compresi tra 0 e N, o tali da non soddisfare le relazioni d’ordine previste) il programma deve produrre il messaggio “Errore nel formato del file” ed interrompere l’esecuzione.".......
.....questo è il mio programma ..nella prima parte creo il file che poi andrò ad analizzare in lettura


#include <stdio.h>
#include <stdlib.h>
#define N 100
int main(int argc,char *argv[])
{
int i,j,r,l,x1,y1,x2,y2,flag,s;
char str[12],matrice[N][N];
FILE*fp;
fp=fopen("rett.txt","w");


if(fp==NULL){

printf ("\nerrore apertura file in write\n");

return -1;



}



for(i=0;i<5;i++){

printf("\nscrivi quattro numeri intervallati da spazio di massimo 2 cifre ciascuno \n");

gets(str);
fprintf(fp,"%s\n",str);


}



r=fclose(fp);
if(r==EOF){

printf("\nerrore chiusura file in write\n");
return -2;


}

if(argc!=2){

printf("\nerrore numero di parametri passati da linea di comando\n");

return -3;

}
fp=fopen(argv[1],"r");
if(fp==NULL){

printf("\nerrore apertura file in read\n");

return-4;


}
for(i=0;i<N;i++){

for(j=0;j<N;j++){
matrice[i][j]='_';



}

}






flag=0;
s=1;
while(fgets(str,12,fp)!=NULL){

l=sscanf(str,"%d %d %d %d",&x1,&y1,&x2,&y2);
printf(" num par=%d in pos %d\n",l,s);
if(l!=4){

printf("\nerrore nella formattazione dei parametri da stringa ad interi:num par= %d in pos %d\n",l,s);
return -5;



}
s++;

if(x1>=x2||y1>=y2||x1<0||x1>=N||y1<0||y1>=N||x2<0||x2>=N||y2<0||y2>=N){

printf("\nerrore nel formato del file\n");
return -6;


}

for(i=x1;i<=x2;i++){

for(j=y1;j<=y2;j++){



if(matrice[i][j]=='_')
matrice[i][j]='1';
else{
matrice[i][j]='2';
flag=1;


}





}



}

}
r=fclose(fp);
if(r==EOF){
printf("\nerrore chiusura file in read\n");
return -7;





}
if(flag==0)
printf("\nnon ci sono sovrapposizioni\n");
else
printf("\nc'e' almeno una sovrapposizione\n");



for(i=0;i<N;i++){

for(j=0;j<N;j++){
if(matrice[i][j]!='_')
printf("\nmatrice[%d][%d]=%c\n",i,j,matrice[i][j]);
}



for(i=0;i<N;i++){

printf("\n");


for(j=0;j<N;j++)

printf("%c",matrice[i][j]);

}
}
return 0;

}
l'errore sta nel fatto che se io metto 4 numeri di massimo 2 cifre uno spazio per ogni numero e alla fine un ritorno a capo..sono 12 caratteri ma mi da un errore mentre se aumento la grandezza della stringa che deve ricevere i i dati in lettura del file va tutto bene..anche se a me sembra che siano proprio 12 i caratteri...inoltre il contatore quella 's',funziona male non so perchè mi mette una posizione in più..io lo faccio partire da uno e ogni volta che passo la possibiltà di errore lo incremento..quindi ricapitolando se metto 4 numeri di 2 cifre ciascuno con spazio tra i numeri e \n finale questo è l'effetto


scrivi quattro numeri intervallati da spazio di massimo 2 cifre ciascuno
warning: this program uses gets(), which is unsafe.

11 22 33 44

scrivi quattro numeri intervallati da spazio di massimo 2 cifre ciascuno
1 2 3 4

scrivi quattro numeri intervallati da spazio di massimo 2 cifre ciascuno
1 2 3 4

scrivi quattro numeri intervallati da spazio di massimo 2 cifre ciascuno
1 2 3 4

scrivi quattro numeri intervallati da spazio di massimo 2 cifre ciascuno
1 2 3 4
num par=4 in pos 1
num par=-1 in pos 2

errore nella formattazione dei parametri da stringa ad interi:num par= -1 in pos 2
come vedete la posizione non corrisponde anche se è la prima lui segna la seconda
.....grazie a tutti

oregon
12-12-2012, 21:24
Inserisci i tag CODE perché non si riesce a seguire il codice ...

MItaly
12-12-2012, 21:36
Originariamente inviato da oregon
Inserisci i tag CODE perché non si riesce a seguire il codice ...
:mem:
inoltre, nel titolo va indicato il linguaggio di riferimento come "tag"; qui ho sistemato tutto io, dai un'occhiata al regolamento (http://forum.html.it/forum/showthread.php?s=&threadid=973887) per evitare di fare questi errori in futuro.
:ciauz:

cianeddu
13-12-2012, 12:34
si scusate ..giustamente non si capisce niente..adesso la rimetto meglio

ZioLuffio
13-12-2012, 13:16
Ho 2 domande sciocche per te:
1- Perché scrivi i numeri nel file attraverso il programma e non semplicemente aprendo e salvando il file, visto che nessuno ti ha chiesto di fare in quel modo?
2- Perché fai la boiata di usare una dannatissima gets() quando risolveresti in due secondi con una fscanf("%d%d%d%d", &x1, &y1, &x2, &y2); ?

cianeddu
13-12-2012, 13:30
allora..lo faccio attraverso il programma per essere sicuro di non lasciare spazi strani che mi "incasinerebbero" la grandezza della stringa..
per quanto riguarda la gets() me la ricordo meglio..devi contare che questo è un compito d'esame della mia università,quindi in teoria il file esiste già,io dovrei fare solo la seconda parte quella di lettura,e gets(come tutto il resto del programma) la scrivo in un foglio di carta quindi anche se è "unsafe" non me ne puo fregare de meno ne a me ne ai prof...adesso rimetto il codice commentato in dettaglio

ZioLuffio
13-12-2012, 13:55
Originariamente inviato da cianeddu
allora..lo faccio attraverso il programma per essere sicuro di non lasciare spazi strani che mi "incasinerebbero" la grandezza della stringa..
per quanto riguarda la gets() me la ricordo meglio..devi contare che questo è un compito d'esame della mia università,quindi in teoria il file esiste già,io dovrei fare solo la seconda parte quella di lettura,e gets(come tutto il resto del programma) la scrivo in un foglio di carta quindi anche se è "unsafe" non me ne puo fregare de meno ne a me ne ai prof...adesso rimetto il codice commentato in dettaglio
ma non frega manco a me che sia "unsafe", è solo che ti incasini la vita per niente, visto che devi solo leggere degli interi! CAVOLO è il caso più semplice, questo! E poi printf() e scanf() son quasi le prime cose che insegnano, e si applicano pari pari a file e stringhe, quindi non vedo come tu possa "ricordarti meglio" la gets(), bah... Devi solo ripassarle bene, che sono delle cavolate pazzesche

L'ho capito subito che è un testo d'esame, sai, sto facendo ingegneria informatica... E appunto perché sono del mestiere mi chiedo perché tu ti debba complicare la vita, anche creando un file che ci metti due secondi a modificare a mano.-.

cianeddu
13-12-2012, 13:57
questo è il codice commentato spero si capisca tutto..ho rimesso solo il codice..la prima e l'ultima parte sono uguali alla domanda originale
#include <stdio.h>
#include <stdlib.h>
#define N 100
int main(int argc,char *argv[])
{
int i,j,r,l,x1,y1,x2,y2,flag,s;
char str[12],matrice[N][N];
FILE*fp;
fp=fopen("rett.txt","w");

//inizio a scrivere il file
if(fp==NULL){

printf ("\nerrore apertura file in write\n");

return -1;



}
//scrivo 5 stringhe..composte da 4 numeri di massimo 2 cifre..spazio tra i numeri e \n alla fine


for(i=0;i<5;i++){

printf("\nscrivi quattro numeri intervallati da spazio di massimo 2 cifre ciascuno \n");

gets(str);
fprintf(fp,"%s\n",str);


}

// chiudo il file

r=fclose(fp);
if(r==EOF){

printf("\nerrore chiusura file in write\n");
return -2;


}
//faccio il controllo sul numero di parametri passati da linea di comando
if(argc!=2){

printf("\nerrore numero di parametri passati da linea di comando\n");

return -3;


//apro il file in lettura e il nome lo passo da linea di comando
}
fp=fopen(argv[1],"r");
if(fp==NULL){

printf("\nerrore apertura file in read\n");

return-4;

//inizializzo la matrice col carattere underscore '_'
}
for(i=0;i<N;i++){

for(j=0;j<N;j++){
matrice[i][j]='_';



}

}






flag=0;//metto un flag a 0..che mi aiuterà a stabilire se i rettangoli si sovrappongono nella matrice o no
s=1;//questo è il contatore per vedere l'eventuale posizione di errore numero di parametri nella conversione da stringa ad interi
while(fgets(str,12,fp)!=NULL){//inizio la lettura del file

l=sscanf(str,"%d %d %d %d",&x1,&y1,&x2,&y2);//converto la stringa in interi(che mi rappresentano le coordinate del primo punto del rettangolo in alto a sinistra (x1,y1)e le coordinate del punto in basso a destra(x2,y2))



printf(" num par=%d in pos %d\n",l,s);//qua verifico il numero di parametri 'l' per ogni posizione 's'

if(l!=4){ //qua verifico che il numero di parametri siano 4

printf("\nerrore nella formattazione dei parametri da stringa ad interi:num par= %d in pos %d\n",l,s);
return -5;



}
s++;//superato il controllo incremento la variabile posizione

if(x1>=x2||y1>=y2||x1<0||x1>=N||y1<0||y1>=N||x2<0||x2>=N||y2<0||y2>=N){//qua mi chiedo se il file rispetta il formato richiesto,cioè x1 e y1 devono essere minori di x2 e y2..e tutti e 4 devono essere compresi tra 0 ed N con N escluso

printf("\nerrore nel formato del file\n");
return -6;


}

for(i=x1;i<=x2;i++){ //qua inizio il ciclo che dovrà all'interno della matrice tra le coordinate che mi interessano cioè x1,x2 per le righe

for(j=y1;j<=y2;j++){y1,y2 per le colonne



if(matrice[i][j]=='_')//qui mi chiedo se la matrice ha il valore con cui l'ho inizializzata..se si ci metto un '1'
matrice[i][j]='1';
else{
matrice[i][j]='2'; //se no ci metto un '2' e in questa seconda ipotesi cambio del flag a 1
flag=1;


}





}



}

}
r=fclose(fp);//chiudo il file
if(r==EOF){
printf("\nerrore chiusura file in read\n");
return -7;





}
if(flag==0)
printf("\nnon ci sono sovrapposizioni\n"); //a questo punto mi chiedo se il flag è 0 o no..se è 0 vuo dire che non ho scritto la matrice in zone già occupate…cioè non ho scritto '2' ma sempre '1' avendo sempre trovato posto libero
else
printf("\nc'e' almeno una sovrapposizione\n");//in caso il flag non fosse 0(sarebbe 1) vuol dire che c'é almeno un '2' nella matrice cioè era già occupata la posizione



for(i=0;i<N;i++){//qua visualizzo a schermo i valori della matrice;solo nel caso in cui non sia uguale a underscore '_ 'cioè il valore con cui l'ho inizializzata

for(j=0;j<N;j++){
if(matrice[i][j]!='_')
printf("\nmatrice[%d][%d]=%c\n",i,j,matrice[i][j]);
}



for(i=0;i<N;i++){//e qui la vedo graficamente

printf("\n");


for(j=0;j<N;j++)

printf("%c",matrice[i][j]);

}
}
return 0;

}

cianeddu
13-12-2012, 14:00
anche le altre le ricordo bene solo che la scanf con le stringhe intervallate da spazio e con l'invio si incasina perchè il carattere non va perso..dovrei mettere quel carattere speciale %*c..non te lo sto spiegando..ti sto chiarendo il motivo della gets..

ZioLuffio
13-12-2012, 14:08
Originariamente inviato da cianeddu
solo che la scanf con le stringhe intervallate da spazio e con l'invio si incasina perchè il carattere non va persoperché il carattere non va perso? questa non l'ho capita... se mettessi 5 numeri su una riga e 3 sull'altra la scanf() su interi te ne leggerebbe cmq 4 e 4 perché gli spazi e gli a capi neanche li considera

Poi un'altra cosa: non capisco perché usi 3 valori nella matrice: basterebbe una matrice di interi (e non di caratteri come la tua) con valore 0 = vuoto, 1 = già pieno, per capire se stai sovrapponendo, perché leggendo il testo non mi pare di vedere che ti serva sapere DOVE si sovrappongono, ma solo SE.

Poi credo (non mi ricordo) che tu possa inizializzare una matrice con
matrice[N][N] = {'_'};
provalo un po' perché forse funziona, anziché iterare con for su righe e colonne :)


PS: Ricorda che ad un esame devi prestare molta attenzione alle SPECIFICHE del problema, e non implementare cose che non ti richiedono, perché perdi solo tempo a fare che non ti aumentano il voto, trascurendo invece l'essenziale per avere almeno un 18 :old:

Loading