4.3.2. Encontrar el primero/último de un conjunto de caracteres

La función miembro find_first_of( ) y find_last_of( ) pueden ser convenientemente usadas para crear una pequeña utilidad the ayude a deshechar los espacion en blanco del final e inicio de la cadena. Nótese que no se toca el string originar sino que se devuelve una nuevo string:

//: C03:Trim.h
// General tool to strip spaces from both ends.
#ifndef TRIM_H
#define TRIM_H
#include <string>
#include <cstddef>

inline std::string trim(const std::string& s) {
  if(s.length() == 0)
    return s;
  std::size_t beg = s.find_first_not_of(" \a\b\f\n\r\t\v");
  std::size_t end = s.find_last_not_of(" \a\b\f\n\r\t\v");
  if(beg == std::string::npos) // No non-spaces
    return "";
  return std::string(s, beg, end - beg + 1);
}
#endif // TRIM_H ///:~

Listado 4.17. C03/Trim.h


La primera prueba checkea si el string esta vacío; en ese caso, ya no se realizan más test, y se retorna una copia. Nótese que una vez los puntos del final son encontrados, el constructor de string construye un nuevo string desde el viejo, dándole el contador incial y la longitud.

Las pruebas de una herramienta tan general den ser cuidadosas

//: C03:TrimTest.h
#ifndef TRIMTEST_H
#define TRIMTEST_H
#include "Trim.h"
#include "../TestSuite/Test.h"

class TrimTest : public TestSuite::Test {
  enum {NTESTS = 11};
  static std::string s[NTESTS];
public:
  void testTrim() {
    test_(trim(s[0]) == "abcdefghijklmnop");
    test_(trim(s[1]) == "abcdefghijklmnop");
    test_(trim(s[2]) == "abcdefghijklmnop");
    test_(trim(s[3]) == "a");
    test_(trim(s[4]) == "ab");
    test_(trim(s[5]) == "abc");
    test_(trim(s[6]) == "a b c");
    test_(trim(s[7]) == "a b c");
    test_(trim(s[8]) == "a \t b \t c");
    test_(trim(s[9]) == "");
    test_(trim(s[10]) == "");
  }
  void run() {
    testTrim();
  }
};
#endif // TRIMTEST_H ///:~

Listado 4.18. C03/TrimTest.h


//: C03:TrimTest.cpp {O}
#include "TrimTest.h"

// Initialize static data
std::string TrimTest::s[TrimTest::NTESTS] = {
  " \t abcdefghijklmnop \t ",
  "abcdefghijklmnop \t ",
  " \t abcdefghijklmnop",
  "a", "ab", "abc", "a b c",
  " \t a b c \t ", " \t a \t b \t c \t ",
  "\t \n \r \v \f",
  "" // Must also test the empty string
}; ///:~

Listado 4.19. C03/TrimTest.cpp


//: C03:TrimTestMain.cpp
//{L} ../TestSuite/Test TrimTest
#include "TrimTest.h"

int main() {
  TrimTest t;
  t.run();
  return t.report();
} ///:~

Listado 4.20. C03/TrimTestMain.cpp


En el arrglo de string, puede ver que los arreglos de carácter son automáticamente convertidos a objetos string. Este arreglo provee casos para checkear el borrado de espacios en blanco y tabuladores en los extremos, además de asegurar que los espacios y tabuladores no son borrados de la mitad de un string.