[C con Clase] Concatenar un caracter a una cadena

Steven Davidson srd4121 en njit.edu
Sab Mayo 16 04:40:21 CEST 2009


Hola Chema,

José María Nevárez wrote:
> Hola amigos listeros, quisiera si me podrian decir cual es la forma
> más apropiada de concatenar un solo caracter a una cadena de
> carcteres.
> 
> Ejemplo:
> 
> char *Token;
> char c;
> 
> o si por ejemplo tengo:
> 
> char Token[15];
> char c;
> 
> y quiero concatenar esos dos- Token y c.
> 
> Lo que estoy haciendo es un analizador lexicográfico (SCANNER). Lo
> que hago es tomar una linea de un archivo de texto.
> Y la idea es ir separando las palabras o "tokens" (para después 
> clasificarlos).
> La verdad no sé cual de los dos ejemplos me sirva más para guardar
> los tokens, y como acumular cada carcter leído a cada token.
> 

Si aún queda espacio en 'Token', entonces puedes agregar 'c' al final. 
Sin embargo, si estás intentando crear una cadena de caracteres, 
mantener el carácter nulo al final. Por lo tanto, al agregar un carácter 
al final, también debes agregar el carácter nulo. Por ejemplo,

int nCantidad;
...
Token[nCantidad] = c;
Token[++nCantidad] = 0;  // Carácter nulo y actualizamos 'nCantidad'

Si necesitas redimensionar la cadena para guardar más caracteres, 
entonces me temo que el array no te servirá, porque no se puede 
redimensionar. Por lo tanto, requerirás un puntero, para poder adjudicar 
y posiblemente readjudicar memoria dinámicamente.

Te todas maneras, sugiero usar las STL y en particular la clase 
'string'. Funciona como un array de caracteres, pero automáticamente se 
redimensiona cuando haga falta. Por ejemplo,

string tokens;
char c;
...
tokens.push_back( c );  // o incluso, tokens.append( 1, c );

Acerca del analizador lexicográfico, te aconsejo que la lista de 
"tokens" sea una lista de códigos numéricos que representen tales 
"tokens". Por ejemplo,

enum token_t { PAREN_IZQ, PAREN_DER, OP_ASIGNACION, OP_SUMA, OP_RESTA, 
OP_PRODUCTO, OP_DIVISION, OP_POTENCIA, TIPO_INT, TIPO_FLOAT, 
TIPO_DOUBLE, TIPO_CHAR, TIPO_BOOL };

const char *lista_tokens_cadenas[14] = { "(",
                                          ")",
                                          "=",
                                          "+",
                                          "-",
                                          "*",
                                          "/",
                                          "^",
                                          "int",
                                          "float",
                                          "double",
                                          "char",
                                          "bool",
                                        };

Ahora puedes mantener una lista de enteros que representa los índices a 
cada "token" en nuestra lista de arrays. Por ejemplo,

token_t lista_tokens[1024], token;
...
// Crear la lista de "tokens"
while( ... )
{
   ...
   // Buscar el token que corresponda a la subcadena
   for( ... )
     if( token = BuscarToken( szCadena, lista_tokens_cadenas[i] ) )
       Agregar_Token( lista_tokens, token );
}

En lugar de un array de 'token_t', podríamos usar la plantilla 'vector', 
para no preocuparnos de redimensionar el array. Por ejemplo,

vector< token_t > lista_tokens;
...
if( ... )
   lista_tokens.push_back( token );

Como existe una asociación entre el valor numérico y la cadena de 
caracteres, podríamos usar otra plantilla llamada 'map'. Por ejemplo,

typedef pair< token_t, string > TOKEN_STR;

map< token_t, string > mapa_tokens;

mapa_tokens.insert( TOKEN_STR( PAREN_IZQ, "(" ) );
mapa_tokens.insert( TOKEN_STR( PAREN_DER, ")" ) );
mapa_tokens.insert( TOKEN_STR( OP_ASIGNACION, "=" ) );
mapa_tokens.insert( TOKEN_STR( OP_SUMA, "+" ) );
mapa_tokens.insert( TOKEN_STR( OP_RESTA, "-" ) );
mapa_tokens.insert( TOKEN_STR( OP_PRODUCTO, "*" ) );
...


Espero que todo esto te ayude y te oriente.

Steven





Más información sobre la lista de distribución Cconclase