View Full Version : [c]strano problema con una funzione che richiede un char *
dyablo96
24-11-2013, 14:18
buon giorno a tutti, come da titolo ho uno strano problema con una funzione che richiede in ingresso un char *.
io ho un vettore di struct, ogni elemento ha una variabile char *.
all'interno del ciclo utilizzo la suddetta funzione per togliere le parentesi ad una stringa che gli viene passata.
per esempio al primo ciclo la stringa da analizzare è la seguente : ((3+2+1))
mi restituisce : (3+2+1).
e lo salva nell'elemento successivo nel vettore di struct.
aumento il contatore.
al ciclo successivo gli passo (3+2+1).
pero' facendo un printf all'interno della funzione:
printf("\nStringa : %s",stringa);
a monitor non mi mostra niente.
quindi l'errore sta nel passaggio del char *stringa alla funzione.
qualcuno può aiutarmi ? :(
bancodeipugni
24-11-2013, 14:23
se posti il codice forse si puo' guardare :fagiano:
dyablo96
24-11-2013, 14:31
eh è un po lunghetto ma cercherò di mettere solo le parti essenziali.
dyablo96
24-11-2013, 14:36
questo è il main :
typedef struct
{
int pid;
char *stringa;
}Associazione;
int main()
{
//vettore di struct per mettere in relazione i pid con le stringhe da eseguire
Associazione vet[20];
//Variabili
int ProcessoPadre;
int i=0;
char espressione[20];
ProcessoPadre = getpid();
//Acquisisco il numero dei processi
printf("Inserire l'espressione : ");
scanf("%s",espressione);
vet[0].pid=ProcessoPadre;
vet[0].stringa=espressione;
int parentesi = 0;
while(parentesi==0)
{
printf("i=%d\n",i);
printf("parentesi=%d\n",parentesi);
printf("sottotringa di partenza : %s\n",vet[i].stringa);
parentesi=controllo_parentesi(vet[i].stringa);
printf("parentesi dopo controllo=%d\n",parentesi);
if(parentesi==0)
{
printf("i=%d\n",i);
printf("sottotringa di partenza : %s\n",vet[i].stringa);
i=i+1;
int a=i;
printf("a=%d\n",i);
i--;
char *str=vet[i].stringa;
printf("str = %s\n",str);
int ctrl = sotto_operazione(str,vet,a);
printf("i=%d\n",i);
printf("sottotringa ricavata : %s\n",vet[a].stringa);
if(ctrl!=0)
printf("ERRORE, parentesi non corrette");
else
i++;
}
}
//trovo il risultato di una stringa, gli mando anche il pid del processo così poi mi crea automaticamente il file
esegui_operazioni(7,vet[i].stringa);
return 0;
}
queste sono le funzioni che eliminano le parentesi:
void *taglia(char *stringa,int inizio, int fine, Associazione *vet, int posizione)
{
printf("taglia");
char risultato[fine-inizio];
int i=0,k=0;
while(stringa[i]!=0)
{
if(i>inizio && i<fine)
{
risultato[k]=stringa[i];
k++;
}
i++;
}
printf("\n\n\n\n stringa : %s\nposizione : %d\nrisultato : %s\n",stringa,posizione,risultato);
vet[posizione].stringa = risultato;
printf("\nvet[%d].stringa = %s\n",posizione,vet[posizione].stringa);
return 0;
}
int sotto_operazione(char *stringa, Associazione *vet, int posizione)
{
printf("sotto operazione");
printf("\n\n\n\n stringa : %s\nposizione : %d\n",stringa,posizione);
int a=0;
int i=0;
int k=0;
while(stringa[i]!=0)
{
if(stringa[i]=='(')
{
a++;
}
if(stringa[i]==')')
{
a--;
if(a==0)
break;
}
i++;
}
if(a!=0)
return (a);
taglia(stringa,k,i,vet,posizione);
return 0;
}
ho messo in grassetto dove c'è il malfunzionamento.
so che ci sono molti printf, li utilizzavo per vedere cosa non va.
spero riusciate a capirci qualcosa.
bancodeipugni
24-11-2013, 15:08
vet[0].stringa=espressione;
con
espressione[20]
non mi piace
puo' dare problemi
fai lo strcpy e dichiari il record:
typedef struct
{
int pid;
char stringa[20];
}Associazione;
...
strcpy(vet[0].stringa, espressione);
oltre al fatto che manca un controllo sulla lunghezza di espressione inserita dallo scanf
poi vado avanti a leggere
dyablo96
24-11-2013, 15:29
Nn credo di poter usare l'strcpy perché prima di copiarlo devo togliergli le parentesi, ma se non riesco a passarlo alla funzione non posso togliere le parentesi e quindi neanche copiarlo sulla posizione del vettore
bancodeipugni
24-11-2013, 15:56
sto parlando dell'inizio del codice, nella main prima di fare tutto
dyablo96
24-11-2013, 16:15
Ok, ho capito xo li nn cis sono mai problemi, il problema é semprenel second ciclo al passaggio della stringa.
lorenzo001
24-11-2013, 16:58
Come ti è stato detto, questa
vet[0].stringa=espressione;
e anche questa
vet[posizione].stringa = risultato;
non fanno quello che pensi scritte in quel modo.
Devi assolutamente allocare lo spazio per la stringa e copiare con la strcpy
vet[0].stringa = (char *)malloc(strlen(espressione)+1);
strcpy(vet[0].stringa, espressione);
vet[posizione].stringa = (char *)malloc(strlen(risultato)+1);
strcpy(vet[posizione].stringa, risultato);
dyablo96
24-11-2013, 17:46
ok, appena posso provo e vi faccio sapere, comunque mi sembra strano che al primo ciclo funzioni mentre al secondo no :confused:
lorenzo001
24-11-2013, 17:55
A te pare strano, a me no.
bancodeipugni
24-11-2013, 17:57
a me pare strano che funzioni anche il primo
forse perché avevi provato con una stringa molto semplice
dyablo96
24-11-2013, 18:22
bho, io ho messo (3+2+1), facendo un solo giro funziona.
mettendo ((3+2+1)) il primo giro lo fa e infatti grazie ai printf vedo che mi stampa (3+2+1) poi però appena viene passato alla funzione chiedendogli di stampare no stampa niente.
lorenzo001
24-11-2013, 18:39
Apporta le modifiche, fai le prove e se ci sono altri problemi, mostra nuovamente il codice modificato e spiega ...
dyablo96
24-11-2013, 19:58
non posso postarvi il codice perchè sono via e scrivo col cellulare ma per maggior chiarezza posso postarvi la consegna che ci ha dato il nostro professore :
Strutturare un parser per delle espressioni solo numeriche.
Data a padre una espressione del tipo (((7+3)/6)+(4+(5*3)))
vengono gestite le precedenze tra operatori solo con il raggruppamento a parentesi.
opzione: il primo passo quindi sara' del padre che nel rispetto delle regole matematiche aggiunge eventuali parentesi per dipanare questi dubbi di precedenza.
Ogni "sottooperazione" delimitata da parentesi verrà trattata in fork da un figlio in modo da avere il calcolo concorrente della stessa.
Per restituire il risultato del figlio si usino i file i questo modo:
- il processo si annota la porzione di espressione abbinandola al pid del figlio che la tratta.
- il processo aspetta il risultato con un waitpid specifico
- il processo legge il risultato scritto da filgio nel file <nomeprogramma>-<pid>.txt
il padre a richiesta cancella anche i file .txt intermedi.
opzione2: scrivere un file di log che tracci la generazione dei figli con le rispettive porzioni di espressione
spero possiate capire meglio.
lorenzo001
24-11-2013, 20:55
A me la consegna non interessa perché non ti voglio fare l'esercizio.
Ti posso dare una mano a correggere gli errori e ancora dovresti dire se hai rimediato come ti ho suggerito ...
bancodeipugni
24-11-2013, 21:29
fai una prova cosi':
1/(1+(3-(8*(3+1)-4)+5)-6)
e vedi qual è l'ultimo output se solo il secondo o l'ultimo
dyablo96
24-11-2013, 21:36
So che mi puoi fare l'esercizio, e nn ti chiedo di farlo. Domani provo l'espressione e vi faccio sapere.
Doman
dyablo96
25-11-2013, 15:15
ho provato con quello che mi avete detto, malloc e strcpy ma con entrambi mi vengono stampati caratteri asci a caso.
ho provato come mi hai detto te bancodeipugni ma si ferma comunque al secondo giro.
ho provato a mettere una variabile globale da modificare prima del passaggio alla funzione ma anche quella al primo giro funziona mentre il secondo risulta vuota.
dyablo96
25-11-2013, 15:57
credo ci sia stato un miglioramento, vi posto il risultato:
Inserire l'espressione : ((3+2))
i=0
parentesi=0
parentesi dopo controllo=0
sottotringa di partenza : ((3+2))
sotto operazione
stringa : ((3+2))
posizione : 1
taglia
stringa : ((3+2))
posizione : 1
risultato : (3+2)�r��8Y�
vet[1].stringa = (3+2)�r��8Y�
sottotringa ricavata : (3+2)�r��8Y�
i=1
parentesi=0
parentesi dopo controllo=0
sottotringa di partenza : (3+2)�r��8Y�
sotto operazione
stringa : (3+2)�r��8Y�
posizione : 2
taglia
stringa : (3+2)�r��8Y�
posizione : 2
risultato : 3+)�r��8Y�
vet[2].stringa = 3+)�r��8Y�
sottotringa ricavata : 3+)�r��8Y�
i=2
parentesi=0
parentesi dopo controllo=-1
Segmentation fault (core dumped)
almeno adesso la stringa viene passata anche nel secondo ciclo, però viene lavorata in modo sbagliata dal primo ciclo che gli aggiunge quei caratteri asci e quindi poi si sporca tutta la prosecuzione.
al codice ho sostituito le parti che mi dicevate con i malloc e gli strcpy.
credo che perchè funzioni bisogna togliergli quello che si forma dietro, sapete come fare?
bancodeipugni
25-11-2013, 22:48
si sporca la stringa
calloc
malloc restituisce un blocco di memoria allocato dal programmatore per essere utilizzato, ma non è inizializzato. Questa operazione è spesso effettuata a mano, se necessario, tramite la funzione memset, o da una o più assegnazioni con dereferenziazione del puntatore. Un'alternativa è di usare la funzione calloc, che alloca la memoria e la inizializza. Il prototipo è
void *calloc(size_t nelements, size_t elementSize);
che alloca un'area di memoria, la inizializza a 0, di dimensioni nelements × elementSize.
dyablo96
26-11-2013, 12:40
quindi io al posto di usare malloc utilizzo calloc?
dyablo96
26-11-2013, 15:42
risolto grazie bancodeipugni, anch'io adoro quel programma ;)
bancodeipugni
26-11-2013, 21:53
ma quale programma ? :fagiano:
dyablo96
28-11-2013, 19:01
mah, forse quello che hai messo nel tuo nome?? ;) ;)
e immagine del profilo ?? ;) ;)
e città ?? ;) ;)
bancodeipugni
28-11-2013, 20:16
ah io avevo capito programma = codice :rolleyes: :mbe: :stordita: :fagiano: :sofico: :ciapet:
:doh:
dyablo96
29-11-2013, 13:20
hahahaha :D :D :D :D :D
mi sono spiegato male :D
vBulletin® v3.6.4, Copyright ©2000-2025, Jelsoft Enterprises Ltd.