leotech Inviato 3 Febbraio 2016 Segnala Condividi Inviato 3 Febbraio 2016 Ciao a tutti! Ho un problema con il ritorno di una stringa da una funzione, anziché salvarmi tutta la stringa all'interno di un altro array di caratteri nel main mi riporta solo l'ultima lettera della stringa. Eccovi il codice, spero che possiate darmi una mano //main int main() { char frase[20]; *frase = *nuovo_gioco(frase); printf("%s\n", frase); //funzione nuovo_gioco //prende le parole da un file txt esterno al programma char *nuovo_gioco(char *frase) { struct parola { char parole[20]; }; typedef struct parola Parola; Parola array[5]; FILE *fp; int j; int i; srand(time(NULL)); j = rand() % 4; if((fp = fopen("parole.txt", "r")) == NULL) { printf("errore\n"); } else { while(!feof(fp)) { fscanf(fp, "%s", array.parole); i++; } fclose(fp); } vita = MAX_VITA; printf("DEBUG: la parola da indovinare e' %s\n", frase); frase = malloc(40*sizeof(char)); frase = array[j].parole; return frase; Link al commento Condividi su altri siti Altre opzioni di condivisione...
Lief Inviato 8 Febbraio 2016 Segnala Condividi Inviato 8 Febbraio 2016 il tuo codice è un po' confusionario (copiando e incollando non funziona, ma forse non lo hai copiato tutto)... ma sicuramente c'è una cosa che non quadra: richiami una funzione nuovo_gioco che ritorna un char... in c se non erro (è qualche mese che programmo solo in Java) le stringhe si possono ritornare da una funzione con char**. Link al commento Condividi su altri siti Altre opzioni di condivisione...
leotech Inviato 12 Febbraio 2016 Autore Segnala Condividi Inviato 12 Febbraio 2016 il tuo codice è un po' confusionario (copiando e incollando non funziona, ma forse non lo hai copiato tutto)... ma sicuramente c'è una cosa che non quadra: richiami una funzione nuovo_gioco che ritorna un char... in c se non erro (è qualche mese che programmo solo in Java) le stringhe si possono ritornare da una funzione con char**. Nono la funzione ritorna una stringa, il problema era nel main dove non usavo la funzione strcpy per copiare la stringa dalla funzione alla string nel main. Si è presentato un altro problema però (mai una gioia): la funzione funziona perfettamente la prima volta, la seconda volta va in segmentation code su "return frase"... Non so più che fare, le ho provate tutte... Link al commento Condividi su altri siti Altre opzioni di condivisione...
Lief Inviato 13 Febbraio 2016 Segnala Condividi Inviato 13 Febbraio 2016 Nono la funzione ritorna una stringa, il problema era nel main dove non usavo la funzione strcpy per copiare la stringa dalla funzione alla string nel main. Si è presentato un altro problema però (mai una gioia): la funzione funziona perfettamente la prima volta, la seconda volta va in segmentation code su "return frase"... Non so più che fare, le ho provate tutte... #include <stdio.h> #include <stdlib.h> #include <string.h> //dichiarazione funzione obbligatoria char* nuovo_gioco(char *frase); //main int main() { char frase[20] = ""; //strcpy aggiunta strcpy(frase, nuovo_gioco(frase)); printf("%s\n", frase); } char* nuovo_gioco(char *frase) { struct parola { char parole[20]; }; typedef struct parola Parola; Parola array[5]; FILE *fp; int j = 0; int i = 0; srand(time(NULL)); j = rand() % 4; if((fp = fopen("parole.txt", "r")) == NULL) { printf("errore\n"); }else{ while(!feof(fp)) { fscanf(fp, "%s", array[i].parole); i++; } fclose(fp); } // variabile non dichiarata // vita = MAX_VITA; // cast a char* frase = (char *)malloc(40*sizeof(char)); //strcpy aggiunta seconda volta strcpy(frase, array[j].parole); printf("DEBUG: la parola da indovinare e' %s\n", frase); return frase; } ok, ho trovato qualche minuto in più per guardare il codice che hai scritto e provare a compilarlo (l'altro giorno ero ancora sotto esami quindi ci avevo dato solo un'occhiata... e C è un po' che non lo prendevo in mano quindi avevo un po' di difficoltà a ricordare... figurati che avevo letto char *funzione come se restituissi char e la funzione fosse un puntatore... una roba senza senso... chiaramente il tutto perchè io di solito scrivo char* funzione con lo spazio dopo il *). i problemi che ho riscontrato sono comunque tanti, oltre agli include e alla dichiarazione della funzione (obbligatoria in c) ma che immagino tu non abbia semplicemente copiato... mancava una graffa alla fine del main e una graffa alla fine della funzione nuovo_gioco... ho poi aggiunto la strcpy (nel main E nella funzione, mancava anche lì), commentato la variabile vita (che non ho proprio idea di cosa sia e a cosa serva), e ho aggiunto il cast nel malloc (buona pratica che ti consiglio di adottare in futuro, ti permette di scovare facilmente errori), ho anche spostato debug sotto frase (lì dov'era non aveva molto senso). Probabilmente usi un compilatore diverso da gcc, perchè gcc mi ha segnalato questi problemi già in partenza. Fatto questo spero di aver più o meno capito cosa fa questo programmino (in pratica legge un file, mette tutte le parole contenute in parole.txt in un array di stringhe, ne sceglie una a caso e la mette dentro la stringa da restituire e la stampa). Il segmentation fault non ho idea a cosa fosse dovuto (in questo momento a me funziona sempre, anche più volte di seguito, ma non ho idea di come sia strutturato il tuo programma)... Spero che il codice che ho postato riesca a chiarirti qualsiasi problema tu abbia e che ti sia d'aiuto. PS. se usi l'icona che si chiama Code il codice viene visualizzato molto più chiaramente (qui sul forum). PS2. ho anche inizializzato le variabili... non è obbligatorio ma in C può fare la differenza visto che una variabile non inizializzata può contenere di tutto. Link al commento Condividi su altri siti Altre opzioni di condivisione...
leotech Inviato 14 Febbraio 2016 Autore Segnala Condividi Inviato 14 Febbraio 2016 #include <stdio.h> #include <stdlib.h> #include <string.h> //dichiarazione funzione obbligatoria char* nuovo_gioco(char *frase); //main int main() { char frase[20] = ""; //strcpy aggiunta strcpy(frase, nuovo_gioco(frase)); printf("%s\n", frase); } char* nuovo_gioco(char *frase) { struct parola { char parole[20]; }; typedef struct parola Parola; Parola array[5]; FILE *fp; int j = 0; int i = 0; srand(time(NULL)); j = rand() % 4; if((fp = fopen("parole.txt", "r")) == NULL) { printf("errore\n"); }else{ while(!feof(fp)) { fscanf(fp, "%s", array[i].parole); i++; } fclose(fp); } // variabile non dichiarata // vita = MAX_VITA; // cast a char* frase = (char *)malloc(40*sizeof(char)); //strcpy aggiunta seconda volta strcpy(frase, array[j].parole); printf("DEBUG: la parola da indovinare e' %s\n", frase); return frase; } ok, ho trovato qualche minuto in più per guardare il codice che hai scritto e provare a compilarlo (l'altro giorno ero ancora sotto esami quindi ci avevo dato solo un'occhiata... e C è un po' che non lo prendevo in mano quindi avevo un po' di difficoltà a ricordare... figurati che avevo letto char *funzione come se restituissi char e la funzione fosse un puntatore... una roba senza senso... chiaramente il tutto perchè io di solito scrivo char* funzione con lo spazio dopo il *). i problemi che ho riscontrato sono comunque tanti, oltre agli include e alla dichiarazione della funzione (obbligatoria in c) ma che immagino tu non abbia semplicemente copiato... mancava una graffa alla fine del main e una graffa alla fine della funzione nuovo_gioco... ho poi aggiunto la strcpy (nel main E nella funzione, mancava anche lì), commentato la variabile vita (che non ho proprio idea di cosa sia e a cosa serva), e ho aggiunto il cast nel malloc (buona pratica che ti consiglio di adottare in futuro, ti permette di scovare facilmente errori), ho anche spostato debug sotto frase (lì dov'era non aveva molto senso). Probabilmente usi un compilatore diverso da gcc, perchè gcc mi ha segnalato questi problemi già in partenza. Fatto questo spero di aver più o meno capito cosa fa questo programmino (in pratica legge un file, mette tutte le parole contenute in parole.txt in un array di stringhe, ne sceglie una a caso e la mette dentro la stringa da restituire e la stampa). Il segmentation fault non ho idea a cosa fosse dovuto (in questo momento a me funziona sempre, anche più volte di seguito, ma non ho idea di come sia strutturato il tuo programma)... Spero che il codice che ho postato riesca a chiarirti qualsiasi problema tu abbia e che ti sia d'aiuto. PS. se usi l'icona che si chiama Code il codice viene visualizzato molto più chiaramente (qui sul forum). PS2. ho anche inizializzato le variabili... non è obbligatorio ma in C può fare la differenza visto che una variabile non inizializzata può contenere di tutto. Gli include, la dichiarazione non li ho copiati, le due parentesi probabilmente mi sono sfuggite mentre copiavo il codice, uso gcc e me li avrebbe segnati come errori. La variabile vita è una variabile globale (il programma esegue il gioco dell'impiccato, questa è la funzione che sceglie una tra 5 parole prese da un file esterno e inizializza le vite con un define impostato da me nel file .h. Potresti spiegarmi come mai hai aggiunto un cast nella malloc? il prof a lezione non ce ne ha mai parlato... Riguardando il codice mie ro accorto anc?io della mancanza del secondo strcpy. Un'ultima cosa, l'inizializzazione della stringa frase sarebbe come inizializzarla a NULL? Grazie mille per la pazienza e l'aiuto!!! Link al commento Condividi su altri siti Altre opzioni di condivisione...
leotech Inviato 14 Febbraio 2016 Autore Segnala Condividi Inviato 14 Febbraio 2016 Ho appena apportato le correzioni e il programma non va più in segmentation code, grazie mille!!! Può essere che il programma andava in segmentation code a causa della malloc non castata? Grazie infinite per l'aiuto :) Link al commento Condividi su altri siti Altre opzioni di condivisione...
Lief Inviato 15 Febbraio 2016 Segnala Condividi Inviato 15 Febbraio 2016 Ho appena apportato le correzioni e il programma non va più in segmentation code, grazie mille!!! Può essere che il programma andava in segmentation code a causa della malloc non castata? Grazie infinite per l'aiuto :) la malloc ritorna sempre un void* (puntatore a void), di conseguenza potresti metterlo in qualunque variabile... però è sempre buona norma fare un cast, infatti aiuta sia te (che sai cosa metti dentro alla tua variabile anche dopo un mese che hai scritto il programma e non ricordi più niente XD... per me è così mi scordo subito tutto), sia il compilatore (che se fai un cast errato te lo dice). gcc mi dava un warning che diceva: "cast implicito", compilava comunque ma quel warning mi ha ricordato che in C è meglio metterlo. Se usi gcc controlla tra i warning, spesso sono consigli ai quali non si da peso ma che alla fin fine consentono di creare un codice più pulito e a volte correggono anche comportamenti strani (tra l'altro in molti consigliano di mettere anche il parametro -Wall quando si compila, in modo da avere dei warning aggiuntivi... sembra masochismo ma quando si fanno programmi più grossi più warning si correggono meno problemi si hanno in futuro... qualche warning alla fine rimane sempre per programmi grossi, ma per i piccoli meglio averne il meno possibile). Detto questo non credo che fosse quello il problema... penso piuttosto che fosse l'inizializzazione delle variabili il problema. In C quando una variabile non è inizializzata può contenere caratteri spazzatura fino alla sua inizializzazione... tiro a indovinare ma credo che il problema fosse la i oppure frase (visto che non erano inizializzate), tiro a indovinare perchè non ricordo se in C gli interi abbiano come valore di default 0... per quanto riguarda le stringhe inizializzarle a NULL significa far puntare il puntatore ad un'area di memoria non valida, inizializzarle a "" significa mettere dentro la nostra stringa una stringa vuota ad un indirizzo di memoria valido. Se inizializzi a NULL un puntatore è perchè anche i puntatori non sai quale valore abbiano prima di averli inizializzati... ad esempio se tu inizializzassi una stringa in questo modo: char *str = NULL; successivamente potresti utilizzare un codice di questo genere if(str != NULL) faiQualcosa(); al contrario quando vuoi copiare un valore dentro la tua stringa devi chiaramente avere un'area di memoria già valida, quindi "" ha più senso. pensa all'inizializzazione a NULL come ad una malloc a 0, ti serve per liberare lo spazio di memoria utilizzato e per un check sicuro... l'inizializzazione è meglio farla ad una stringa vuota. Link al commento Condividi su altri siti Altre opzioni di condivisione...
leotech Inviato 17 Febbraio 2016 Autore Segnala Condividi Inviato 17 Febbraio 2016 Infatti il problema era sul return di frase, grazie infinite Lief!!! Link al commento Condividi su altri siti Altre opzioni di condivisione...
Messaggi raccomandati
Archiviato
Questa discussione è archiviata e chiusa a future risposte.