Newsgroup: it.comp.lang.c
Titolo: [NEWBIE]Problemi con le stringhe

Sto cercando di imparare il C, provenendo da altri linguaggi di
programmazione
Ho un problema con una breve applicaizone, che ho messo giů per
"apprendere" l'uso delle stringhe
In pratice dovrebbe richiedere un input all'utente (un numero n) e
visualizzare una stringa formata da n caratteri ascii
Tutto riesce bene finoa  che il numero immesso č < 15
Da li in avanti, nella stringa restituita viene tolto l'ultimo
carattere e inserita una stringa che č presa dal percorso di uno dei
drive del sistema
se per esempio il drive F č sul percorso c;\temp
mi resituisce ABC.........QRS\	temp
Cosa sto sbagliando ?
C'č qualche "blocco di memoria" o limite fisico nel C ?
Lavoro wu win2k sp3 con compilatore devc++ (l'ultima rel. disponibile
sul sito)
Grazie anticipatamente per l'aiuto
Di seguito il codice
Andrea
----------------------------------------------------------------------------------------------------
#include <stdio.h>
#include <stdlib.h>
char *ptr,*p;
int conta;
int numeri=0;
main()
{
  printf ("Quanti caratteri devo inserire ? \t");
  scanf("%d",&numeri);
  // se non inserisco un numero > 1, termino il programma
  if(numeri<1)
   {
     printf("\n Arrivederci \n");
     return 1;
   }
 
  // altrimenti genero la stringa
  ptr=malloc((numeri+1)*sizeof(char));
 
  if(ptr==NULL)
 {printf("Memoria insufficiente! impossibile continuare");
  return 1;}
 
  // genero la stringa da elaborare
  printf("\n\n");
  char ascii='a';
  int i;
  p=ptr;
  for(i=0;i<=numeri;i++)
   {*p++=ascii;
    printf("%d %c \n",i,ascii);
    ascii++;
   }
 
 p='\0'; 
 printf("Stringa generata : %s",ptr);
 return 0;
 
 
 
}

    }
A parte che queste dichiarazioni "sparse" per il codice
mi sanno piu' di C++ che di C (mi riferisco a int i; e char ascii=...;)
di sicuro un errore consiste nel seguente ciclo:
facendo for(i=0; i<=numeri; i++) tu esegui il ciclo
numeri+1 volte.
Quindi stai scrivendo una stringa lunga (numeri+1) 'a' + un terminatore
ovvvero un totale di numeri+2 caratteri
in un posto che hai allocato per numeri+1 caratteri.
Cio' e' MALE....
ciao,
g.

  for(i=0;i<=numeri;i++)
dovrebbe essere <numeri, non <=numeri altrimenti scrivi un carattere in piu'
di quello richiesto ed inoltre vai fuori dalla memoria allocata quando metti
il carattere \0.
Tommy

numeri+1 volte.
Già..... avevo inserito un incrementatore a numero dopo che veniva
inserito, poi l'ho tolto e non ho corretto il resto.
Grazie!
Come mi consiglieresti di gestire le dichiarazioni di variabili ?
vorrei anche chiederti un opinione:
il mio obbiettivo è arrivare ad apprendere c++ e java
Poichè mi sono accorto che molti linguaggi, soprattutto interpretati
(vedi php e perl) prendono molto dalla logica e dalla sintassi C, mi è
davvero utile dedicare del tempo al C prima di passare a c++  ?
(vorrei eviatre un errore commesso in passato: quello di buttarmia
capofitto su Delphi senza passare per una valida conoscenza del
Pascal, e poi dover ritornare al Pascal....)
Grazie per l'interessamento
Andrea


Perchè ?
Una stringa non è un array di carrateri (char) terminante con un
carattere null ?
Andrea


ok, è sbagliato e ho visto (mi era scappato l'operatore.....)
però me lo compilava ugualmente e, dopo aver corretto il ciclo for,
funzionava regolarmente anche con p='\0'
......
Andrea

 carattere null ?
Si!
Ma in questo modo tu non fai altro che dire al puntatore di puntare a null.
Per fare quello che dici tu devi fare come ti ho detto io.
Tommy


Funzionava perche'
1) o la tua malloc azzera la memoria che alloca (e quindi quel byte era 
gia' a zero). oppure
2) quel byte era gia' a zero per motivi suoi.
Entrambe le cose possono essere false, di solito...
Sul fatto che te lo compilasse ugualmente non c'e'
nulla di strano, visto che mettere a zero una variabile che
contiene un puntatore e' una operazione perfettamente lecita.
ciao.
g.

 funzionava regolarmente anche con p='\0'
Non e' detto che funzioni sempre. Quello che fai e' sbagliato!
Tu imposti solamente il puntatore p a NULL, non dici affatto (come dovresti
invece fare) che l'ultimo carattere della stringa punti sia \0, per fare
cio' devi scrivere quello che ti detto io.
Ripeto, il fatto che funzioni regolarmente e' puro caso. Funziona in quanto
l'area di memoria che usi e' "per tua fortuna" circondata da byte a 0. Se
non lo fossero la tua stringa non terminerebbe mai quando la vuoi stampare a
video.
Non farti fregare del fatto che funzioni (a volte), e' profondamente
sbagliato e... ad esempio sul mio compilatore NON funziona!
Tommy

 davvero utile dedicare del tempo al C prima di passare a c++  ?
La mia risposta non piacera' alla maggior parte dei "giovani
programmatori". Comunque e' molto soggettiva e vi prego di non
scatenare il solito flame-war.
Secondo me farsi le ossa su un linguaggio "vecchio stile" come
il C ha diversi vantaggi. Intanto e' piu' semplice da imparare
rispetto ai linguaggi ad oggetti e ti da' maggiore liberta' mentale:
molta gente che ho visto imparare direttamente un linguaggio ad oggetti
non riusciva a "pensare" se non in quel modo. Con chiare forzature
(dieci classi per calcolare 2+2) e perdendo a volte di vista certi
problemi di efficienza (in termini di memoria allocata e velocita'
di esecuzione) che chi impara a programmare in modo piu' rudimentale
penso abbia piu' presenti e che magari un giorno ti possono servire.
Naturalmente se uno ha gia' consistenti esperienze di programmazione
penso possa affrontare direttamente il c++ o java.
Sinceramente penso che il problema che tanti affrontano quando
cominciano a programmare non dipenda dal linguaggio in se' ma dal
prendere l'abitudine a tradurre un problema in una soluzione algoritmica
efficace.
Ciao,
g.

 Pascal, e poi dover ritornare al Pascal....)
Se tu ti butti su Delpi provando a caso il tuo ragionamento funziona.
Tuttavia se ti sei comprato un buon libro di Delphi che spieghi anche il
linguaggio del delphi ed i suoi costrutti quello che dici non ha senso!
Tra le altre cose il Delphi non e' il Pacal, e' certamente basato sul
pascal, ma tanto per dirne una e OO (object oriented) mentre il Pascal
classico non lo e'!
Pur non essendo d'accordo sul fatto che per programmare delphi sia
necessario sapere pascal, (lo si puo' imparare direttamente con delphi), ti
ricordo che il C++ non prevede finestre, pulsanti, etc.. e' come il C in
questo senso, "un linguaggio puro" e quindi il tuo esempio Delphi/Pascal non
calza nemmeno tanto.
Se tu  mi avessi detto devo imparare il C++ prima di imparare il VisualC++
io ti avrei detto certamente di SI.
In pratica se vuoi imparare java inizia con java. Se vuoi imparare C++
inizia con C++. Se vuoi imparare Delphi inizia con Delphi. Se vuoi imparare
il Visual C++ inizia con il C++ semplice. Se vuoi imparare Borland C++
inizia con il C++ semplice. Se vuoi  imparare il C inizia pure con il C ma
ricordati che non e' un linguaggio molto adatto ai principianti.
Io adoro il C e per certi versi lo consiglio anche a chi deve iniziare.
Tuttavia devo ammettere che e' un linguaggio molto "stronzetto" per i
principianti ed e' per questo che molti lo sconsigliano! Forse il C++ se
imparato poco alla volta, nonostante sia un linguaggio mooolto piu'
complesso del C, e' per certi versi piu' adatto ai principianti rispetto al
C.
Certamente java e' piu semplice di C++ ed e' piu' adatto ai principianti
rispetto a C. E' per questo che molti iniziano con java, e' un buon
compromesso, tra le altre cose, come il C++, e' OO (mentre il C non lo e').
Concludo dicendo che nella battaglia C++ vs Java io sono per il C++, e
quindi se hai voglia di sforzarti un pochino di piu' inizia pure con il C++!
Tommy
P.S. Molti parlano bene di pyton per iniziare. Non sono un esperto di pyton
ma credo abbiano ragione!

 problemi di efficienza
Beh, concordo con te. Per questo se uno inizia con il C++ (linguaggio OO)
dovrebbe comprare un buon libro che non sottovaluti la parte procedurale e
che non faccia diventare le persone "class happy"!
Tra i linguaggi procedurali pero' il C e' "stronzetto", il pascal
(nonostante mi piaccia poco) e' piu' adatto ad iniziare.
Ma visto che il nostro amico conosce gia' pascal puo' andare direttamente al
C++ forse...
Tommy

  p='\0';
*p='\0';
EMG
--
EMAG Software Homepage:     
http://www.emagsoftware.it
The EMG's ZX-Spectrum Page: 
http://www.emagsoftware.it/spectrum
The Best of Spectrum Games: 
http://www.emagsoftware.it/tbosg

Grazie a tutti per le risposte, molto esaurienti
Andrea