Pagina 1 di 2 1 2 ultimoultimo
Visualizzazione dei risultati da 1 a 10 su 12
  1. #1
    Utente di HTML.it
    Registrato dal
    Dec 2004
    Messaggi
    286

    [c99/c++] puntatore a stringa come argomento

    Carissimi ho un problemino che non riesco a superare. Ho una funzione che mi converte
    un valore intero nella sua rappresentazione ASCII. La funzione è questa:

    codice:
    char * UInt32ToStr(int i)
    {
    	static char buf[10];
    	char *p = buf + 10; // Posiziono in fondo alla stringa sul terminatore null.
    
    	do	{
    			*--p = '0' + (i % 10);
    			i /= 10;
    		} 
    		while (i != 0);
    		
    	return p;
    }
    Questa funzione lavora bene; i è il valore da rappresentare e una volta uscita la
    funzione p contiene l'indirizzo della stringa che ha ricevuto i caratteri corrispondenti.
    Tuttavia com'è scritta sopra lo spazio per la stringa è allocato staticamente all'interno della funzione. Ora io vorrei fare in modo di poter allocare questo spazio esternamente, prima di invocare la funzione, dunque ho scritto così:

    codice:
    int UInt32ToStr(int i, char *p)
    {
    	int n = 0; // Contatore di caratteri in scrittura. 	
    	while(*p++); // Posiziono in fondo alla stringa sul terminatore null.
    	
    	do	{
    			*--p = '0' + (i % 10); n++;
    			i /= 10;
    		} 
    		while (i != 0);
    		// Qui all'uscita del ciclo p mi fornisce la stringa corretta.  
    		
    	return n;
    }
    Di seguito ecco come uso la chiamata alla funzione:

    codice:
    	int nChars = 0;
    	int iVal = 18954;
    	char pStr[21];
    
    	nChars = IntToStr(iVal, pStr);
    A questo punto però il puntatore pStr non ha copiato lo stesso indirizzo del corrispettivo puntatore all'interno del corpo della funzione, dunque l'esito è un fallimento. Qualcosa mi sfugge, come potrei fare?

    Ringrazio per l'attenzione

  2. #2
    Utente di HTML.it L'avatar di ShaleN
    Registrato dal
    Aug 2010
    Messaggi
    517
    Se non erro, devi fare:

    codice:
    	int nChars = 0;
    	int iVal = 18954;
    	char pStr[21];
    
    	nChars = IntToStr(iVal,  &pStr);
    Le vie del Signore sono infinite. È la segnaletica che lascia a desiderare.
    La luce viaggia più veloce del suono. Per questo alcune persone sembrano brillanti finchè non parlano.
    Occhio per occhio uguale... occhio al quadrato

  3. #3
    Utente di HTML.it
    Registrato dal
    Dec 2004
    Messaggi
    286
    Originariamente inviato da ShaleN
    Se non erro, devi fare:

    codice:
    	int nChars = 0;
    	int iVal = 18954;
    	char pStr[21];
    
    	nChars = IntToStr(iVal,  &pStr);
    Ciao ShaleN e grazie per la risposta. Per evitare l'errore del compilatore per compatibilità tra i tipi ho scritto (char*)&pStr, ma purtroppo il risultato non cambia e la funzione continua a fallire. Poiché pStr è un nome di array esso è anche un puntatore costante al primo elemento dell'array, in questo modo &pStr diventerebbe l'indirizzo di memoria in cui è contenuto l'indirizzo dell'array. Si potrebbe scrivere &(pStr[0]) ma anche così il problema non è risolto.


    codice:
    	int nChars = 0;
    	int iVal = 18954;
    	char pStr[21];
    	char *p = pStr; // come scrivere: char *p = &pStr[0]
    	// p = 0012FDD6
    
    	nChars = IntToStr(iVal,  pStr);
    	// Ancora p = 0012FDD6
    Noto invece che all'interno del corpo della funzione p riceve il valore 0012FDC6 e quel puntatore mi fornisce il riferimento alla stringa correttamente formattata. Il problema è che non riesco a tirar fuori quel puntatore dalla funzione, se non come valore di ritorno.

  4. #4

  5. #5
    Utente di HTML.it L'avatar di oregon
    Registrato dal
    Jul 2005
    residenza
    Roma
    Messaggi
    36,480
    Attenzione ... quando scrivi

    while(*p++); // Posiziono in fondo alla stringa sul terminatore null.

    non puoi pensare di trovare il terminatore dato che la stringa non è inizializzata.

    Se devi usare lo stesso algoritmo, ti devi posizionare alla fine della stringa in un altro modo, magari indicando nei parametri la lunghezza oppure inizializzando correttamente la stringa in ingresso.

    P.S. Ho dato per scontato che la funzione si chiama UInt32ToStr e non IntToStr come fai nel main ...
    No MP tecnici (non rispondo nemmeno!), usa il forum.

  6. #6
    Utente di HTML.it
    Registrato dal
    Dec 2004
    Messaggi
    286
    Originariamente inviato da oregon
    non puoi pensare di trovare il terminatore dato che la stringa non è inizializzata.
    Ovviamente!
    Ho inizializzato la stringa in ingresso e il puntatore dato come argomento alla funzione mi rende la stringa cercata, a parte una piccola anomalia che fisserò sta sera, poi vi metto al corrente del buon esito.


    Originariamente inviato da oregon
    P.S. Ho dato per scontato che la funzione si chiama UInt32ToStr e non IntToStr come fai nel main ...
    Si, infatti mi sono sbagliato a scrivere, è sempre la UInt32ToStr.

  7. #7
    Utente di HTML.it
    Registrato dal
    Dec 2004
    Messaggi
    286
    Originariamente inviato da ESSE-EFFE
    Ma per ottenere quello che ti serve, non ti basta la sprintf?
    Si, quando sono disposto ad accettare che il puntatore del processore compia il giro del globo prima di rendere un risultato. Ma se devo processare qualche milione di istruzioni cerco di scrivermi un algoritmo fatto apposta solo per quel compito, in modo da evitare un labirinto di tanti passi inutili.

  8. #8
    Originariamente inviato da Paulin
    Si, quando sono disposto ad accettare che il puntatore del processore compia il giro del globo prima di rendere un risultato. Ma se devo processare qualche milione di istruzioni cerco di scrivermi un algoritmo fatto apposta solo per quel compito, in modo da evitare un labirinto di tanti passi inutili.
    Beh sì, la sprintf essendo così generica non può essere ottimizzata come un algoritmo ad hoc. La mia domanda era più che altro per capire se lo scopo della funzione era solo quello.

  9. #9
    Utente di HTML.it
    Registrato dal
    Dec 2004
    Messaggi
    286
    Ok, la mia conclusione è che non riesco a fare esattamente quel che volevo. La stringa inizializzata sarà composta in questo modo:

    |a|a|a|a|a|a|a|a|a|a|NULL|


    L'algoritmo di conversione da valore intero a stringa ASCII che ho usato sopra funziona riempiendo la stringa dal fondo in sù, pertanto se il valore da rappresentare fosse 15378 otterrò:

    |a|a|a|a|a|1|5|3|7|8|NULL|

    Le operazioni di incremento o decremento dell'indirizzo del puntatore all'interno del corpo della funzione non hanno effetto sul puntatore usato nella chiamata di funzione inquanto quello interno alla funzione costituisce solo una copia di quello passato come argomento.
    Il mio puntatore punterà sempre all'inizio della stringa, pertanto avrò sempre:

    |a|a|a|a|a|1|5|3|7|8|NULL|

    Se decido di fare in questo modo debbo verificare se non mi da problema inizializzare la stringa con il carattere spazio vuoto.

    | | | | | |1|5|3|7|8|NULL|

    Se invece ritornassi il puntatore all'ultimo elemento scritto come valore di ritorno allora otterrò solo quel che mi serve:

    |1|5|3|7|8|NULL|

    In altrentativa potrei riempire la stringa a partire dal primo elemento e aggiungere il temianatore NULL appena teminata la scrittura, ma in questo modo dovrei impiegare qualche istruzione in più nell'agoritmo di conversione.

  10. #10
    Originariamente inviato da Paulin
    Se invece ritornassi il puntatore all'ultimo elemento scritto come valore di ritorno allora otterrò solo quel che mi serve
    Come dici tu, ritornare il puntatore effettivo è semplice e risolve il problema. Un'altra possibilità (da testare bene) potrebbe essere la seguente:

    codice:
    #define L_MAX 21
    
    int UInt32ToStr(int i, char **p, int lmax)
    {
        int n = 0; // Contatore di caratteri in scrittura.
    
        *p += (lmax - 1);
        **p = '\0';
    
        do
        {
                (*p)--;
                **p = '0' + (i % 10);
                n++;
                i /= 10;
         }
         while (i != 0);
         // Qui all'uscita del ciclo p mi fornisce la stringa corretta.
    
        return n;
    }
    
    int main(int argc, char* argv[])
    {
        int nChars = 0;
        int iVal = 18954;
    
        char str[L_MAX];
        char *pstr = str;
    
        nChars = UInt32ToStr(iVal, &pstr, L_MAX);
    
        printf("%s\n\n", pstr);
    
        return 0;
    }
    HTH,

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2025 vBulletin Solutions, Inc. All rights reserved.