Newsgroup: it.comp.lang.c
Titolo: stdin

E' possibile inserire dei caratteri nel buffer stdin
come se avessi scritto dalla tastiera?
mi sarebbe molto utile per fare un parser, mi spiego meglio:
int numero;
char *pippo = "(345+21)";
//qui dovrei mettere la stringa pippo nel buffer stdin; ma come??
getchar();   //salta il primo carattere '('
scanf("%i",&numero);
ovviamente potrei usare sscanf che opera su un buffer di memoria, ma
avrei
bisogno necessariamente di usare uno stream (di memoria) che mi faccia
avanzare un
puntatore.
in pratica vorrei sfruttare le funzioni già esistenti del C
che operano sui file e sugli stream compresi 'stdin/stout',
evitando cosi di farne delle nuove.
se qualcuno mi puo' aiutare lo ringrazio anticipatamente.
DaveNlp

 scanf("%i",&numero);
????
   int   tokLen = 0;
   char* endP   = NULL;
   char* startP = NULL;
   char  buff[256];
 
   startP = pippo;
 
   startP = strchr(pippo, '(');
// Elimina spazi di testa
// ----------------------
   while(isspace(*startP))
      startP++;
   endP = strchr(startP, '+');
   tokLen = endP - startP;
   strncpy(buff, startP, tokLen);
   buff[tokLen] = '\0'; 
// Elimina spazi di coda 
   while(isspace(buff[tokLen -1]))
   {
      tokLen--;
      buff[tokLen] ='\0';
   }
   // Conversione primo token
   // -----------------------
   ....
   startP = endP+1;
// Ricerca e conversione del secondo token
// ---------------------------------------
   ....
e tutto senza complicarsi troppo la vita...
C:\>iao Angelo
P.S. La vita si complica quando cominci a considerare il fatto che
     alcune di quelle chiamate possono restituire NULL in caso di
     errore nella stringa da processare.
-- 
Posted via Mailgate.ORG Server - 
http://www.Mailgate.ORG

 char *pippo = "(345+21)";
prima di tutto questo tipo di sintassi e sbagliata..  perchè non hai
allocato dello spazio..
e comunque se tieni un indice e fai avanzare la lettura su stirnga non va
bene?
tipo:
while (pippo[i]!=0)
{
//    pippo[i] è la tua lettera....
    i++;
}

non avevo ben capito il tuo problema, sorry

 allocato dello spazio..
La sintassi e` perfettamente corretta. L'assegnamento e` valido (i tipi 
coinvolti coincidono in quanto il letterale stringa sulla destra decade 
in un char *).
Ricordiamo infatti come l'operatore = non provochi la copia della 
stringa carattere per carattere, bensi` l'assegnamento dell'indirizzo 
del primo carattere della stringa di cui sopra alla variabile pippo.
L'errore a cui ti riferisci si ha in un caso del genere:
     char *pippo;
     strcpy(pippo, "(345+21)");
Questo si` che e` sbagliato.
-- 
Enrico `Trippo' Porreca

 in un char *).
Quello che pero' succede e' che pippo puo' puntare in questo
modo in una zona di memoria che il sistema operativo
potrebbe assumere essere di sola lettura.
In tal caso una modifica della stringa puntata da pippo
(operazione perfettamente legittima) potrebbe
(almeno stando ad un messaggio in un thread di alcuni giorni fa) causare
un eccezione su particolari accoppiate compilatore/sistema operativo.
Mi piacerebbe che qualcuno confermasse/smentisse questa cosa.
ciao,
g.

 Mi piacerebbe che qualcuno confermasse/smentisse questa cosa.
Compilato con VC++ 5.0, non da nessun problema se si modifica la
stringa, compilando con mingw lo stesso codice si ottengono splendidi
fuochi artificiali :-)
HTH
C:\>iao Angelo
P.S. Se non ricordo male, con gcc e' derivati e' possibile specificare
     se quel tipo di valiabili deve essere messo in memoria read only
     o meno, con VC++ non so.


 fuochi artificiali :-)
Grazie! Sono felice di aver sempre evitato questa modo di mettere le
stringhe nel codice...
E se uno scrive
char p[]={"ciao pippo"};
a parte il fatto di non poter modificare *p, pero'
la stringa puntata in questo caso presumo
si possa modificare a piacimento, o sbaglio ?
ciao,
g.

 si possa modificare a piacimento, o sbaglio ?
Non vedo perche' tu non possa modificare la 'c' di "ciao pippo",
visto che tutto il contenuto dell'array e' modificabile. :-)
C:\>iao Angelo


 visto che tutto il contenuto dell'array e' modificabile. :-)
Si vole vovo dire che non posso modificare p in quanto
indirizzo (penso tu avessi capito.)
ciao,
g.

 ciao,
:-)


 evitando cosi di farne delle nuove.
*Se* vuoi evitare di scrivere nuove funzioni, *allora* devi abbandonare
l'idea di restare nel C standard; esso, infatti, non fornisce di _suo_
strumenti per il parsing avanzato (_ovviamente_ ti fornisce gli strumenti
per potertene scrivere uno ... ma se non vuoi scrivere nuove cose ...).
[OT]
*Se* le righe che devi andare a leggere sono semplici come nel tuo
esempio (tonda, numero, piu`, numero, tonda), ti basta un codice
cosi` (con 2 modifiche riesci a coprire le 4 operazioni base):
[code]
#include <stdio.h>
#include <stdlib.h>
#include <regex.h>
#define MATCH_RPATTERN  "^"                     \
                        "[[:blank:]]*"          \
                        "\\("                   \
                        "[[:blank:]]*"          \
                        "([+-]?[[:digit:]]+)"   \
                        "[[:blank:]]*"          \
                        "\\+"                   \
                        "[[:blank:]]*"          \
                        "([+-]?[[:digit:]]+)"   \
                        "[[:blank:]]*"          \
                        "\\)"                   \
                        "[[:blank:]]*"          \
                        "$"
static __inline__ int __is_valid(char *buff, regex_t *match, int *result)
 {
   regmatch_t offset[3];
   int i;
   *result = 0;
   if (!regexec(match, buff, 3, offset, 0))
     {
       for(i = 1; i < 3 && offset[i].rm_so != -1; i++)
        {
          *(buff + offset[i].rm_eo) = '\0';
          *result += atoi(buff + offset[i].rm_so);
        }
       return 1;
     }
   return 0;
 }
int main (void)
 {
   char line[256];
   regex_t this;
   int result;
   regcomp (&this, MATCH_RPATTERN, REG_EXTENDED | REG_ICASE | REG_NEWLINE);
   while (fgets (line, sizeof(line), stdin))
    if (__is_valid(line, &this, &result))
      printf("\t>>> %d\n", result);
   regfree (&this);
   return 0;
 }
[/code]
Questo semplice codice esegue la somma tra due interi, siano essi
positivi o negativi. Fa il parsing del buffer passatogli e, se risuta
valido,memorizza il risultato della somma in result.
[/OT]
Entrambi i codici non sono testati, e mancano i soliti sanity check.
Ciao.
-- 
questo articolo e` stato inviato via web dal servizio gratuito 
http://www.newsland.it/news
 segnala gli abusi ad 
ab...@newsland.it


ok, grazie mille per il codice,
ma questo tuo prog. fa l'input da tastiera..
invece a me serve che legga una stringa da un buff. di memoria.
Ad ogni modo, dopo lunghe ricerche su internet sono
riuscito a trovare del codice sorgente per gestire gli stream
e con funzioni per fare un parser sintattico.
vi ringrazio tutti comunque,
pensavo che ci fosse un trucco per mettere
una stringa di caratteri nel buffer stdin.
saluti.
Dave

 un eccezione su particolari accoppiate compilatore/sistema operativo.
Il problema e` che la modifica della stringa puntata da pippo *non* e` 
un'operazione legittima ai sensi dello standard. Infatti un'operazione 
di questo tipo produce comportamento indefinito, e l'implementazione e` 
libera qundi di reagire in qualsiasi maniera (permettere la modifica, 
terminare il programma, etc...).
-- 
Enrico `Trippo' Porreca