Newsgroup: it.comp.lang.c
Titolo: Dubbi su char.

Dopo un po di tempo finalmente mi riavvicino al c.
Ora a parte tutto mi sorge un dubbio:
Se voglio ricevere come input una serie di caratteri uso un array di
caratteri e fino a qui non ci piove (almeno spero);
Ma come faccio ad effettuare su questo testo immesso delle operazioni che
operano su int o comunque su tipi di dato numerici?
Per esempio: io voglio che se nell'array (metti char pippo[10]) ho immesso
-(1/x), allora cambia x con 100 e ne calcola il valore assoluto e lo stampa
a video.
Sostanzialmente non mi serve che il programma riconosca che prima di x c'e'
-(1/; In pratica e' possibile far trattare quel char che a questo punto vale
-(1/100) (pippo[0]="-"... ) come un espressione da calcolare (convertendola
se necessario in un dato numerico)???
Scartabellando sull'inossidabile K&R non ho trovato nulla al riguardo.
Grazie a tutti.
Vi][oZ  
-- 
Per rispondere togliere NONSCASSA da reply-to.

a video.
Il C non fornisce alcuna funzione di supporto per questa tua esigenza, devi
fare tutto tu o trovare delle librerie che gestiscano l'input per te.
Quello di cui hai bisogno è una routine che faccia il tipico lavoro del
compilatore riconoscimento sintattico, semantico e conversione in un codice
eseguibile.
Ciao

Scartabellando sull'inossidabile K&R non ho trovato nulla al riguardo.
E' necessario scrivere un "parser" di espressioni matematiche.
Puoi trarre spunto dal seguente programma :
/*********************************************************
 * rdparser.c - parser di espressioni matematiche.       *
 *                                                       *
 * ALCLIB v.2.0 - Andrea Laforgia C Library              *
 * (C)1999 Andrea Laforgia (
andrea_...@bigfoot.com
) *
 *                                                       *
 * NOTE :                                                *
 * Il programma implementa un parser di tipo             *
 * recursive-descendant.                                 *
 *                                                       *
 * L'algoritmo di funzionamento si basa sulla            *
 * discesa ricorsiva per il riconoscimento dei           *
 * simboli terminali e la risoluzione delle              *
 * produzioni della grammatica adottata.                 *
 *                                                       *
 * La grammatica adottata e' la seguente :               *
 *                                                       *
 * espressione ::= espressione + espressione |           *
 *                 espressione - espressione |           *
 *                 fattore                               *
 *                                                       *
 * fattore ::= fattore * fattore |                       *
 *             fattore / fattore |                       *
 *             termine                                   *
 *                                                       *
 * termine ::= costante numerica |                       *
 *             funzione ( espressione ) |                *
 *             ( espressione )                           *
 *                                                       *
 * Il parser riconosce quattro semplici funzioni :       *
 *                                                       *
 * rq()   : estrae la radice quadrata.                   *
 * quad() : calcola il quadrato.                         *
 * ass()  : restituisce il valore assoluto.              *
 * neg()  : restituisce il valore negativo.              *
 *                                                       *
 * Ha, inoltre, alcune limitazioni :                     *
 * non consente l'uso di spazi bianchi,                  *
 * non gestisce la divisione per zero e                  *
 * gli argomenti negativi per rq().                      *
 *                                                       *
 * C'e' un piccolo bug, a dire il vero, scoperto in      *
 * seguito :                                             *
 *                                                       *     
 * la funzione termine() dovrebbe contemplare anche il   *
 * caso "espressione" evitando di implementare un "while"*
 * sia nella funzione espressione() che in fattore().    *
 *                                                       *
 * Ma nonostante questo il programma funziona bene.      *
 *                                                       *
 *********************************************************/
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include <stdlib.h>
#include <math.h>
typedef struct {
                 double num ;
                 char   nome_funz[10] ;
               } tipo_valore ;
typedef struct {
                 char * formula ;
                 int    indice ;
               } oggetto_formula ;
typedef enum { OP_ADDZ,   /* operatore di addizione */
               OP_SOTT,   /* operatore di sottrazione */
               OP_MOLT,   /* operatore di moltiplicazione */
               OP_DIVS,   /* operatore di divisione */
               OP_PARA,   /* operatore parentesi aperta  */
               OP_PARC,   /* operatore parentesi chiusa */
               NOMEFNZ,   /* identificatore di funzione */
               COSTNUM,   /* costante numerica */
               FINEFRM    /* fine formula */
             } tipo_token ;
void errore_sintassi ( oggetto_formula * f )
{
     int i ;
     puts ("errore di sintassi nella formula :") ;
     printf ( "%s\n", f->formula ) ;
     for (i = 0 ; i < f->indice-1 ; i++)
         putchar(' ');
     printf("^\n");
     exit ( 1 ) ;
}
tipo_token prossimo_token ( oggetto_formula * f, tipo_valore * v )
{
     char cnum[20] ;
     int i = 0 ;
     if ( f->formula[f->indice] )
     {
        if ( isdigit ( f->formula[f->indice] ) )
        {
           while ( isdigit ( f->formula[f->indice] ) && (i < 20) )
                 cnum[i++] = f->formula[f->indice++] ;
           cnum[i] = 0 ;
           v->num = atof ( cnum ) ;
           return COSTNUM ;
        }
        else
        if ( isalpha (f->formula[f->indice]) )
        {
           while ( (isalpha (f->formula[f->indice]) ||
                    isdigit (f->formula[f->indice])) &&
                   (i < 10) )
                 v->nome_funz[i++] = f->formula[f->indice++] ;
           v->nome_funz[i] = 0 ;
           if (f->formula[f->indice++] == '(')
              return NOMEFNZ ;
           else errore_sintassi ( f ) ;
        }
        else
        switch ( f->formula[f->indice++] )
        {
               case '+' : return OP_ADDZ ;
               case '-' : return OP_SOTT ;
               case '*' : return OP_MOLT ;
               case '/' : return OP_DIVS ;
               case '(' : return OP_PARA ;
               case ')' : return OP_PARC ;
               default  : errore_sintassi( f ) ;
        }
     }
     else return FINEFRM ;
}
int atteso ( oggetto_formula * f, const tipo_token t )
{
    int i = f->indice ;
    tipo_valore dummy ;
    tipo_token tk = prossimo_token ( f, &dummy ) ;
    if (tk == t) return 1 ;
    else
    {
       f->indice = i ;
       return 0 ;
    }
}
double termine ( oggetto_formula * f )
{
       tipo_token t ;
       tipo_valore v ;
       double x ;
       extern double espressione( oggetto_formula * f ) ;
       switch ( t = prossimo_token( f, &v ) )
       {
              case COSTNUM : return v.num ;
              case OP_PARA : x = espressione ( f ) ;
                             if ( atteso ( f, OP_PARC ) )
                                return x ;
                             else
                                errore_sintassi( f ) ;
              case NOMEFNZ : x = espressione ( f ) ;
                             if ( atteso ( f, OP_PARC ) )
                             {
                                if (!strcmp(v.nome_funz, "rq"))
                                   return sqrt ( x ) ;
                                else
                                if (!strcmp(v.nome_funz, "ass"))
                                   return abs ( x ) ;
                                else
                                if (!strcmp(v.nome_funz, "neg"))
                                   return ( -x ) ;
                                else
                                if (!strcmp(v.nome_funz, "quad"))
                                   return ( x*x ) ;
                             }
                             else errore_sintassi( f ) ;
              default : errore_sintassi( f ) ;
       }
}
double fattore ( oggetto_formula * f )
{
       double op1, op2 ;
       int attesoMOLT, attesoDIVS ;
       op1 = termine ( f ) ;
       while ( (attesoMOLT = atteso ( f, OP_MOLT )) ||
               (attesoDIVS = atteso ( f, OP_DIVS )) )
       {
          op2 = termine ( f ) ;
          if ( attesoMOLT ) op1 = op1 * op2 ;
          else
          if ( attesoDIVS ) op1 = op1 / op2 ;
       }
       return op1 ;
}
double espressione ( oggetto_formula * f )
{
       double op1, op2 ;
       int attesoADDZ, attesoSOTT ;
       op1 = fattore ( f ) ;
       while ( (attesoADDZ = atteso ( f, OP_ADDZ )) ||
               (attesoSOTT = atteso ( f, OP_SOTT )) )
       {
          op2 = fattore ( f ) ;
          if ( attesoADDZ ) op1 = op1 + op2 ;
          else
          if ( attesoSOTT ) op1 = op1 - op2 ;
       }
       return op1 ;
}
void assegna_formula ( oggetto_formula * f, const char * testo )
{
     f->indice = 0 ;
     f->formula = malloc ( strlen(testo) + 1 ) ;
     strcpy ( f->formula, testo ) ;
}
int main ( void )
{
    int counter = 0 ;
    oggetto_formula mia_formula ;
    assegna_formula ( &mia_formula,
                      "(neg(5)-rq(quad(5)-4*6*1))/(2*6)" ) ;
    printf ( "%f\n", espressione ( &mia_formula ) ) ;
    return 0 ;
}
--------------------------------------------------------
* Andrea Laforgia        (
andrea_...@bigfoot.com
) *
--------------------------------------------------------

Interessante...
Grazie 1000 per l'aiuto.
Vi][oZ