[C] Restituzione di una stringa da una procedura

Linguaggi di programmazione: php, perl, python, C, bash e tutti gli altri.
Coogle
Prode Principiante
Messaggi: 24
Iscrizione: giovedì 16 giugno 2011, 16:25

[C] Restituzione di una stringa da una procedura

Messaggio da Coogle »

Codice: Seleziona tutto

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void parolamax(char *testo,char output,int *numeromassimo){
    char *copia=strdup(testo);
    char *word,*ret = NULL;
    int lunghezza;
    int max=0;
    while((word=strtok(copia, " "))){
        copia=NULL;
        lunghezza=strlen(word);
        
        if(lunghezza>max){
            max=lunghezza;
            ret=word;
            
        }
        
    }
    output=ret;
    *numeromassimo=max;
}
int main(){
    char *stringa = "Asd lollo silvestro serena";
    char *parolamass;
    int max=0;
    parolamax(stringa,parolamass, &max);
    printf("La parola più lunga è : %s e misura %d \n",parolamass,max);
    return 0;
}
Voglio ottenere la parola di lunghezza massima di una stringa e restituire sia la parola in questione sia la sua dimensione.
Per la dimensione non c'è problema restituisce,per la parola stampa a video (null).

Grazie a tutti quelli che risponderanno
Avatar utente
M_A_W_ 1968
Scoppiettante Seguace
Scoppiettante Seguace
Messaggi: 856
Iscrizione: venerdì 15 febbraio 2013, 3:57
Desktop: KDE
Distribuzione: SuSE
Sesso: Maschile
Località: Un luogo geometrico
Contatti:

Re: [C] Restituzione di una stringa da una procedura

Messaggio da M_A_W_ 1968 »

Inizia col leggere questo thread per chiarirti un po' le idee.

Hai sbagliato il tipo di parametri passati alla procedura (void function). Se devi restituire un puntatore a char, il cui contenuto viene modificato dalla procedura stessa, dovresti passare un puntatore a puntatore a char. Ma questo è comunque erroneo, dato il comportamento della strtok() illustrato appunto nel link sopra presentato. In realtà, a te serve una copia dell'intera sottostringa in un buffer, che sarà poi restituito al chiamante (e qui nasce anche il problema di deallocare la relativa memoria, o piuttosto di passare ad una variabile con diverso scope)

In realtà dovrai correggere i tuoi errori di impostazione seguendo una di queste asseverate strategie di design. Tipicamente, potrai passare un puntatore ad una struct che contiene un unsigned int (equivalentemente, size_t) per la lunghezza massima, e un buffer (array di char) di dimensione prudenziale, che conterrà copia della "parola" più lunga estratta dalla stringa di testo.

In sostanza, qualcosa del seguente tenore:

Codice: Seleziona tutto

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

#define BUF_SIZE 64

typedef struct {
    char buff[BUF_SIZE];
    size_t len;
} parola_t;
    
void parolamax(char *testo, parola_t *output)
{
        size_t max = 0;
        char *p;

        p = strtok(testo, " ");
        while(NULL != p)
        {
            size_t len = strlen(p);
          
            if(len > max)
            {
                max = len;
                output->len = len;
                strcpy(output->buff, p);
            }
            p = strtok(NULL, " ");
        }
}

int main(void)
{
        char *stringa = "Asd lollo silvestro serena";
        parola_t parola_max;
        
        parolamax(stringa, &parola_max);
        
        printf("La parola piu' lunga e' [%s] di dimensione %d\n",
               parola_max.buff, parola_max.len);
               
        return 0;
}
L'esempio, strettamente basato sul codice presentato, ha poi ampissimi margini di miglioramento. Ma per il momento possiamo fermarci qui.
Sì, un blog ce l'ho perfino io: gli è che mi manca il tempo...

"...in una società che sembra sempre più spaventata dai problemi troppo articolati e che rigetta come un corpo estraneo ogni elemento di complessità, sapremo ancora come utilizzare il parere degli esperti?"
Coogle
Prode Principiante
Messaggi: 24
Iscrizione: giovedì 16 giugno 2011, 16:25

Re: [C] Restituzione di una stringa da una procedura

Messaggio da Coogle »

Grazie per la risposta e lo snippet,ho solo un problema quando vado ad eseguirlo crasha secondo il debugger all'incirca qui:

p = strtok(testo, " ");

Come mai accade questo?

EDIT:

Ho risolto adattando il mio codice a ciò che mi ha detto mav

Codice: Seleziona tutto

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define BUFFSIZE 40
typedef struct{
    size_t len;
    char buff[BUFFSIZE];
}parola_t;

void parolamax(char *testo,parola_t *output){
    char *copia=strdup(testo);
    char *word;
size_t lunghezza;
    size_t max=0;
    while((word=strtok(copia," "))){
        copia=NULL;
        lunghezza=strlen(word);
        if(lunghezza>max){
            max=lunghezza;
            strcpy(output->buff, word);
            output->len=lunghezza;
        }
    }
}
int main(){
    char *stringa = "Asd lollo silvestro serena";
    parola_t parolamas;
    parolamax(stringa,&parolamas);
    printf("La parola più lunga è : %s e misura %zu \n",parolamas.buff,parolamas.len);
    return 0;
}
Se qualcuno però mi spiega il perchè di quell'errore gliene sarei grato :)
gila75
Imperturbabile Insigne
Imperturbabile Insigne
Messaggi: 2739
Iscrizione: mercoledì 16 gennaio 2013, 17:28
Desktop: ubuntu-2d
Distribuzione: Ubuntu 12.04.2 LTS i686
Località: Airuno(Lecco)

Re: [C] Restituzione di una stringa da una procedura

Messaggio da gila75 »

@M_A_W:


il tuo esempio compila perfettamente ma....

Codice: Seleziona tutto

Errore di segmentazione (core dump creato)
Avatar utente
vbextreme
Entusiasta Emergente
Entusiasta Emergente
Messaggi: 1214
Iscrizione: domenica 12 gennaio 2014, 14:06
Desktop: lxde
Distribuzione: xubuntu 14.10

Re: [C] Restituzione di una stringa da una procedura

Messaggio da vbextreme »

Codice: Seleziona tutto

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

#define BUF_SIZE 64

typedef struct {
    char buff[BUF_SIZE];
    size_t len;
} parola_t;
    
void parolamax(char *testo, parola_t *output)
{
    size_t max = 0;
    char *p;

    p = strtok(testo, " ");
    while(NULL != p)
    {
		size_t len = strlen(p);
        if(len > max)
        {
            max = len;
            output->len = len;
            strcpy(output->buff, p);
        }
        p = strtok(NULL, " ");
     }
}

int main(void)
{
	char stringa[] = "Asd lollo silvestro serena";
    parola_t parola_max;
        
    parolamax(stringa, &parola_max);
    printf("La parola piu' lunga e' [%s] di dimensione %d\n",parola_max.buff, parola_max.len);
              
    return 0;
}
si è dimenticato di copiare la stringa in un'area della memoria "editabile".
Easy framework per il linguaggio C.
vbextreme hack your life
gila75
Imperturbabile Insigne
Imperturbabile Insigne
Messaggi: 2739
Iscrizione: mercoledì 16 gennaio 2013, 17:28
Desktop: ubuntu-2d
Distribuzione: Ubuntu 12.04.2 LTS i686
Località: Airuno(Lecco)

Re: [C] Restituzione di una stringa da una procedura

Messaggio da gila75 »

si è dimenticato di copiare la stringa in un'area della memoria "editabile".
Si,si, ho solo segnalato :)
Avatar utente
M_A_W_ 1968
Scoppiettante Seguace
Scoppiettante Seguace
Messaggi: 856
Iscrizione: venerdì 15 febbraio 2013, 3:57
Desktop: KDE
Distribuzione: SuSE
Sesso: Maschile
Località: Un luogo geometrico
Contatti:

Re: [C] Restituzione di una stringa da una procedura

Messaggio da M_A_W_ 1968 »

...la cui collocazione finale dipende strettamente dal compilatore, come già rimarcato più volte: con le opzioni di default di OpenWatcom la stringa così inizializzata finisce comunque nello heap, e non ci sono problemi a runtime.

Ma in questo caso non ho volutamente modificato il resto del codice dell'OP, ponendo l'accento unicamente su come impostare il passaggio dei parametri. :)
Sì, un blog ce l'ho perfino io: gli è che mi manca il tempo...

"...in una società che sembra sempre più spaventata dai problemi troppo articolati e che rigetta come un corpo estraneo ogni elemento di complessità, sapremo ancora come utilizzare il parere degli esperti?"
Avatar utente
vbextreme
Entusiasta Emergente
Entusiasta Emergente
Messaggi: 1214
Iscrizione: domenica 12 gennaio 2014, 14:06
Desktop: lxde
Distribuzione: xubuntu 14.10

Re: [C] Restituzione di una stringa da una procedura

Messaggio da vbextreme »

@Maw pensavo usassi ancora il turbo c++, mi stupisce questo tuo "upgrade" tecnologico.No dai scherzo, comunque non mi garba più di tanto quella tecnica, un pò troppo obfuscated, poco elegante e molto furviante.
Easy framework per il linguaggio C.
vbextreme hack your life
Avatar utente
M_A_W_ 1968
Scoppiettante Seguace
Scoppiettante Seguace
Messaggi: 856
Iscrizione: venerdì 15 febbraio 2013, 3:57
Desktop: KDE
Distribuzione: SuSE
Sesso: Maschile
Località: Un luogo geometrico
Contatti:

Re: [C] Restituzione di una stringa da una procedura

Messaggio da M_A_W_ 1968 »

vbextreme [url=http://forum.ubuntu-it.org/viewtopic.php?p=4727696#p4727696][img]http://forum.ubuntu-it.org/images/icons/icona-cita.gif[/img][/url] ha scritto:@Maw pensavo usassi ancora il turbo c++, mi stupisce questo tuo "upgrade" tecnologico.No dai scherzo, comunque non mi garba più di tanto quella tecnica, un pò troppo obfuscated, poco elegante e molto furviante.
Non ho il mio fido BCC 5.5.1 perché sono molto lontano da casa e mi devo accontentare di quel che passa il convento, cioé un vecchio laptop di chissà chi. :lol:

Comunque il passaggio di puntatori a strutture, volenti o nolenti, è un'istituzione: ci sono fior di librerie commerciali impostate totalmente in quel modo, e perfino API di RTOS, come già spiegavo a suo tempo (proprio a te) nel thread su IoProgrammo referenziato qualche post fa: ci sono anche coding standand aziendali di tutto rispetto che ne caldeggiano l'uso sistematico. :sisi:

Per giunta, nello specifico si tratta del modo più "objective" disponibile per implementare coerentemente le "stringhe" in C.

Quanto al modo barbaro di inizializzare la stringa, che rischia di diventare implicitamente costante, ne abbiamo già discusso in lungo e in largo centinaia di volte. La più recente credo sia questa. Quando parlavo di "ampi margini di miglioramento" ovviamente mi riferivo anche a questo.
Sì, un blog ce l'ho perfino io: gli è che mi manca il tempo...

"...in una società che sembra sempre più spaventata dai problemi troppo articolati e che rigetta come un corpo estraneo ogni elemento di complessità, sapremo ancora come utilizzare il parere degli esperti?"
Scrivi risposta

Ritorna a “Programmazione”

Chi c’è in linea

Visualizzano questa sezione: 0 utenti iscritti e 14 ospiti