Vai al contenuto

Ritornare Una Stringa Da Una Funzione Linguaggio C


Messaggi raccomandati

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

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

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

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

#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

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

Archiviato

Questa discussione è archiviata e chiusa a future risposte.

×
×
  • Crea Nuovo...