PDA

Visualizza la versione completa : [C] Inserire da input una stringa arbitrariamente lunga


gaten
14-04-2012, 02:47
Salve ragazzi, stò cercando di creare una funzione per inserire una stringa da input arbitrariamente lunga. Io per adesso ho la seguente function:



char *StringaArbitraria()
{
int i=0;
char *c,ci;
c=(char*)malloc(sizeof(char));

while(ci!=10) // mi fermo quando trovo un newline \n
{
ci=getchar(); // inserisco un singolo carattere
c[i]=ci; // lo associo puntatore
i++;
c=(char*)realloc(c,sizeof(char)*(i+1));
}
c[i]='\0'; //inserisco terminatore '\0'

return c;
}


Però, il prof. ci ha detto che usare tante volte la realloc, è dispendioso e và modificata, come posso modificare questa function?

lolide
14-04-2012, 03:49
Di solito per ottimizzare i realloc si usano dei metodi per riallocarla il minor numero di volte possibile.
Tipo allocare sempre il doppio della memoria gia' allocata e magari partire con un array gia' allocato. Hai un piccolo spreco di memoria che però ottimizza la riallocazione.

es. parti con un array di 20 char. se volessi inserire il 20°, allochi altri 20 caratteri, poi al 40° allochi altri 40 caratteri ecc...

così facendo ti risparmi molti realloc pagando un piccolo spreco di memoria.

Who am I
14-04-2012, 03:49
Fai che metti una stringa lunga (ad esempio) 100 caratteri, la prendi in input con fgets, la copi su un' area di memoria allocata dinamicamente e la ritorni.
Per esempio puoi fare così:



char* get_string(void)
{
char buffer[100], *result;
fgets(buffer,100,stdin);
result=(char*)malloc( (strlen(buffer)+1)* sizeof(char));
return result;
}


Una variante consiste nel prende in input direttamente la stringa allocata dinamicamente, ma allocando tot caratteri alla volta (ad esempio 10) e riallocandola solo quando supera le dimensioni dell' input, ma di tot caratteri alla volta pe limitare le chiamate alla realloc:



char* get_string(void)
{
char* result=(char*)malloc(10*sizeof(char)),temp,length= 0,dim=10;
while( (temp=getchar())!=10)
{
length++;
if(dim<length)
{
dim+=10;
result=(char*)realloc(dim*sizeof(char));
}
result[length-1]=temp;
}
return result;
}


Poi ci sono mille varianti, e dipende sostanzialmente da:
-Quanta memoria vuoi occupare al massimo;
-Quanto vuoi che la routine sia veloce.

Scegli te l' importanza di questi fattori.

PS: Ci potrebbe essere qualche errore perché le ho scritte senza provare a compilarle.

gaten
14-04-2012, 15:52
#include<string.h>
#include<stdio.h>

char *get_string(void);

int main()
{
char *c;
c=get_string();

printf("La stringa inserita e': %s", c);

system("\nPAUSE");
}

char *get_string(void)
{
char* result=(char*)malloc(10*sizeof(char)),temp,length= 0,dim=10;
while( (temp=getchar())!=10)
{
length++;
if(dim<length)
{
dim+=10;
result=(char*)realloc(dim*sizeof(char));
}
result[length-1]=temp;
}

return result;
}


Nella compilazione non dà alcun errore, ma prova ad inserire una stringa con più di 10 caratteri e fai la stessa cosa con una stringa con meno di 10 caratteri e guarda cosa esce fuori.

gaten
14-04-2012, 15:57
Ma poi non riesco a capire:



char lenght=0;


scusa nn è meglio fare:


char temp;
int length=0;
int dim=10;

torn24
14-04-2012, 16:59
Forse c'è un problema nella realloc ,manca un parametro puntatore
result=(char*)realloc(dim*sizeof(char));

per quanto riguarda usare i char , con un char puoi rappresentare numeri fino a 255

un char occupa un byte , è usato molto in questo modo , nella programmazione
microcontrollori ,dove la memoria ram è di pochi byte e quindi bene risparmiarla il piu
possibile , se si può :)

su un pc da 4 GB di ram , lo trovo inutile !

gaten
14-04-2012, 17:03
torn24, sono d'accordo con te, ma quando parliamo di complessità computazionale di un algoritmo, queste cose è meglio tenerle presenti:D

gaten
14-04-2012, 17:05
Ho modificato giustamente il realloc in questo modo:



result=(char*)realloc(result, dim*sizeof(char));


Però quando inserisco le stringhe, mi concatena alla fine sempre alcuni caratteri esempio ù, à e altri ancora... ma non riesco a capire il perchè!

torn24
14-04-2012, 17:35
non viene inserito il terminatore stringa nella funzione , quindi ha un comportamento
indefinito





char *get_string(void)
{
char* result=(char*)malloc(10*sizeof(char)),temp,length= 0,dim=10;
while( (temp=getchar())!=10)
{
length++;
if(dim<length)
{
dim+=10;
result=(char*)realloc(result,dim*sizeof(char));
}
result[length-1]=temp;
}
result[length]='\0';//aggiunge il terminatore stringa
return result;
}

gaten
15-04-2012, 19:39
torn, un'unica domanda, io con getchar(); posso inserire un unico carattere.
Ma se inserisco in input:

Ciao sono gaten!

va ugualmente bene, come mai?

P.S
Ovviamente questa funzione andrebbe bene per qualsiasi input (intero, stringa, float , double etc), basta effettuare il cast del valore di ritorno es:




float x;

x=(float)get_string();

Loading