PDA

View Full Version : Acquisizione di Stringhe


BigMeister
30-04-2014, 21:22
Sera ragazzi, altro problema. Dovrei acquisire delle stringhe (3 in particolare) da mettere all'interno di tre variabili di tipo char allocate dinamicamente.

Per allocare una stringa voglio fare questo:

stringa = (char *)malloc(sizeof(char)*lunghezza + 1);

Il +1 è dato dal fatto che voglio che sia mantenuto il posto per il carattere terminatore.

Ora la lunghezza ho due modi per averla, una è chiederla direttamente all'utente (e non voglio farlo), l'altra dovreste dirmela voi, so che la strada giusta è con getchar(); carattere per carattere ma non so esattamente dove andare a parare (in rete non riesco a trovare nulla).

Grazie dell'aiuto :)

pabloski
01-05-2014, 00:04
Perchè getchar? In C hai fgets


char str[256];

printf("Inserire stringa: ");
fgets(str, 256, stdin);


Ci sarebbe pure gets, ma quest'ultima non ti permette di specificare la dimensione del buffer, per cui è unsafe.

BigMeister
01-05-2014, 00:36
Con fgets non ho purtroppo un allocazione dinamica della memoria con precisione. Per dirti, ho creato il seguente codice:


#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main()
{
char *stringa,
c;

int i = 0;

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

if ( stringa == NULL )
printf("Memoria non disponibile");

printf("Inserisci la stringa\n");

while ( (c = getchar()) != '\n')
{
stringa = (char *)realloc(stringa, (strlen(stringa)*sizeof(char))+1);
stringa[i] = c;
i++;
}
stringa[strlen(stringa)+1] = '\0';

printf("stringa: %s\n",stringa);

return(0);
}


Questo alloca dinamicamente e automaticamente e precisamente la memoria necessaria per la stringa. Se ora volessi acquisire 3 stringhe contemporaneamente in tre variabili differenti (esempio stringa,stringa1,stringa2) come dovrei fare?

pabloski
01-05-2014, 11:43
Queste stringhe non hanno una dimensione massima oltre la quale non vanno?

Come l'hai fatto tu è computazionalmente molto oneroso. Riallocare ogni volta la memoria è un processo lento e genera molta frammentazione in memoria.

Comunque, se vuoi allocare altre stringhe, devi rifare il malloc e tutto il ciclo while. Ovviamente devono conservare il puntatore alla stringa precedente da qualche parte. Magari in un array o in una lista allocata dinamicamente.

BigMeister
01-05-2014, 17:50
No, non hanno una dimensione massima. In compenso non devo preoccuparmi della complessità computazionale perchè il programma è molto piccolo e non impiegherà troppe risorse. Soluzioni?

pabloski
01-05-2014, 18:23
No, non hanno una dimensione massima. In compenso non devo preoccuparmi della complessità computazionale perchè il programma è molto piccolo e non impiegherà troppe risorse. Soluzioni?

La soluzione è che, per ogni stringa che devi leggere, devi effettuare una malloc e poi le varie realloc. Il puntatore al buffer contenente la stringa precedente va ovviamente conservato da qualche parte, in un'array o una lista.

WarDuck
02-05-2014, 12:11
No, non hanno una dimensione massima. In compenso non devo preoccuparmi della complessità computazionale perchè il programma è molto piccolo e non impiegherà troppe risorse. Soluzioni?

Se è piccolo e non impiegherà troppe risorse allora perché ti preoccupi della memoria? :D.

Comunque sotto Linux hai anche getline() che dovrebbe gestire in automatico l'allocazione.

Edit: provato ora, anche getline alloca più del dovuto:


#include <stdlib.h>
#include <stdio.h>

int main(void)
{
ssize_t r;

size_t allocated = 0;
char* my_string = NULL;

r = getline(&my_string, &allocated, stdin);

if (r < 0)
{
printf("Error while reading.\n");
return r;
}

printf("Allocated: %u bytes\n", allocated);
printf("Read: %d bytes\n", r);

printf("String: %s\n", my_string);

free(my_string);
}


Esempio di esecuzione:

[giulio@giulio-linux STRING]$ ./a.out
Ciao!
Allocated: 120 bytes
Read: 6 bytes
String: Ciao!

Io non mi farei problemi comunque :p.