Newsgroup: it.comp.lang.c
Titolo: Dubbi stringhe...

Ciao a tutti, mi č venuto un piccolo dubbio forse stupido...
Se io dovessi creare un programma che riceve (con scanf)una stringa di una certa lnghezza e poi la manipola, farei una definizione del tipo:
char str[10]; //(10 come esempio)
Ma se io volessi ricevere invece una stringa di una lunghezza non determinata, come posso fare?? Se io facessi una definizione cosě:
char *str;
dopo dovrei allocare un certo spazio in memoria in base alla lunghezza della stringa che inserisco.. ma come faccio a sapere quanta memoria allocare?? Se non alloco memoria mi da ovviamente errore di accesso alla memoria...come fare?
Grazie
-- 
Questo articolo e` stato inviato dal sito web 
http://www.nonsolonews.it

 fare?
Questa la so anch'io :-)
usa la funzione str = malloc(dimensione);
-- 
ciao
tony

come fare?
Quando si legge una stringa dall'input, in generale bisogna sapere
*esattamente* quanti caratteri leggere.  Questo però perché, in generale,
il "buffering" delle informazioni è affidato alla libreria standard.  Se
si controlla direttamente l'input tramite funzioni non standard ma
specifiche della piattaforma, è possibile gestire carattere per carattere
ed eventualmente espandere a run-time, dinamicamente, lo spazio che
ospiterà la stringa.
-- 
questo articolo e` stato inviato via web dal servizio gratuito 
http://www.newsland.it/news
 segnala gli abusi ad 
ab...@newsland.it

 
Devi allocare un buffer grande abbastanza per il caso peggiore.
Ecco uno dei motivi per cui la scanf() e` sconsigliata!
Ciao
Giovanni
-- 
   A computer is like an air conditioner,
   it stops working when you open Windows.
   Registered Linux user #337974  < 
http://giovanni.homelinux.net/
 >

 Ecco uno dei motivi per cui la scanf() e` sconsigliata!
...
Mi sembra che continua la mitologia negativa della scanf,  che ha 
certamente dei difetti ma non tutti quelli che le sono attribuiti...
Il problema di dover sapere prima di quanta memoria c' e' bisogno per 
contenere una stringa è  un problema legato all' implementazione C 
delle stringhe (mediante array) e  non si risolve passando a funzioni di 
input diverse.
Se non si sa assolutamente nulla di quale possa essere il caso peggiore 
l' unica è  di implementare un meccanismo che permetta di ampliare a 
run time lo spazio in memoria riservato per la stringa.
Una prima possibilità (inefficiente)  è  di riallocare (realloc) spazio 
quando comincia a scarseggiare.  E' però  inefficiente perché  realloc 
effettua una copia della vecchia area di memoria sulla nuova.
Una più  elegante è  di gestire lo spazio per la stringa in input 
mediante una lista concatenata (espandibile quindi a volontà).
Giorgio

 input diverse.
Il problema non è sapere prima quanta memoria serve, ma usare una funzione
che assicuri si usare *quella* memoria e basta e questo problema viene
risolto egregiamente usando, ad esempio, fgets(). Il morale della favola è
che, se scanf() è molto poco sicura, allora si usi una funzione sicura.


 
Chissa' se mi riesce di farti capire il mio punto di vista sull' 
argomento.  In ogni caso può  essere utile per gli altri che leggono.
Non è  molto istruttivo parlare genericamente di  "insicurezza"  della 
scanf senza entrare nello specifico. L' insicurezza della scanf non è 
diversa dall' "insicurezza delle stringhe in C.  Il  linguaggio non 
impedisce a nessuno di omettere o cancellare il terminatore di stringa e 
ecco che si crea una mina vagante. Non per questo la maggioranza di chi 
programma in C abbandona gli array  di char terminati dal carattere nul !
Per evitare i buffer overflow  basta usare l' ampiezza di campo nel 
convertitore di formato. Dopo che uno lo ha imparato,  usa questa 
tecnica esattamente come evita tante altri aspetti pericolosi del 
linguaggio. Se poi per eccesso di prudenza uno vuole evitare 
completamente la scanf libero di farlo. Personalmente trovo questa 
posizione un po' estrema.  Un po' come chi si rifiuta di mangiar funghi 
perchè  così  evita l' Ammanita Falloide.  Vero.  Però addio anche a 
tutti quelli commestibili! Comunque è  questione di gusti. L' importante 
è  di non dare ad intendere  che tutti i funghi sono pericolosi!
I  problemi della scanf ci sono ma stanno altrove. Essenzialmente nella 
difficoltà  di fare in modo pulito un error recovery in caso di problemi 
in lettura.  Ma questa è  un' altra storia rispetto alla domanda dell' OP.
Rispetto alla questione originale,  il problema resta identico anche se 
usi fgets:  devi assegnare un valore al secondo argomento e  soprattutto 
alla  quantità  di memoria che devi usare per immagazzinare i caratteri 
letti.  Questo *prima*  di sapere quanti sono questi caratteri. E, 
relativamente a questo problema, la scanf non c' entra niente e nessuna 
delle funzioni di libreria standard aiuta. Le soluzioni che conosco (a 
parte quella di stimare a spanne il caso peggiore)  sono le due cui 
accennavo sopra. Se conosci altre soluzioni a *questo*  problema,  sarò 
  felice di imparare  qualcosa di nuovo.
Giorgio

 in lettura.  ...
Per chiarire. In questa classe metto anche il famoso problema dello 
svuotamento del buffer di input.
Giorgio

 usi fgets[...]
<snip>
Lo so benissimo.
Ciò che io ho scritto esulava dal problema principale (credevo fosse
chiaro) e si collegava SOLO alla tua discussione sulla sicurezza di
scanf().


 i programmatori C.
Io ho portato dei ragionamenti,  delle argomentazioni.  Tu qui ti stai 
trincerando dietro il principio di autorità. Che sia la maggioranza dei 
programmatori C (misurata come ?) ,  quella degli estensori delle FAQ o 
altro non ha importanza,  è  sempre opporre un ipse dixit  ad un 
ragionamento.
Comunque pazienza. Non sono riuscito a farti capire il mio punto di 
vista neanche stavolta. Ti lascio pure l' ultima parola se ci tieni. Per 
me è  sufficiente.
Giorgio

 ragionamento.
Io sto ragionando a sufficienza e a supporto di certe teorie ti dico che è
il punto di vista di moltissimi programmatori C.  Non si tratta di alcun
"ipse dixit", io *condivido* il loro punto di vista.


 diversa dall' "insicurezza delle stringhe in C.  
Il fatto è che l'istruzione
   scanf("%s",buf);
è SEMPRE rischiosa...
Ora non posso controllare, ma mi sembra di ricordare che nella GLIBC si 
può fare qualcosa del tipo:
   scanf("%as",&buf);
e il buffer viene allocato della dimensione desiderata.
E.

 e il buffer viene allocato della dimensione desiderata.
Confermo:
   * An optional flag character `a' (valid with string conversions only)
     which requests allocation of a buffer long enough to store the
Il problema è che il C99 usa %a per leggere i float...
Luca
-- 
Non ho ancora capito se il mio cane e` maschio o femmina:
quando fa la pipi` si chiude in bagno