Windows Check

di il
14 risposte

Windows Check

Qualcuno cortesemente mi può dare un check sotto Windows?

in.h

#ifndef _IN_H
#define _IN_H
/* Public */
#define IN_CHUNK_LEN   0x10
#define IN_ERROR       -1

int       in_char   ( FILE *stream );
int       in_string ( FILE *stream, char **string, size_t max_size );
int       in_value  ( FILE *stream, const char *format, ... );

#endif // _IN_H

in.c

/*
  STANDARD INPUT LIBRARY
  
  --------------------------------------------------------------------------
  2011/02/27 *nix tested 32/64 bits
  --------------------------------------------------------------------------
  2011/02/27 valgrind tested
  ==15498==
  ==15498== HEAP SUMMARY:
  ==15498==     in use at exit: 0 bytes in 0 blocks
  ==15498==   total heap usage: 4,376 allocs, 4,376 frees, 153,020,616 bytes allocated
  ==15498==
  ==15498== All heap blocks were freed -- no leaks are possible
  --------------------------------------------------------------------------

  int in_string (FILE *stream,char **string, size_t max_size)
  Read string from stream allocating CHUNK space.
  Allow unknows dynamic space w/o garbage problems
  input : 
     stream     the streamer
     string     reference to pointer buffer
     max_size   if set to zero it allocs CHUNK dynamic spaces
  return:
     IN_ERROR or NULL ptr string when error occours. you can use either ferror or feof to determinate result.


  int in_value (FILE *stream, const char *format,...)
  Read value(s) from stream using in_string + sscanf
  input : 
     stream     the streamer
     format     according to sscanf format
     ...        sequence of reference arguments
  return:   
    referenced arguments or IN_ERROR when error occours 


  int in_char   ( FILE *stream );
  Read one char from streamer
  input : 
     stream     the streamer
  return:
     char as an int. EOF or error


  Copyright (C) 2011, Max Cavallo <ixamit@gmail.com>
 
  This program is free software; you can redistribute it and/or modify
  it under the terms of the GNU General Public License as published by
  the Free Software Foundation; either version 2 of the License, or
  (at your option) any later version.
 
  This program is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  GNU General Public License for more details.
 
  You should have received a copy of the GNU General Public License
  along with this program; if not, write to the Free Software
  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    
*/

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

#include "in.h"

int in_char (FILE *stream)
{
  return (fgetc(stream));
}

int in_string (FILE *stream, char **string, size_t max_size)
{
  int c;
  int len,size;
  char *s,*n;
  
  size=(max_size) ? max_size : IN_CHUNK_LEN;
  if ((s=(char *)malloc ((size_t)size))==NULL)
  {
    *string=NULL;
    return IN_ERROR;
  }

  for (len=0;!max_size || len+1<max_size;len++)
  {
    c=in_char(stream);
    if (c=='\n' || feof(stream) || ferror(stream))
      break;
    
    if (!max_size && (len+1)%IN_CHUNK_LEN==0)
    {
      size+=IN_CHUNK_LEN;
      if ((n=(char *)realloc (s,(size_t) size))==NULL)
      {
        free (s);
        *string=NULL;
        return IN_ERROR;
      }
      s=n;
    }
    s[len]=(char) c;
  }
  s[len]='\0';
  
  if (feof(stream) || ferror(stream))
  {
    free (s);
    s=NULL;
  }
  
  *string=s;
  
  return len;
}


int in_value (FILE *stream, const char *format,...)
{
  static char *values=" .+-0123456789";
  
  char sub_format[16], modifier;
  char *string,*s;

  int len,flush,ExitCode;

  void *ref_ptr;
  
  va_list va;
  
  len=in_string (stream,&string,0);
  ExitCode=(len < 1 || string==NULL) ? IN_ERROR : 0;
  for (--len;!ExitCode && len>=0 ;len--)
    if (!strchr (values,string[len]))
        ExitCode=IN_ERROR;
  
  if (ExitCode)
  {
    if (string) free (string);
    return ExitCode;
  }
  
  va_start(va,format);

  len=flush=0; modifier=' '; s=string; 
  while (*format!='\0' && *s!='\0' && len+1<16)
  {
          
    sub_format[len++]=*format;
    
    if (strchr ("hlL",*format))
    {
      //
      // Modifier
      //
      modifier=*format;
      //
    }
    if (strchr("din",*format))
    {
      //
      //  Type  int *
      //
      if (modifier=='h')
        ref_ptr=(short int *)           va_arg(va,short int *);
      if (modifier=='l')
        ref_ptr=(long int *)            va_arg(va,long int *);
      else
        ref_ptr=(int *)va_arg(va,int *);
      
      flush=1;
    }
    if (strchr("oux",*format))
    {
      //
      //  Type  unsigned int *
      //
      if (modifier=='h')
        ref_ptr=(unsigned short *)      va_arg(va,unsigned short *);
      if (modifier=='l')
        ref_ptr=(long unsigned int *)   va_arg(va,long unsigned int *);
      else
        ref_ptr=(unsigned int *)        va_arg(va,unsigned int *);
      
      flush=1;
    }
    if (strchr("efg",*format))    
    {
      //
      // Type   float *  
      //
      if (modifier=='l')
          ref_ptr=(double *)            va_arg(va,double *);
      if (modifier=='L')
          ref_ptr=(long double *)       va_arg(va,long double *);
      else
        ref_ptr=(float *)va_arg(va,float *);
      
      flush=1;
    }
    if (flush)
    {
      sub_format[len++]='\0';
      if ((ExitCode=sscanf (s,sub_format, ref_ptr))==IN_ERROR)
        break;
      
      while (*s && *s==' ')  s++;    while (*s && *s!=' ')   s++;
      
      len=flush=0; modifier=' ';
    }
  
    format++;
    
  }
  
  if (*format!='\0' || *s!='\0')
    ExitCode=IN_ERROR;
  
  va_end(va);
  free (string);
  
  return ExitCode;
  
}

int main ()
{
  
  char *string;
  int len;
  
  int    val_int;
  float  val_float;
  long   val_long;
  
  FILE *fp=stdin;
  int count=2;
  
  for (;count;count--)
  {
    do
    {
      printf ("type 3 separated values:");
    } while (in_value (fp, "%d%f%ld", &val_int,&val_float,&val_long) == IN_ERROR);
    printf ("val_int=%d\nval_float=%f\nval_long=%ld\n",val_int,val_float,val_long);
    
    printf ("type string:");
    len=in_string (fp,&string,0);
    if (string && len>=0)
    {
      printf ("\"%s\" - len=%d\n",string,len);
      free (string);
    }
  }
  
  if (fp!=stdin) fclose (fp);
  
  return 0;
}


Grazie

~Max

14 Risposte

  • Re: Windows Check

    Compila OK su WALL mode in VS 2010. con un unico avvertimento:
    
    for (len=0;!max_size || len+1<max_size;len++)
    
    warning C4018: '<' : signed/unsigned mismatch
    
    max_size è size_t invece len è int. Il resto è OK.
  • Re: Windows Check

    Grazie!
    Inizialmente era tutto in size_t. Mi sono dimenticato quel parametro.
    L'echo è abilitato? il BS?

    Grazie ancora skynet

    ~Max
  • Re: Windows Check

    Se per echo intendi il redirect su file o altro non ho provato, altrimenti non so cosa intendi come non so cos'è il BS
  • Re: Windows Check

    Redirect su file provato e funziona:
    
    type 3 separated values:val_int=4
    val_float=6.000000
    val_long=8
    type string:"fsdgfdfg" - len=8
    type 3 separated values:val_int=4
    val_float=7.000000
    val_long=9
    type string:"asfsdgfd" - len=8
    
  • Re: Windows Check

    Si x echo intendo il redirect su stdin/file. Per BS intendo il BackSpace su stdin

    Grazie
  • Re: Windows Check

    OK va.Non si finisce mai di imparare cmq
  • Re: Windows Check

    Grazie ancora sei stato molto gentile. L'ho scritto ieri sera un po' di fretta...

    ~Max
  • Re: Windows Check

    Figurati, ma a che serve cmq? Da utilizzatore C++ non ne vedo l'utilità esendo che esiste lo stringstream o altro per fare le varie conversioni, ma in C può essere utile.
  • Re: Windows Check

    Serve al C.
    La mescolanza di fgets + scanf da luogo a problemi sul buffer di tastiera e poi l'allocazione dinamica non definibile a priori in C non esiste.

    Per gestire il buffer da tastiera ci si lega al BIOS ed al sistema operativo... non se ne esce vivi

    ~Max
  • Re: Windows Check

    Ho visto un bug o qualcosa del genere. se io metto tre variabili ma aggiungo uno spazio o più prima di dare enter mi dice input non corretto? E' il comportamento giusto?
  • Re: Windows Check

    No è un BUG. Thx
  • Re: Windows Check

    Allego, il sorgente modificato per chi ne fosse interessato. Domani faro' richiesta all' sf.net per inserire il progetto in rete per il pubblico utilizzo. Grazie

    in.h
    
    #ifndef _IN_H
    #define _IN_H
    /* Public */
    #define IN_CHUNK_LEN   0x10
    #define IN_ERROR       -1
    
    int       in_char   ( FILE *stream );
    int       in_string ( FILE *stream, char **string, int  max_size );
    int       in_value  ( FILE *stream, const char *format, ... );
    
    #endif // _IN_H
    
    
    in.c
    
    /*
      STANDARD INPUT LIBRARY
      
      --------------------------------------------------------------------------
      2011/02/27 *nix    tested 32/64 bits
      2011/02/27 Windows tested           - thx skynet at iprogrammatori.it
      BUG
      2011/02/27- fixed size_t to int     - thx skynet at iprogrammatori.it
      2011/02/27- fixed tail extra space  - thx skynet at iprogrammatori.it
      --------------------------------------------------------------------------
      2011/02/27 valgrind tested
      ==15498==
      ==15498== HEAP SUMMARY:
      ==15498==     in use at exit: 0 bytes in 0 blocks
      ==15498==   total heap usage: 4,376 allocs, 4,376 frees, 153,020,616 bytes allocated
      ==15498==
      ==15498== All heap blocks were freed -- no leaks are possible
      --------------------------------------------------------------------------
    
      int in_string (FILE *stream,char **string, int max_size)
      Read string from stream allocating CHUNK space.
      Allow unknows dynamic space w/o garbage problems
      input : 
         stream     the streamer
         string     reference to pointer buffer
         max_size   if set to zero it allocs CHUNK dynamic spaces
      return:
         IN_ERROR or NULL ptr string when error occours. you can use either ferror or feof to determinate result.
    
    
      int in_value (FILE *stream, const char *format,...)
      Read value(s) from stream using in_string + sscanf
      input : 
         stream     the streamer
         format     according to sscanf format
         ...        sequence of reference arguments
      return:   
        referenced arguments or IN_ERROR when error occours 
    
    
      int in_char   ( FILE *stream );
      Read one char from streamer
      input : 
         stream     the streamer
      return:
         char as an int. EOF or error
    
    
      Copyright (C) 2011, Max Cavallo <ixamit@gmail.com>
     
      This program is free software; you can redistribute it and/or modify
      it under the terms of the GNU General Public License as published by
      the Free Software Foundation; either version 2 of the License, or
      (at your option) any later version.
     
      This program is distributed in the hope that it will be useful,
      but WITHOUT ANY WARRANTY; without even the implied warranty of
      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      GNU General Public License for more details.
     
      You should have received a copy of the GNU General Public License
      along with this program; if not, write to the Free Software
      Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
        
    */
    
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <stdarg.h>
    
    #include "in.h"
    
    int in_char (FILE *stream)
    {
      return (fgetc(stream));
    }
    
    int in_string (FILE *stream, char **string, int max_size)
    {
      int c;
      int len,size;
      char *s,*n;
      
      size=(max_size) ? max_size : IN_CHUNK_LEN;
      if ((s=(char *)malloc ((size_t)size))==NULL)
      {
        *string=NULL;
        return IN_ERROR;
      }
    
      for (len=0;!max_size || len+1<max_size;len++)
      {
        c=in_char(stream);
        if (c=='\n' || feof(stream) || ferror(stream))
          break;
        
        if (!max_size && (len+1)%IN_CHUNK_LEN==0)
        {
          size+=IN_CHUNK_LEN;
          if ((n=(char *)realloc (s,(size_t) size))==NULL)
          {
            free (s);
            *string=NULL;
            return IN_ERROR;
          }
          s=n;
        }
        s[len]=(char) c;
      }
      s[len]='\0';
      
      if (feof(stream) || ferror(stream))
      {
        free (s);
        s=NULL;
      }
      
      *string=s;
      
      return len;
    }
    
    
    int in_value (FILE *stream, const char *format,...)
    {
      static char *values=" .+-0123456789";
      
      char sub_format[16], modifier;
      char *string,*s;
    
      int len,flush,ExitCode;
    
      void *ref_ptr;
      
      va_list va;
      
      len=in_string (stream,&string,0);
      while (len && string[len-1]==' ')    string[--len]='\0';
      ExitCode=(len < 1 || string==NULL) ? IN_ERROR : 0;
      for (--len;!ExitCode && len>=0 ;len--)
        if (!strchr (values,string[len]))
            ExitCode=IN_ERROR;
      
      if (ExitCode)
      {
        if (string) free (string);
        return ExitCode;
      }
      
      va_start(va,format);
    
      len=flush=0; modifier=' '; s=string; 
      while (*format!='\0' && *s!='\0' && len+1<16)
      {
              
        sub_format[len++]=*format;
        
        if (strchr ("hlL",*format))
        {
          //
          // Modifier
          //
          modifier=*format;
          //
        }
        if (strchr("din",*format))
        {
          //
          //  Type  int *
          //
          if (modifier=='h')
            ref_ptr=(short int *)           va_arg(va,short int *);
          if (modifier=='l')
            ref_ptr=(long int *)            va_arg(va,long int *);
          else
            ref_ptr=(int *)va_arg(va,int *);
          
          flush=1;
        }
        if (strchr("oux",*format))
        {
          //
          //  Type  unsigned int *
          //
          if (modifier=='h')
            ref_ptr=(unsigned short *)      va_arg(va,unsigned short *);
          if (modifier=='l')
            ref_ptr=(long unsigned int *)   va_arg(va,long unsigned int *);
          else
            ref_ptr=(unsigned int *)        va_arg(va,unsigned int *);
          
          flush=1;
        }
        if (strchr("efg",*format))    
        {
          //
          // Type   float *  
          //
          if (modifier=='l')
              ref_ptr=(double *)            va_arg(va,double *);
          if (modifier=='L')
              ref_ptr=(long double *)       va_arg(va,long double *);
          else
            ref_ptr=(float *)va_arg(va,float *);
          
          flush=1;
        }
        if (flush)
        {
          sub_format[len++]='\0';
          if ((ExitCode=sscanf (s,sub_format, ref_ptr))==IN_ERROR)
            break;
          
          while (*s && *s==' ')  s++;    while (*s && *s!=' ')   s++;
          
          len=flush=0; modifier=' ';
        }
      
        format++;
        
      }
      
      if (*format!='\0' || *s!='\0')
        ExitCode=IN_ERROR;
      
      va_end(va);
      free (string);
      
      return ExitCode;
      
    }
    
    int main ()
    {
      
      char *string;
      int len;
      
      int    val_int;
      float  val_float;
      long   val_long;
      
      FILE *fp=stdin;
      int count=2;
      
      for (;count;count--)
      {
        do
        {
          printf ("type 3 separated values:");
        } while (in_value (fp, "%d%f%ld", &val_int,&val_float,&val_long) == IN_ERROR);
        printf ("val_int=%d\nval_float=%f\nval_long=%ld\n",val_int,val_float,val_long);
    
        printf ("type string:");
        len=in_string (fp,&string,0);
        if (string && len>=0)
        {
          printf ("\"%s\" - len=%d\n",string,len);
          free (string);
        }
    
      }
      
      if (fp!=stdin) fclose (fp);
      
      return 0;
    }
    
    ~Max
  • Re: Windows Check

    Grazie a te per i commenti aggiunti
  • Re: Windows Check



    ~Max
Devi accedere o registrarti per scrivere nel forum
14 risposte