Newsgroup: it.comp.lang.c++
Titolo: ciclo maledetto

Ciao a tutti
sono tornato dalle vacanze ed ho ancora un piccolo problemino da risolvere
con un vecchio programma; il problema è questo: devo estrarre da un file
creato tramite una system tutte le ricorrenze della voce "Indirizzo fisico"
contenuti all'interno del file; fino ad ora sono stato capace, anche grazie
al vostro aiuto, di visualizzare solo la prima ricorrenza, ma mi servirebbe
un ciclo che mi scansiona tutto il file e mi fa uscire non solo la prima
voce....il codice che ho fatto fin'ora è questo:
#include <iostream.h>
#include <fstream.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
char buf[1000], *ptr;
int main()
{
 system("ipconfig /all > mac.txt");
 ifstream in("mac.txt", ios::in | ios::binary);
 if(!in) {
          cout<<"Impossibile aprire il file";
          return 1;
          }
 in.read((unsigned char *) buf,sizeof buf);
 (ptr = strstr(buf, "Indirizzo fisico"));
 do{
     cout<<*ptr;
     *ptr++;
   }while(*ptr!='\n');
 cout<<"\n";
 in.close();
 system("PAUSE");
 return 0;
}
Spero di essere stato chiaro....grazie dell'aiuto!

Francamente per un problema del genere non userei il C++... Se questo
genere di problema ti si presenta comunemente, considera l'opportunita'
di scaricarti Cygwin, che ti mette a disposizione un po' di comandi
adatti a questo tipo di cose (ad esempio "grep"). In alternativa
potresti usare un linguaggio di scripting, tipo Python.
Ciao,
Nicola

 ha scritto nel messaggio
news:3B8B5C3B...@divalsim.it...


cosa che devo fare per l'uni.....ma è davvero così difficile???????
Ah allora sono compiti! E io che ti stavo già per scrivere il codice
:-)
Giusto per curiosità che università fai? Mi sembra che il tuo C++ non
sia molto recente.
Visto che non pui usare un altro linguaggio (sarebbero 4 o 5 righe di
python) che ne dici di rendere tutto più semplice usanto le
std::string e std::getline?
Marco Barisione (ICQ 84277092)

Ma non ti basta scorrere tutto il file e cercare le parole "indirizzo
fisico" ?
Che ci vuole?
Ciao

 difficile???????
Non č difficile, ma č difficile dare indicazioni senza finire per scrivere
tutto il codice. Comunque, visto che avevo un paio di minuti liberi, ti ho
scritto un rudimentalissimo mini-parser che legge l'output di ipconfig e
inserisce tutte le informazioni in una mappa di mappe (ossia una serie di
coppie chiave-valore divise per sezioni). Non fa esattamente quello che
volevi tu e non č nemmeno garantito che funzioni su ogni sistema, in
quanto fa alcune assunzioni sul formato dell'output che potrebbero anche
non valere sempre. Ad ogni modo, eccolo, divertiti.
#include <iostream>
#include <fstream>
#include <map>
#include <string>
class ipconfig_map
{ public:
  typedef std::map< std::string, std::string >    attrib_map_type;
  typedef std::map< std::string, attrib_map_type> section_map_type;
  typedef section_map_type::iterator              iterator;
  private:
  section_map_type	data_;
  attrib_map_type*	curr_;
  public:
  ipconfig_map( std::ifstream& in ) : curr_(0)
  {
    std::string		line;
    std::string::size_type  p0;
    std::string::size_type  p1;
    std::string::size_type  p3;
    while( ! in.eof() )
    {
      getline(in,line);
      if( line.size() == 0 ) continue;
      p0 = line.find_first_not_of(" \t");
      if( p0 == std::string::npos ) continue;
      p1 = line.find_first_of(":.", p0 );
      if( p1 == std::string::npos || p1 == 0 ) continue;
      while( line[p1-1] == ' ' ){  --p1; }
      if( p0 == 0 ) // inizio nuova sezione...
      {	 curr_ = &( data_[ line.substr(p0,p1-p0) ] );
      }
      else if( curr_ || ( curr_ = &( data_["Config"] ) ) )
      {   // coppia chiave-valore...
        p3 = line.find_first_not_of(" .:", p1 );
        if( p3 == std::string::npos ) continue;
        (*curr_)[ line.substr(p0,p1-p0) ] = 
                     line.substr( p3, line.size()-p3 );
      }
    }
  }
  iterator	begin() { return data_.begin(); }
  iterator	end() { return data_.end(); }
 
  attrib_map_type& operator[]( const std::string& name ) 
  { return  data_[name]; }
};
Esempio:
using std::cout;
using std::endl;
int main()
{
  std::ifstream	in("mac.txt");
  ipconfig_map	m(in);
 for( ipconfig_map::iterator i = m.begin(); i!=m.end(); ++i )
 { cout << (*i).first << endl;
   cout <<" indirizzo fisico = "<<(*i).second["Indirizzo fisico"]<<endl;
 }
}
'notte,
Max

 python) che ne dici di rendere tutto più semplice usanto le
Non conosco python pero' 2 righe di un batch
mac.bat
ipconfig /all > mac.txt
find "Indirizzo fisico" mac.txt
che in c++ diventano 8
mac.cpp
#include <cstdlib>
int main()
{
   std::system("ipconfig /all > mac.txt");
   std::system("find \"Indirizzo fisico\" mac.txt");
   std::system("pause");
   return 0;
}
ciao
Massimo

 }
Ma se e' per l'universita', questo e' barare :-)
Ciao,
Nicola

Anche se ho detto che non avrei + postato, lo faccio lo stesso,
eventualmente stasera mi frusto. :)))))
Cmq ho scritto questa funzione che fà quello che chiedi, l'ò provata e
funziona benone, tengo a precisare che sono poco + che un principiante,
quindi se il codice che scrivo e poco performante o il mio stile fà pena,
datemi tempo, prima o poi le cose miglioreranno. :) ecco il codice :
#include <iostream>
#include <fstream>
#include <string>
#include <map>
std::map<short,short>*
find(std::string szFileName,std::string szWrdShrc)
{
     typedef std::map<short,short> Map;
     Map* vsSPos;
     try{vsSPos=new Map;}
     catch(std::bad_alloc xa)
     {std::cerr<<"Impossibile allocare memoria!\n";exit(0);}
     std::ifstream inFile(szFileName.c_str());
     if(!inFile)
     {
          std::cerr<<"Impossibile aprire il file!\n";
          return 0;
     }
     std::string szActLine,szActWrd;
     std::string::size_type Pos,pPos;
     short sRow=0;
     while(!inFile.eof())
     {
          sRow++;
          std::getline(inFile,szActLine,'\n');
          pPos=0;Pos=0;
          while((Pos=szActLine.find(szWrdShrc,Pos))!=std::string::npos)
          {
               if(vsSPos->count(sRow))
               {
                    Map::iterator it=vsSPos->find(sRow);
                    if(it!=vsSPos->end())
                         it->second++;
               }
               else
                    vsSPos->insert(Map::value_type(sRow,1));
               Pos+=szWrdShrc.size();pPos=Pos;
          }
     }
     return vsSPos;
}
int main()
{
     system("ipconfig /all > mac.txt");
     typedef std::map<short,short> Map;
     Map* Result=find("mac.txt","Indirizzo fisico");
     std::cout<<"Ecco il risultato della ricerca di \"Indirizzo
fisico\":\n";
     Map::iterator beg=Result->begin();
     while(beg!=Result->end())
     {
          std::cout<<"\n Riga :"<<beg->first
               <<" Trovati :"<<beg->second<<std::endl;
          beg++;
     }
     delete Result;
     std::cout<<"Ciao Ciao\n";
     return 0;
}
Ho messo anche un esempio del funzionamento in main, suppongo che il codice
sia auto esplicante, quindi non l'ò commentato ne tantomeno lo spiegherò
ora, ma se vuoi qualche spiegazione, chiedi pure, mi fà piacere aiutare,
come gli altri aiutano me... :))))
Ciao
ps:
compilato con VC++ 6 con service pack 5 e 6 su win2k senza service pack. :)
-- 
Posted from 
smtp.tiscalinet.it
 [195.130.225.147] (may be forged) 
via Mailgate.ORG Server - 
http://www.Mailgate.ORG

 datemi tempo, prima o poi le cose miglioreranno. :) ecco il codice :
[snip]
Giusto qualche suggerimento....
(Non prenderli come una critica ma piuttosto come un consiglio
  a chi sta imparando)
  1) usa nomi piu' pronunciabili
     szWrdShrc sono nove consonanti e neanche una vocale!
     se usi nomi del genere in programmi solo un po' piu'
     lunghi finirai con l'impazzire... sono praticamente
     impossibili da ricordare e facili da scrivere sbagliati...
     Ti consiglio inoltre di lasciar stare la notazione ungherese
     che, in un linguaggio fortemente tipato come il c++, e' inutile
     e, a volte, dannosa. (Ma questa e' solo una mia opinione personale)
     Tral'altro, nel tuo codice, e' anche controintuitiva.
     (Cominicio a dubitare se si tratti di notazione ungherese o se
      piuttosto hai una certa predilezione per le consonanti:
      gia' sz come prefisso per std::string e' strano, ma si puo'
      capire, mentre vs come prefisso per std::map<short,short> e'
      proprio enigmatico...)
  2) cerca di indentare in maniera piu' leggibile
    il blocco try/catch e' praticamente incomprensibile
     non ti costa nulla aggiungere qualche ritorno carrello qua e la
     es.
     try
     {
        ...
     }
     catch(...)
     {
        ...
     }
     saranno il doppio delle linee ma solo pochi caratteri in piu' e
     una migliore leggibilita'
  3) attento ai memory leaks
     (quando non riesci ad aprire il file, esci dalla funzione
      senza liberare la memoria allocata con new)
     In generale e' preferibile evitare new/delete (almeno quando
     non si usa il polimorfismo)
Qualche giorno fa qualcuno ha postato un link a un sito dove
si illustravano le regole d'oro per scrivere codice immanutenibile,
Non e' che ci hai dato un'occhiata ? Sembra che tu le abbia seguite 
quasi tutte !  ;-)
Saluti,
Fabio
-- 
Posted from [194.214.173.28] 


           std::getline(inFile,szActLine,'\n');
Non ho studiato per nulla il codice, ma questa mi e' saltata agli
occhi: viene letta una riga di troppo (l'indicatore di eof viene
settato DOPO aver incontrato l'end-of-file, non PRIMA).
-- 
Maurizio Loreti                         
http://www.pd.infn.it/~loreti/mlo.html
Univ. of Padova, Dept. of Physics - Padova, Italy            
lor...@pd.infn.it