Visualizzazione dei risultati da 1 a 6 su 6
  1. #1

    [C] Problema con array di caratteri

    Ciao a tutti,
    ho appena iniziato a programmare con c, e sto facendo un programma che deve gestire le stringhe usando solo i char....però sono arrivato a un punto che mi da un warning e non capisco il perchè, vi allego i due pezzi di codice:

    codice:
    typedef char *string;
    
    string alloca(int dimensione){
    return malloc(dimensione * sizeof(char));
    }
    
    
    char rmv(int n, char s[]) {
    	int i;
    	char arr[ln(s)-1];
    	for(i=0;i<n-1;i++)
    		arr[i] = s[i];
    	for(i=n;i<ln(s);i++)
    		arr[i] = s[i];
    
    	return *arr;
    }
    metodo che elimina il char all n-1 posizione

    codice:
    main() {
    ...
    const int dimensione=10;
    string stringa = alloca(dimensione);
    stringa="ciao";
    ...
    ...
    char stringaProva = rmv(2,stringa);
    printf("%s\n",stringaProva);
    
    }
    e sulla riga del printf mi da questo warning: warning: format ‘%s’ expects type ‘char *’, but argument 2 has type ‘int

    qualcuno mi sa spiegare il perché e come risolverlo???

    Grazie, ciao ciao

  2. #2
    Utente di HTML.it L'avatar di r1cky`
    Registrato dal
    Feb 2007
    Messaggi
    432
    Beh scusa, tu hai una stringa, la passi alla funzione, quest'ultima ti toglie un carattere quindi perchè il valore di ritorno è un char e non un char* o un char[]?
    Tra l'altro è normale che ti dia l'errore sulla printf, perchè se la stringa di formato è %s lui considera la variabile come puntatore, se %c prendere direttametne il valore della variabile!

  3. #3
    ho fatto così perché non mi dava nessun errore...cmq se faccio così:

    codice:
    char* rmv(int n, char s[]) {
    	int i;
    	char arr[ln(s)-1];
    	for(i=0;i<n-1;i++)
    		arr[i] = s[i];
    	for(i=n;i<ln(s);i++)
    		arr[i] = s[i];
    
    	return *arr;
    }
    mi da questo warning:
    return makes pointer from integer without a cast

    e poi se nel printf faccio così:

    codice:
    printf("%c\n",stringaProva);
    fa questo warning:
    format ‘%c’ expects type ‘int’, but argument 2 has type ‘char *’


    aiutami un'attimo,arrivando da java qeuste cose non le so......

  4. #4
    Originariamente inviato da Oiziorbaf
    ho fatto così perché non mi dava nessun errore...cmq se faccio così:

    codice:
    char* rmv(int n, char s[]) {
    	int i;
    	char arr[ln(s)-1];
    	for(i=0;i<n-1;i++)
    		arr[i] = s[i];
    	for(i=n;i<ln(s);i++)
    		arr[i] = s[i];
    
    	return *arr;
    }
    mi da questo warning:
    return makes pointer from integer without a cast
    Certo, perché così restituisci un singolo carattere (ossia il primo carattere di arr), che viene automaticamente convertito in puntatore (restituendo così un puntatore non valido). Se arr non fosse una variabile locale non statica potresti fare
    codice:
    return arr;
    , ma visto che lo è restituiresti un puntatore non valido, visto che arr viene distrutto automaticamente all'uscita dalla funzione. Devi quindi allocare dinamicamente la memoria per la stringa restituita, e il chiamante dovrà poi occuparsi di deallocarla.
    codice:
    char* rmv(int n, char s[]) {
    	int i;
    	char * arr=malloc(strlen(s));
            if(arr==NULL)
                return NULL;
    	for(i=0;i<n-1;i++)
    		arr[i] = s[i];
    	for(i=n;i<strlen(s);i++)
    		arr[i-1] = s[i];
    	return arr;
    }
    In generale comunque vedo che stai facendo una gran confusione tra caratteri, array di char allocati sullo stack, array di char allocati nell'heap, puntatori a stringhe nella tabella delle stringhe dell'eseguibile. Ad esempio, se fai:
    codice:
    const char * stringa="Prova";
    non c'è bisogno di allocare niente prima, visto che stai assegnando ad una variabile puntatore l'indirizzo di una stringa già pronta nella tabella dell'eseguibile che non deve essere modificata, pena potenziali casini.
    Se invece fai
    codice:
    char * stringa;
    stringa = malloc(10);
    if(stringa!=NULL)
    {
        strcpy(stringa,"Prova");
    }
    else
    {
        /* gestisci sempre gli errori di memoria insufficiente */
    }
    ottieni una stringa modificabile allocata dinamicamente nell'heap, che ti dovrai ricordare di deallocare.
    codice:
    if(stringa!=NULL)
        free(stringa);
    Se invece fai
    codice:
    char stringa[10];
    strcpy(stringa, "Prova");
    ottieni una stringa modificabile che non ti devi ricordare di deallocare perché è allocata sullo stack e viene eliminata automaticamente all'uscita dalla procedura.
    In generale, comunque, evita assolutamente cose come
    codice:
    typedef char *string;
    visto che potrebbero farti pensare cose sbagliate sulle variabili che stai utilizzando: un char * non è minimamente comparabile con una string Java o C++, n char * è un puntatore a char (non necessariamente ad un array di char, e su come è allocato ciò a cui punta non sai nulla), con tutto quello che ciò comporta. Inoltre ti sconsiglio anche di scrivere routine personalizzate che incapsulano funzioni di libreria, come la alloca o la ln, esistono già le funzioni standard malloc/calloc e strlen, che risultano più immediatamente riconoscibili da chi conosce il C ma non il tuo codice particolare.

    Le stringhe C sono delle bestiacce, e non le puoi affrontare a cuor leggero. Assicurati di aver studiato a fondo e ben compreso il capitolo a proposito di esse (e quello su array e puntatori) del tuo manuale di C prima di scrivere pasticci come quello che hai qui riportato.
    Amaro C++, il gusto pieno dell'undefined behavior.

  5. #5
    OK,
    Grazie mille per l'aiuto!!
    Ora ho le idee un pochino più chiare....ora mi ci metto dietro.

    Grazie ancora.
    Ciao ciao

  6. #6
    Amaro C++, il gusto pieno dell'undefined behavior.

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.