Pagina 1 di 2 1 2 ultimoultimo
Visualizzazione dei risultati da 1 a 10 su 13
  1. #1

    [C] Problema con puntatore a puntatore

    Ho un main con
    codice:
    char **t;
    int n
    printf("Quante stringhe vuoi inserire?");
    scanf("%d",&n);
    t=leggi(n);
    e il seguente metodo che, da 0 a n-1, fa inserire all'utente le stringhe, poi le duplica con strdup() e le assegna ad un puntatore di puntatore. Infine, restituisce il punt. di punt.
    (Devo farlo per scuola, quindi devo per forza usare questa sequenza di passi!)

    codice:
    char **leggi(int n){
         int i;
         char **p=malloc(n*sizeof(char));
         char *s;
         
         for(i=0;i<n;i++){
            printf("Stringa n. %d: ",i+1);
            scanf("%s",&s);     
            p[i]=strdup(s);
         }
    
         for(i=0;i<n;i++)
         printf("%c",p[i]);
           
              return p;
         }
    ho aggiunto alla fine la stampa di p[] per vedere se la duplicazione funziona...ma niente da fare Cosa avrò sbagliato? Mi viene da pensare che sia sbagliato il malloc...ma non capisco!!
    Grazie

  2. #2

    Re: [C] Problema con puntatore a puntatore

    Originariamente inviato da Lasentinella
    Ho un main con
    codice:
    char **t;
    int n
    printf("Quante stringhe vuoi inserire?");
    scanf("%d",&n);
    t=leggi(n);
    e il seguente metodo che, da 0 a n-1, fa inserire all'utente le stringhe, poi le duplica con strdup() e le assegna ad un puntatore di puntatore. Infine, restituisce il punt. di punt.
    (Devo farlo per scuola, quindi devo per forza usare questa sequenza di passi!)

    codice:
    char **leggi(int n){
         int i;
         char **p=malloc(n*sizeof(char));
         char *s;
         
         for(i=0;i<n;i++){
            printf("Stringa n. %d: ",i+1);
            scanf("%s",&s);     
            p[i]=strdup(s);
         }
    
         for(i=0;i<n;i++)
         printf("%c",p[i]);
           
              return p;
         }
    ho aggiunto alla fine la stampa di p[] per vedere se la duplicazione funziona...ma niente da fare Cosa avrò sbagliato? Mi viene da pensare che sia sbagliato il malloc...ma non capisco!!
    Grazie
    Ciao Sentinella,
    questo codice dovrebbe funzionare

    Codice PHP:
    #include <stdio.h>
    #include <stdlib.h>

    char **leggi(int n){
         
    int i;
         
    char **p=(char **)malloc(n*sizeof(char *));   
         
    char *s=(char *)malloc(sizeof(char)*80);
         
         
         for(
    i=0;i<n;i++){
            
    printf("Stringa n. %d: ",i+1);
            
    scanf("%s",s);     
            
    p[i]=(char *)malloc(sizeof(char)*strlen(s));
            
    strcpy(p[i],s);
         }

         for(
    i=0;i<n;i++)
         
    printf("%s",p[i]);
           
              
    free(s);
              return 
    p;
         
         }

    int main()
    {

    char **t;
    int n;
    printf("Quante stringhe vuoi inserire?");
    scanf("%d",&n);
    t=leggi(n);

    system("pause");


    In particolare hai fatto questi errori:
    char **p=malloc(n*sizeof(char)); // non hai detto a malloc che tipo di puntatore restituire e hai specificato il sizeof in maniera errata. In questo caso malloc deve restituire un puntatore a puntatore e deve allocare memoria per ospitare puntatori a carattere non a caratteri.

    char **p=(char **)malloc(n*sizeof(char *));

    char *s; // non hai allocato la memoria per questo puntatore
    scanf("%s",&s); // quando passi una stringa o un vettore alla scanf non devi usare & perchè è sufficiente passare s che contiene l indirizzo della prima cella del vettore/stringa
    printf("%c",p[i]); // per stampare la stringa devi usare %s

    Spero di esserti stato di aiuto, buon fine settimana!

  3. #3
    Grazie infinite, ora funziona
    Ti chiedo un altro piccolo aiuto..
    Dopo la lettura delle stringhe si passa al nuovo metodo la prima posizione e l'ultima come parametri:

    codice:
    selsort(v,v+n-1);
    La funzione sel sort è questa:
    codice:
    void selsort(char **begin, char **end){ 
    
         for(;begin<end;begin++){
            swap(begin, begin[pos_min(begin,end)]);
             }
    Per ogni elemento dell'array, scambia l'elemento stesso col minore degli elementi successivi (non so spiegarlo bene...QUI trovi la descrizione del "Selection Sort"..ma magari lo conosci già )


    Il primo problema è che compilando ottengo l'errore "conflicting types for pos_min"...ti scrivo anche lo swap, perché anche con questo metodo ottengo lo stesso errore.

    codice:
    void swap(char **a, char **b){
          char **papp;
         **papp=**a;
         **a=**b;
         **b=**papp;
         }
    Risolto questo problema dovrei aver finito, penso
    Grazie ancora!

    p.s.
    Ma se te sei UltraBeginner io cosa sono?

  4. #4
    Risolto da solo il problema precedente, ora il problema finale ( ):
    codice:
    void swap(char **a, char **b){
        
         char **papp;
         papp=a;
         a=b;
         b=papp;
         printf("SCAMBIO : %s - %s\n",*a,*b);
    
         }
    Questo codice, richiamato da selsort, scambia **a e **b. Se inserisco 's' e 'a', leggo infatti:
    SCAMBIO: a - s.
    Quando, però, torno a selsort, è come se non li avessi scambiati. Riottengo s e a!!!!!!!
    Il selsort è questo:
    codice:
    void selsort(char **begin, char **end){ 
    
         for(;begin<end;begin++){
            swap(begin, pos_min(begin,end));
    
             }
        
    }
    Com'è possibile che non memorizzi lo scambio??

  5. #5
    Originariamente inviato da Lasentinella
    Grazie infinite, ora funziona
    Ti chiedo un altro piccolo aiuto..
    Dopo la lettura delle stringhe si passa al nuovo metodo la prima posizione e l'ultima come parametri:

    codice:
    selsort(v,v+n-1);
    La funzione sel sort è questa:
    codice:
    void selsort(char **begin, char **end){ 
    
         for(;begin<end;begin++){
            swap(begin, begin[pos_min(begin,end)]);
             }
    Per ogni elemento dell'array, scambia l'elemento stesso col minore degli elementi successivi (non so spiegarlo bene...QUI trovi la descrizione del "Selection Sort"..ma magari lo conosci già )


    Il primo problema è che compilando ottengo l'errore "conflicting types for pos_min"...ti scrivo anche lo swap, perché anche con questo metodo ottengo lo stesso errore.

    codice:
    void swap(char **a, char **b){
          char **papp;
         **papp=**a;
         **a=**b;
         **b=**papp;
         }
    Risolto questo problema dovrei aver finito, penso
    Grazie ancora!

    p.s.
    Ma se te sei UltraBeginner io cosa sono?
    Reciao lasentinella,

    ecco il codice corretto

    Codice PHP:
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>

    void selection(char ** aunsigned long N); 

    char **leggi(int n){
         
    int i;
         
    char **p=(char **)malloc(n*sizeof(char *));   
         
    char *s=(char *)malloc(sizeof(char)*80);
         
         
         for(
    i=0;i<n;i++){
            
    printf("Stringa n. %d: ",i+1);
            
    scanf("%s",s);     
            
    p[i]=(char *)malloc(sizeof(char)*strlen(s));
            
    strcpy(p[i],s);
         }

         
    printf("\n\nStampo la matrice allocata dinamicamente non ordinata\n");
         for(
    i=0;i<n;i++)
         
    printf("%s\n",p[i]);
           
              
    free(s);
              return 
    p;
         
         }

    int main()
    {

    char **t;
    int n,i;
    printf("Quante stringhe vuoi inserire?");
    scanf("%d",&n);
    t=leggi(n);
    selection(t,n);

    printf("\n\nStampo la matrice allocata dinamicamente ordinata con il selection sort\n");
    for(
    i=0;i<n;i++)
    printf("%s\n",t[i]);

    system("pause");

    }

    void selection(char ** aunsigned long N) {
      
    int ijmin
    char temp[80];

      for (
    i=0N-1i++) 
       {
        
    min i;
          for (
    j1Nj++) 
            if (
    strcmp(a[j],a[min])<0
              
    min j;
        
        
    strcpy(temp,a[min]);
        
    strcpy(a[min],a[i]);
        
    strcpy(a[i],temp);
      }

    [QUOTE]Il primo problema è che compilando ottengo l'errore "conflicting types for pos_min"...ti scrivo anche lo swap, perché anche con questo metodo ottengo lo stesso errore.[\QUOTE]

    Bhe, perchè come secondo elemento devi passare la dimensione (ovvero il numero di righe) della tua matrice allocata dinamicamente, valore che richiedi all utente e che poi vai a mettere nella variabile n. Puoi vedere infatti che io ho passato come parametri l inizio della nostra matrice (e cioe il puntatore a puntatore t nella funziona main) e il numero di righe n.

    Dopo di che per implementare il selection sort è bastato seguire la guida di wikipedia e fare in modo che la funzione li riportata funzionasse con le stringhe.

    Buona domenica!



    p.s.
    Io sono sempre UltraBeginner (scrivo codice solo da 1 anno e mezzo!). Però un consiglio te lo posso dare: leggi tutti i post di questo forum, imparerai un sacco di cose anche perchè qui ci sono persone serie e disponibili, oserei dire dei veri e propri maestri tra cui ti posso citare Oregon, MItaly, fastcode, Andbin,Xaratroom,King64 e tanti altri di cui non ricordo il nick. Detto questo in gamba e buona programmazione!!!

  6. #6
    Acc, siamo riusciti a scrivere il post nello stesso momento...i tuoi suggerimenti sono stati utilissimi, ho un solo problema: Le funzioni richieste sono tutte puntatori a puntatori...ti scrivo il codice :
    codice:
    char **leggi_stringhe(int n){
         int i;
         char **p=(char **)malloc(n*sizeof(char*));
         char *s=(char *)malloc(sizeof(char)*80);
         
         for(i=0;i<n;i++){
            printf("Stringa n. %d: ",i+1);
            scanf("%s",s);    
            p[i]=(char *)malloc(sizeof(char)*strlen(s));
            p[i]=strdup(s);
         }
    
         free(s);
    
              return p;
         }
    
    void selsort(char **begin, char **end){ 
    
         for(;begin<end;begin++){
            swap(begin, pos_min(begin,end));
      
    }
    
    char **pos_min(char **begin, char **end){
    
           
         char **res;
         char **w;
         char **app;
         res = begin+1;
    
         for (w=begin; w<end; w++){
             if (strcmp(*w, *res)< 0)
                 res=w;
             
        }
              
         return res;
         
    }
    
    void swap(char **a, char **b){
        
         char **papp;
         papp=a;
         a=b;
         b=papp;
         printf("SCAMBIO : %s - %s\n",*a,*b);
    
         }
         
    void stampa_stringhe(char **t, int n){
         int i;
         for(i=0;i<n;i++)
            printf("%s",t[i]);
            
    }
    
    void elimina(char **p, int n){
         int i;
         for(i=0;i<n;i++)
         free(p[i]);
         free(p);
    }
    
    int main(void)
    {
    char **v;
    int n;
    printf("Numero di stringhe da ordinare: ");
    scanf("%d", &n);
    v=leggi_stringhe(n);
    if( v!=NULL ) {
    selsort(v,v+n-1); // Ordina
    printf( "\nVettore ordinato:\n" );
    stampa_stringhe(v,n); // Stampa
    elimina(v,n); // Libera la memoria
    }
    else printf( "Input fallito." );
    system("PAUSE");
    }
    L'unico problema che ho è che la funzione SWAP scambia correttamente le due stringhe ma, tornando alla funzione chiamante (selsort), le due stringhe tornano ad essere nelle posizioni iniziali. La cosa non è strana?
    Cioé, se io inserisco 's' e poi 'a', swap le scambia (e infatti la printf lo dimostra), ma tornati al selsort, 's' torna ad essere in prima posizione e 'a' in seconda.


    Grazie ancora, sei gentilissimo! Buona domenica anche a te

  7. #7
    Utente di HTML.it L'avatar di oregon
    Registrato dal
    Jul 2005
    residenza
    Roma
    Messaggi
    36,462
    La swap deve essere

    codice:
    void swap(char **a, char **b)
    {
         char *papp;
    
         papp=*a;
         *a=*b;
         *b=papp;
    }
    Controlla tu il perche' ...

  8. #8
    Originariamente inviato da oregon
    La swap deve essere

    codice:
    void swap(char **a, char **b)
    {
         char *papp;
    
         papp=*a;
         *a=*b;
         *b=papp;
    }
    Controlla tu il perche' ...
    *a dovrebbe indicare il contenuto del puntatore (il valore a cui punta), ma
    papp=*a; non dovrebbe voler dire fai puntare papp al contenuto di a? Non si dovrebbe fare o papp=a; oppure *papp=*a ?

  9. #9
    Utente di HTML.it L'avatar di oregon
    Registrato dal
    Jul 2005
    residenza
    Roma
    Messaggi
    36,462
    Originariamente inviato da Lasentinella
    *a dovrebbe indicare il contenuto del puntatore (il valore a cui punta)
    In questo caso, il valore a cui punta a e' a sua volta un puntatore ... (ricorda che a e' un doppio puntatore)

    papp=*a; non dovrebbe voler dire fai puntare papp al contenuto di a? Non si dovrebbe fare o papp=a; oppure *papp=*a ?
    Questa non l'ho capita ...

  10. #10
    Originariamente inviato da Lasentinella
    *a dovrebbe indicare il contenuto del puntatore (il valore a cui punta), ma
    papp=*a; non dovrebbe voler dire fai puntare papp al contenuto di a? Non si dovrebbe fare o papp=a; oppure *papp=*a ?
    Forse un disegnino puo spiegare la situazione

    dop.punt punt. a char stringa di char
    (a)1 --> 3 --> ziao

    (b)2 --> 4 --> ciao

    come vedi facendo

    papp=*a;
    *a=*b; // scambio
    *b=papp;

    metti nel puntatore di appoggia papp quello a cui punta a (il valore 3). Poi scambi i valori a cui puntano a e b. Alla fine riponi nella casella a cui punta b il valore di a.

    Dopo queste operazioni avrai la seguente situazione

    dop.punt punt. a char stringa di char
    (a)1 --> 4 --> ciao

    (b)2 --> 3 --> ziao

    ovvero ora facendo *a punterai alla casella di memoria 4 che puntava a ciao.

    Spero sia chiaro, non sono proprio Giotto io!



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 © 2024 vBulletin Solutions, Inc. All rights reserved.