PDA

Visualizza la versione completa : C allocazione dinamica stringa


Fearuin
21-08-2010, 16:44
Salve a tutti, mi sto cimentando in un programma in C di gestione di un azienda. Il mio dubbio sorge nel momento in cui devo far inserire i dati all'utente, come nome e cognome. Non voglio dare un limite definito, poiché se per assurdo l'utente voglia inserire un nome o un cognome di 1000 caratteri vorrei che lo possa fare senza però sprecare memoria inutile definendola a priori. In poche parole nel momento in cui l'utente inserirà il nome vorrei che si definisse in quel momento la lunghezza della stringa. Non sò se sono stato chiaro XD
Grazie in anticipo ^___^

XBarboX
21-08-2010, 19:50
Immagino che questi dati li salverai su un database o un file testo, quindi ti bastano due variabili:
nome, cognome;
Di tipo string, Ops volevo dire vettore di caratteri in C :D
che dopo essere state lette si salvano subito.

simo_85
21-08-2010, 20:47
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

char *name(char *p, int *len)
{
char a[20];
int i;

printf("Insert Name: ");
scanf("%s", a);
*len = strlen(a);
p = (char *) malloc (sizeof(char) * (*len));

for (i = 0; i < (*len); i++)
p[i] = a[i];

return p;
}

int main(int argc, char *argv[])
{
int len;
char *p;

p = name(p, &len);
printf("%s - %d\n", p, len);

free(p);

return 0;
}

Dovrebbe essere corretto come esempio..

Ippo343
21-08-2010, 20:53
Veramente, se ho capito bene cosa intende fare lui, non va bene, perchè il codice di simo_85 ha comunque un buffer di dimensione fissa che poi viene troncato.

Dovresti fare un algoritmo del genere:


while ((c = getchar()) != '\n')
{
len = strlen(buffer);
buffer = realloc(buffer, (len + 1));
buffer[len] = c;
len++;
}


Leggi un carattere, e se non è il newline, allora incrementi le dimensioni della stringa di un char e inserisci il carattere letto in fondo.

Fearuin
22-08-2010, 12:41
Ecco cosa mi mancava! realloc! >_< Ottimo grazie mille!
Potrei perciò utilizzare anche la funzione gets, invece che getchar, dato che in fondo anche gets tende a superare i limiti del buffer che verrebbe poi riallocato con realloc, una cosa del tipo:

main(){
char buff[10], *message;
printf("Inserisci la prima linea: \n");
gets(buff);
message=realloc(NULL, strlen(buff)+1);
puts(buff);
system("PAUSE");
return 0;
};
giusto?

Ippo343
22-08-2010, 12:54
No.

Non confondere le cose: nel codice che ti ho postato io:
_viene letto un carattere
_il buffer viene aumentato di un carattere
_viene aggiunto il carattere in fondo al buffer

Nel codice che hai postato tu
_hai un buffer di dimensioni fisse
_con gets lo riempi e probabilmente lo superi causando un segmentation fault
_se per caso non avessi riempito il buffer e il programma non crasha, riduci la dimensione del buffer a quella della stringa

Fearuin
22-08-2010, 12:58
Giusto...non avevo minimamente pensato ai contro...bèh mi hai risolto non pochi problemi con questa chicca XD, grazie mille! ^__^

Fearuin
01-09-2010, 11:24
Ho un altro problema, cercando di rifarmi al codice che mi avete gentilmente suggerito, ho elaborato questo:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
main(){
char *buffer, ch;
int n, f, i;
n=0;
buffer = (char *) malloc(sizeof(char));
if(!buffer){
puts("Memory failed");
exit(EXIT_FAILURE);
}
printf("Inserisci la frase: ");
while(ch='\n'){
ch=getchar();
if(ch='\b'){
if(n>1) {
n--;
buffer=realloc(buffer, n*sizeof(char));
}
else if(n==1) n--;
else if(n==0) break;
}
else {
buffer[n]=ch;
n++;
buffer=realloc(buffer, n*sizeof(char));
}
}
buffer=realloc(buffer, (n+1)*sizeof(char));
buffer[n]='\0';
printf("La frase e': ");
puts(buffer);
printf("\n");
system("PAUSE");
return 0;
}
L'unico problema è al momento della stampa, cioè non stampa niente, come se il buffer caricato fosse vuoto(cosa che sospetto) però non riesco a individuare il problema :master:

Ippo343
01-09-2010, 11:57
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <conio.h>

int main()
{
char *buffer, ch;
int n;
n = 1;

buffer = (char *) malloc(sizeof(char));

if(!buffer)
{
puts("Memory failed");
exit(EXIT_FAILURE);
}

printf("Inserisci la frase: ");

ch = 0;
while ((ch = getche()) != '\n')
{
if (ch == '\b')
{
if( n >= 1)
{
n--;
buffer = realloc(buffer, n * sizeof(char));
}
else
break;
}
else
{
buffer[n-1] = ch;
n++;
buffer = realloc(buffer, n*sizeof(char));
}
}

buffer = realloc(buffer, (n+1)*sizeof(char));
buffer[n] = '\0';
printf("La frase e': ");
puts(buffer);
printf("\n");

system("PAUSE");

return 0;
}


Credo che gli errori principali fossero dati dagli assegnamenti usati come comparazioni (= al posto di == ). Inoltre era sbagliata la gestione della dimensione del buffer: dato che tenevi n di uno più piccolo rispetto al buffer, veniva sbagliata la riallocazione del buffer.

Non ho avuto tempo di testare la parte del backspace (purtroppo adesso devo andare) ma non dovrebbe presentare grossi problemi, credo.

getche() legge un carattere senza aspettare il tasto enter, quindi è decisamente meglio in questo caso.

Ciao.

Loading