Newsgroup: it.comp.lang.c++
Titolo: Token

Il mio problema è generare da un file di testo delimitato da virgole e da cr un
altro file di testo opportunamente modificato.
In java si usano i token e mi sembra che esista qualcosa di simile in c++.
Ho un testo a mia disposizione ma è poco esaustivo.
Sono inesperto del c++ e sono in difficoltà.C'è nessuno che mi darebbe una
breve spiegazione ?
Grazie anticipatamente.
Vittorio Menascì
wonderf...@inwind.it
-- 
Posted from  [194.21.187.199] 
via Mailgate.ORG Server - 
http://www.Mailgate.ORG

In java si usano i token e mi sembra che esista qualcosa di simile in c++.
In C++ non c'č l'equivalente della classe StringTokenizer di Java;
perň la classe string ha (piů o meno) le stesse caratteristiche in 
entrambi i linguaggi, quindi č facile fare uno string_tokenizer sulla
falsariga di quello contenuto nella libreria di Java. Ad esempio (mi
scuso col ng per la lunghezza del codice):
// inizio file string_tokenizer.hpp
#ifndef string_tokenizer_hpp
#define string_tokenizer_hpp
#include <string>
class end_of_tokens_exception {};
class string_tokenizer
{
  int currentPosition;
  int newPosition;
  int maxPosition;
  std::string str;
  std::string delimiters;
  bool retDelims;
  bool delimsChanged;
  char maxDelimChar;
  void setMaxDelimChar() 
  {
    if (delimiters == "")
      {
	maxDelimChar = 0;
	return;
      }
    char m = 0;
    for (int i = 0; i < delimiters.length(); i++) 
      {
        char c = delimiters[i];
        if (m < c)
          m = c;
      }
    maxDelimChar = m;
  }
public:
  string_tokenizer(const std::string& sstr, const std::string& delim=" \t\n\r\f", 
                   bool returnDelims=false) 
  {
    currentPosition = 0;
    newPosition = -1;
    delimsChanged = false;
    str = sstr;
    maxPosition = str.length();
    delimiters = delim;
    retDelims = returnDelims;
    setMaxDelimChar();
  }
  string_tokenizer( const string_tokenizer& st )
  {
    currentPosition = 0;
    newPosition = -1;
    delimsChanged = false;
    str = st.str;
    maxPosition = str.length();
    delimiters = st.delimiters;
    retDelims = st.retDelims;
    setMaxDelimChar();
  }
  ~string_tokenizer() {}
  void reset()
  {
    currentPosition = 0;
    newPosition = -1;
    delimsChanged = false;
    maxPosition = str.length();
  }
private:
  int skipDelimiters(int startPos) 
  {
    int position = startPos;
    while (!retDelims && position < maxPosition) 
      {
        char c = str[position];
        if ((c > maxDelimChar) || (delimiters.find(c)==std::string::npos))
          break;
        position++;
      }
    return position;
  }
  int scanToken(int startPos) 
  {
    int position = startPos;
    while (position < maxPosition) 
      {
        char c = str[position];
        if ((c <= maxDelimChar) && (delimiters.find(c)!=std::string::npos))
          break;
        position++;
      }
    if (retDelims && (startPos == position)) 
      {
        char c = str[position];
        if ((c <= maxDelimChar) && (delimiters.find(c)!=std::string::npos))
          position++;
      }
    return position;
  }
public:
  bool hasMoreTokens()
  {
    newPosition = skipDelimiters(currentPosition);
    return (newPosition < maxPosition);
  }
  std::string nextToken() 
  {
    currentPosition = (newPosition >= 0 && !delimsChanged) ?  
      newPosition : skipDelimiters(currentPosition);
    delimsChanged = false;
    newPosition = -1;
    if (currentPosition >= maxPosition)
      throw end_of_tokens_exception();
    int start = currentPosition;
    currentPosition = scanToken(currentPosition);
    return str.substr(start, currentPosition-start);
  }
  std::string nextToken(const std::string& delim) 
  {
    delimiters = delim;
    delimsChanged = true;
    setMaxDelimChar();
    return nextToken();
  }
  int countTokens() 
  {
    int count = 0;
    int currpos = currentPosition;
    while (currpos < maxPosition) 
      {
        currpos = skipDelimiters(currpos);
        if (currpos >= maxPosition)
          break;
        currpos = scanToken(currpos);
        count++;
      }
    return count;
  }  
};
#endif
// fine file string_tokenizer.hpp
string_tokenizer ha gli stessi metodi di StringTokenizer, e si puň
usare in maniera analoga (con hasMoreTokens):
// inizio file prova.cpp
#include <iostream>
#include "string_tokenizer.hpp"
using namespace std;
int main()
{
  string str="un, due e tre:stella";
 
  string_tokenizer tok( str, " ,:" );  //delimitatori: spazio, virgola, due punti
  while( tok.hasMoreTokens() )
    cout<<tok.nextToken()<<endl;
}
//
// output: 
// un
// due
// e
// tre
// stella
//
// fine file prova.cpp
oppure con un try-catch(end_of_tokens_exception).
A questo punto, puoi leggere l'in_file una riga alla volta, passare la
riga al tokenizer, e scrivere l'out_file una riga alla volta.
-- 
Ciao, Marvin