0% encontró este documento útil (0 votos)
38 vistas11 páginas

Apuntes C++ Manejo Variables Char

El documento describe las cadenas de caracteres en C. Una cadena de caracteres es un arreglo de tipo char que almacena una secuencia de caracteres terminada en 0. Se pueden declarar cadenas, inicializarlas con valores literales o mediante funciones como scanf y printf para entrada y salida de datos.

Cargado por

romanito0
Derechos de autor
© © All Rights Reserved
Nos tomamos en serio los derechos de los contenidos. Si sospechas que se trata de tu contenido, reclámalo aquí.
Formatos disponibles
Descarga como ODT, PDF, TXT o lee en línea desde Scribd
0% encontró este documento útil (0 votos)
38 vistas11 páginas

Apuntes C++ Manejo Variables Char

El documento describe las cadenas de caracteres en C. Una cadena de caracteres es un arreglo de tipo char que almacena una secuencia de caracteres terminada en 0. Se pueden declarar cadenas, inicializarlas con valores literales o mediante funciones como scanf y printf para entrada y salida de datos.

Cargado por

romanito0
Derechos de autor
© © All Rights Reserved
Nos tomamos en serio los derechos de los contenidos. Si sospechas que se trata de tu contenido, reclámalo aquí.
Formatos disponibles
Descarga como ODT, PDF, TXT o lee en línea desde Scribd
Está en la página 1/ 11

CADENA DE CARACTERES

Cuando se estudió los tipos de datos definidos en C, se pudo observar que el lenguaje
C sólo define datos de tipo entero y de punto flotante. Se puede apreciar que existe
un tipo de dato denominado char, sin embargo una variable definida de este tipo
alberga números enteros entre -128 y 127 y no caracteres como lo hacen otros
lenguajes como el Pascal.
También se pudo apreciar que un valor constante de tipo entero se puede expresar de
diferentes formas, por ejemplo como un número entre tradicional (123, 5, 796, 114567,
etc), como un número en base 8, anteponiendo un cero al número (0173, 05, 01434,
337607, etc.) o como números hexadecimales, anteponiéndoles 0x (0x7B, 0x5, 0x31C,
0x1BF87, etc.), pero también se puede expresar un número entero empleando una
notación de caracteres, es decir escribiendo un carácter entre apóstrofos simples
('A', '?', 'h' '%', etc.). Esto se da porque un programa en C/C++ (o en cualquier
otro lenguaje de programación) se redacta en un editor de palabras, por lo tanto todo
lo que se escribe en el editor son secuencias de caracteres. Es el compilador el que
interpreta estos caracteres y los almacena en la memoria como representaciones
binarias. Es lo mismo para el compilador haber escrito int a = 65; que escribir int a
= 'A'; o escribir int a = 0x41; en la dirección de memoria dada para la variable a se
almacena la misma representación binaria (0100 0001). Es por esta razón que una
expresión puede darse de esta manera a = 'A' + 32;, no es que se pretenda sumar el
valor de 32 a la letra A, si no que se esta sumando 32 al valor numérico que este
carácter representa.
En este sentido podemos definir una cadena de caracteres en C como un arreglo en el
que en cada elemento es de tipo char. Los caracteres de una cadena se colocarán uno a
continuación del otro en los elementos del arreglo, a partir del primero. Para poder
saber donde terminan los caracteres válidos en el arreglo, se debe colocar un valor
de terminación al final de la secuencia de caracteres, este valor es cero, que
representa al carácter cuyo código ASCII es cero. Este valor se le puede proporcionar
al arreglo simplemente como 0 ó mediante su representación como carácter: '\0'.
Esta forma de manipular las cadenas de caracteres trae muchas ventajas en comparación
de la forma en que lo hacen otros lenguajes de programación. Por ejemplo en Pascal,
la longitud de las cadenas de caracteres se almacena en la misma representación, al
inicio de la secuencia de caracteres. Como cada elemento de la cadena se almacena en
un byte, y la longitud no es una excepción, las cadenas en Pascal no pueden tener más
de 255 caracteres. Las cadenas en C, al no almacenar el tamaño, permite manejar
cadenas sin límite de tamaño.
DECLARACIÓN:
Una cadena de caracteres es un arreglo de tipo char, por lo tanto una cadena de
caraceres se declara de la siguiente manera:
char identificador [límite];

Por ejemplo:
char nombre[20];
donde "nombre" es una cadena de caracteres que puede albergar hasta 19
caracteres, no olvidar que se requiere un espacio para el delimitador de la
cadena (cero o '\0'). por eso no se pueden albergar en ella 20 caracteres.

INICIALIZACIÓN:
Como cualquier arreglo, una cadena de caracteres se puede ser inicilizada en el
momento de su declaración. Esta operación se realiza de la siguiente manera:
char nomb1[10] = { 72, 111, 108, 97, 0, 43, 9, 123, 10, 45}; ó
char nomb2[10] = {'H', 'o', 'l', 'a', '\0', '+', '\t', '{', '\n', 'A'};
En ambos casos se asigna a los elemntos del arreglo la misma información
(los números en nomb1 equivalen a los códigos ASCCI de los caracteres que
aparecen en nomb2).
Observe que, según lo expuesto anteriormente, sólo los primeros cuatro datos
corresponden a caracteres válidos en las cadenas, ya que el quinto elemento
es un 0 (cero) o un '\0', delimitadores de la cadena.

Si recordamos de los arreglos, si se colocan menos valores de inicialización que la


capacidad del arreglo, el resto de elementos del arreglo se inicializa en cero.
Entonces, si realizamos la siguiente operación:
char nomb3[10] = {'H', 'o', 'l', 'a'};

Esto signfica que: nomb3[0] = 'H', nomb3[1] = 'o', nomb3[2] = 'l',


nomb3[3] = 'a', nomb3[4] = 0 ó '\0', nomb3[5] = 0 ó '\0', etc., lo que
significa que la cadena está perfectamente delimitada.

Otra opción que nos da el compilador para inicializar una cadena de caracteres es
haciendo uso de una secuencia de caracteres encerrados entre comillas ("..."), como
se muestra a continuación:
char nomb4[10] = "Hola";

Esto es equivalente a la inicialización de la variable nomb3. Incluso se le


ha colocado el delimitador en la quinta posición.

LECTURA Y ESCRITURA DE CADENAS DE CARACTERES


El lenguaje C/C++ implementa una serie de funciones que permiten el ingreso y la
salida de cadenas de caracteres a, y desde, un programa. Empezaremos analizando las
funciones scanf y printf.

La función scanf, como lo indicamos en capítulos anteriores, permite el ingreso de


datos desde la consola. Esta misma función, empleando el especificador de formato %s,
permite el ingreso de cadenas de caracteres. Observe el siguiente ejemplo:
char nombre[20];
scanf("%s", nombre);

Primero observe que, en la función scanf, a la variable nombre no se le


antepone el & como a las variables enteras o de punto flotante, esto se debe
a que la variable nombre es un arreglo y por lo tanto un puntero que
contiene la dirección de inicio del arreglo.
La función scanf irá tomando uno a uno los caracteres del buffer de entrada,
y los irá colocando consecutivamente en el arreglo a partir del primer
elemento. Al final colocará el delimitador 0 ó '\0' en el siguiente
elemento, inmediatamente después del último carácter ingresado.
La imagen siguiente muestra cómo se realiza este proceso:

La función scanf también se puede emplear con punteros, sin embargo se debe tener
especial cuidado en el sentido de asegurar antes que el puntero apunte a una
dirección válida. En ese sentido, observe las siguientes instrucciones:
char nombre[20];
char *c1, *c2;
scanf("%s", c1); // Esto es un error lógico, ya que c1 no apunta a
una dirección válida.
c2 = nombre;
scanf("%s", c2); // Esto es correcto.

Un aspecto que se debe tomar en cuenta, cuando se quiere leer una cadena de
caracteres empleando scanf es que, al igual con la lectura de números, la exploración
de un dato se realiza hasta encontrar un "espacio" (entiéndase por "espacio", un
carácter blanco, un carácter de tabulación o un carácter de cambio de línea). Es por
esta razón que empleando el especificador de acceso %s en la función scanf sólo se
podrán leer palabras sueltas y no frases completas.

La imagen siguiente ilustra este enunciado:

CONJUNTO DE EXPLORACIÓN %[]: Se denomina "conjunto de exploración" a una lista de


caracteres que se coloca en la cadena de formato de la función scanf y permite
restringir los caracteres que se pueden ingresar a una cadena de caracteres. Un
"conjunto de exploración" se coloca en reemplazo del %s, los caracteres que se desea
permitir en el ingreso se colocan uno a continuación del otro entre los paréntesis.
Se puede definir también un rango de caracteres, para esto se coloca el carácter
inicial seguido de un guión (-).

A continuación se muestran algunos ejemplos:

También se puede negar un conjunto, de modo que se permita cualquier carácter menos
los contenidos en el conjunto. Esto se logra poniendo el carácter ^ al inicio del
conjunto.
Aquí un ejemplo:
La función printf permite, empleando el especificador de formato %s, la impresión del
contenido de un arreglo de tipo char, como caracteres en la consola. La función irá
tomando cada uno de los elementos del arreglo e irá mostrando en la pantalla cada uno
de los caracteres correspondientes, hasta encontrar el delimitador de la cadena (0 ó
'\0'). Si el delimitador no se encontrara presente en el arreglo, se seguirían
imprimiendo caracteres contenidos en los bytes contiguos hasta encontrar uno.

Otro par de funciones que permiten el ingreso y la salida de cadenas de caracteres


son las funciones gets y puts. La sintaxis de estas funciones es la siguiente:
char * gets(char *);
int puts (char *);

La función gets recibe como parámetro un arreglo de tipo char, en él se almacenará


los caracteres provenientes de la consola. A diferencia de printf la lectura con gets
no se detendrá cuando se encuentre un espacio en blanco sino hasta encontrar un
carácter de cambio de línea. La función devuelve un puntero de tipo char que apunta
al argumento, si se pretende leer al final del archivo la función devuelve NULL.

La función puts es equivalente a scanf con la diferencia que cuando puts termina de
imprimir los caracteres, envía a la pantalla un carácter de cambio de línea. La
función puts devuelve un valor entero positivo si la operación tiene éxito y un valor
negativo (por lo general EOF) si hubo un error de lectura.

Finalmente se pueden emplear los objetos cin y cout. El uso de ambos objetos tiene un
efecto igual al del %s en las funciones scanf y printf.

También existe un método asociado a cin que permite realizar una operación similar a
gets, este método se denomina getline. La manera cómo se utiliza se explica a
continuación:
Por ejemplo:
cin.getline(cad, n);
donde "cad" es una cadena de caracteres y n es la cantidad máxima de
caracteres menos uno, que se podrá leer desde el buffer de entrada. Al final
coloca el carácter de terminación.
ASIGNACIÓN DE VALORES
Asignar un valor a una variable en un programa quiere decir que colocaremos un valor
en la posición de memoria relacionada con la variable. Cuando se hacen operaciones de
asignación se emplean por lo general valores constantes, variables o expresiones.
Empleando tipos de datos numéricos,esto se realiza de la siguiente manera:
int a, b, c;
a = 234; // asignación de un valor constante.
b = a; // asignación de una variable.
c = a + b; // asignación de una expresión.

En el caso de las cadenas de caracteres, no se puede asignar valores como se hacen


con las variables numéricas. La razón de esto es la forma como se definen las cadenas
en C., mediante arreglos. Si definimos dos cadenas como char a[20], b[2]; y queremos
asignar una a la otra escribiendo la instrucción a = b; se producirá un error de
compilación, esto debido a que, como dijimos en el capítulo de arreglos, cuando en un
programa se emplee el identificador del arreglo sin colocar un índice entre
corchetes, se estará haciendo referencia a la dirección de memoria del inicio del
área de datos del arreglo. En el caso de la instrucción anterior se estará tratando
de asignar la dirección de memoria del área asignada a b a la variable a. Esto es un
absurdo, ya que una variable definida como arreglo apunta de manera constante a un
área de datos y por lo tanto no se le puede hacer apuntar a otra área de datos.

Por otro lado, un valor constante dado para una cadena de caracteres se representa
como una secuencia de caracteres encerrados entre comillas, por ejemplo: "Cadena",
"Juan Perez Castro". Cuando se pone un valor constante de este tipo en un programa,
el compilador coloca cada uno de los caracteres, incluso el carácter determinación,
en un espacio de memoria libre, luego el compilador reemplaza el valor constante por
la dirección de inicio del área asignada. Es por esta razón que no se permite tampoco
asignar a una cadena de caracteres un valor constante, por que se intentaría
modificar la dirección a la que apunta este arreglo.
char nombre[50];
nombre = "Paula Valentina"; // esto es un ERROR de compilación.

Esto no se debe confundir con la inicialización de una cadena de caracteres como


vimos al inicio de este capítulo, en estos caso el valor constante es ubicado por el
compilador en el espacio asignado al arreglo.

Por otro lado, tampoco se debe confundir con el manejo de punteros ya que:
char *nombre;
nombre = "Naomi Alexandra"; // esto SI es correcto.

esto se debe a que un puntero puede apuntar a cualquier área de datos, en particular
a la asignada al valor constante.
La pregunta ahora es ¿cómo hacer la asignación?. La respuesta a esto es sencilla
aunque no es tan inmediata como una asignación simple, habrá que elaborar un rutina
que permita asignar carácter a carácter los elementos de un arreglo al otro. Esta
rutina puede ser similar a la que se muestra a continuación:
#include <stdio.h>
void copiar (char [], char []);

int main (void)


{ char nomb1[30], nomb2[30];
gets(nomb1);
copiar (nomb2, nomb1); // se lee: copiar en nomb2 los caracteres de
nomb1
···
}

void copiar (char destino[], char origen[])


{ int i=0;
while (origen[i]!= 0)
{ destino[i] = origen[i]; // copiamos carácter a caracter
i++;
}
destino[i] = 0; // no se debe olvidar de colocar el carácter de
terminación
}

Otra versión de esta misma rutina, que aprovecha más las propiedades del lenguaje C
en cuanto a punteros se trata, puede ser la siguiente:
#include <stdio.h>
void copiar (char *, char *);

int main (void)


{ char nomb1[30], nomb2[30];
gets(nomb1);
copiar (nomb2, nomb1); // se lee: copiar en nomb2 los caracters de
nomb1
···
}

void copiar (char *destino, char *origen)


{ while (*destino++ = *origen++);
}

Esta rutina, ahora más pequeña que la anterior, lo que hace es lo siguiente: Los
punteros destino y origen apuntan inicialmente al primer elemento del arreglo
respectivo. Como la condición del while tiene un = (asignación) y no un ==
(comparación), la orden *destino = *origen coloca el primer carácter de la cadena
origen en el primer carácter de la cadena destino. Luego se aplica el operador ++,
que está como sufijo, a destino y a origen (no se aplica a *destino ni a *origen por
la forma como se agrupa el operador), por lo que cada puntero termina apuntando al
siguiente carácter de la cadena. Finalmente el resultado de la asignación es el valor
que se emplea para verificar el final de while, si es un carácter cualquiera el que
se asignó, el ciclo continua, pero si se asignó el carácter de terminación, que es un
valor cero, el ciclo se detiene. Esto último quiere decir que no se necesita dar una
orden adicional para asignar el carácter de terminación a la cadena destino. Se debe
tener en cuenta que destino y origen son dos parámetros por valor, por lo que no
importa que se alteren los lugares a donde apuntan, esto no afecta a los punteros o
arreglos de la función que llamó a la rutina copiar.

COMPARACIÓN DE CADENAS
Para comparar dos cadenas de caracteres se debe tener las mismas consideraciones que
para la asignación de valores, esto es si nosotros pretendemos compara dos cadena de
la siguiente manera:
int cad1[30], cad2[30];
gets(cad1);
gets(cad2);
if (cad1 == cad2) printf("Iguales\n");
else printf("Diferentes");

El compilador no detectará errores, sin embargo al ejecutarlo se imprimirá siempre el


mensaje Diferentes, sin importar qué valores asignemos a las cadenas. Esto se debe a
que lo que se está comparando no son los contenidos de las cadenas, sino las
direcciones donde apuntan; al ser arreglos en este caso apuntarán a direcciones
diferentes.

Para comparar entonces dos cadenas de caracteres, debemos elaborar una rutina que sea
capaz de compara carácter a carácter dos cadenas y así poder determinar, si son
iguales, si una es mayor que otra o viceversa. La función que se muestra a
continuación realiza esta tarea, para lo cual, devuelve un valor menor que cero si la
primera cadena es menor que la segunda, devuelve cero si ambas cadenas son iguales, o
un valor mayor que cero si la primera cadena es mayor que la segunda.
#include <stdio.h>
int comparar (char [], char []);

int main (void)


{ char nomb1[30], nomb2[30];
int resultado;

gets(nomb1); gets(nomb2);
resultado = comparar (nomb1, nomb21);
if (resultado == 0) printf("Las cadenas son iguales\n");
else
if (resultado < 0) printf("La primera cadena es menor que la
segunda\n");
else printf("La primera cadena es mayor que la segunda\n");
···
}

int comparar (char c1[], char c2[])


{ int i;
for (i=0; c1[i] == c2[i]; i++)
if (c1[i]==0) return 0; // si son iguales y su valor es cero
entonces
// las cadenas son iguales
return c1[i]-c2[i]; // si son diferentes, termina el for y se devuelve
// la diferencia de los caracteres
desiguales
}

Otra versión de esta misma rutina empleando punteros puede ser la siguiente:
#include <stdio.h>
int comparar (char *, char *);

int main (void)


{ char nomb1[30], nomb2[30];
int resultado;
···
}

int comparar (char *c1, char *c2)


{ for ( ; *c1 == *c2; c1++, c2++) if (!*c1) return 0;
return *c1 - *c2;
}

En esta rutina los punteros c1 y c2 apuntan inicialmente al primer elemento del


arreglo respectivo. Si los valores referenciados por c1 y c2 son iguales, se verifica
si este valor es cero (0 ó '\0'), si es así se da por terminada la función y se
retorna cero. Luego se desplaza los punteros c1 y c2 de modo que apunten al siguiente
carácter respectivamente y el ciclo continua. En el momento que se detecte que los
valores referenciados son diferentes, se corta el for y se devuelve la diferencia de
los valores referenciados.
BIBLIOTECA DE FUNCIONES string.h
Todos los compiladores de C implementan una biblioteca de funciones que permite, de
una manera sencilla, la manipulación de cadenas de caracteres. Estas funciones
trabajan con las cadenas de la misma manera que lo hemos hecho en este capítulo, es
decir manipulando carácter por carácter cada uno de los elementos del arreglo. A
continuación se muestran algunas de las funciones más comunes:

Función Prototipo Significado

Devuelve el número de caracteres


strlen int strlen(const char *cad); de la cadena "cad". No cuenta el
carácter de terminación.

Copia todos los caracteres de la


cadena origen en la cadena
char *strcpy(char *destino,
strcpy destino, incluso el carácter de
const char *origen);
terminación.
Devuelve un puntero a destino.

Compara uno a uno los caracteres


de ambas cadenas hasta
completarlos todos o hasta
encontrar una diferencia.
int strcmp(const char *cad1, Devuelve cero (0) si ambas
strcmp
const char *cad2); cadenas son iguales, un valor
negativo si la primera cadena es
menor que las segunda y un valor
positivo si la primera es mayor
que la segunda.

Agrega una copia de la cadena


origen al final de la cadena
char *strcat(char *destino,
strcat destino.
const char *origen);
Devuelve la dirección a la que
apunta la variable destino.

Busca la primera ocurrencia de


la cadena "cad2" en la cadena
"cad1".
char *strstr(const char *cad1, Si la encuentra devuelve un
strstr
const char *cad2); puntero que apunta al primer
carácter de la ocurrencia en
"cad1", si no lo encuentra
devuelve NULL.

strchr char *strchr(char *cad, char c); Busca la primera ocurrencia del
carácter contenido en la
variable "c".
Si lo encuentra devuelve un
puntero que apunta al carácter
encontrado en "cad", si no lo
encuentra devuelve NULL.

Busca la última ocurrencia del


carácter contenido en la
variable "c".
char *strrchr(char *cad, char
strrchr Si lo encuentra devuelve un
c);
puntero que apunta al carácter
encontrado en "cad", si no lo
encuentra devuelve NULL.

Busca la primera ocurrencia de


cualquier carácter de la cadena
"cad2" en la cadena "cad1".
char *strpbrk(const char *cad1, Si la encuentra devuelve un
strpbrk
const char *cad2); puntero que apunta al carácter
encontrado en la cadena "cad1",
si no lo encuentra devuelve
NULL.

Convierte las letras contenidas


en la cadena "cad" en
strupr char *strupr(char *cad); mayúsculas.
Devuelva una puntero a la cadena
"cad".

Convierte las letras contenidas


en la cadena "cad" en
strlwr char *strlwr(char *cad); minúsculas.
Devuelva una puntero a la cadena
"cad".

Invierte los caracteres


contenidos en la cadena "cad".
strrev char *strrev(char *cad);
Devuelva una puntero a la cadena
"cad".

Ejemplo:
El siguiente ejemplo muestra cómo se manejan algunas de estas funciones:

/* Este programa pretende realizar las operaciones de "buscar y reeeplazar"


que tienen los procesadores de palabras. El programa lee de la entrada
estándar una cadena a buscar y una cadena que va a reemplazar, luego lee
un texto, una línea por vez, si la cadena buscada se encuentra en la
línea, se reemplaza por segunda cadena tantas veces como se encuentre.
Suponer que las líneas nunca superarán los 100 caracteres.
*/

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

void reemplazar(char *, char *, char *);

void main (void)


{ char cadBusc[20], cadReem[20];
char linea[100];

printf("Ingrese la cadena buscada : "); gets(cadBusc);


printf("Ingrese la cadena de reemplazo: "); gets(cadReem);

// Buscamos y reemplazamos en el texto


while (gets(linea)) // sale cuando encuentra el final del archivo
{ reemplazar(linea, cadBusc, cadReem);
puts(linea);
}
}

void reemplazar(char *linea, char *cadBus, char *cadReem)


{ char *ptLinea=linea, *pos, aux[100];
// el puntero ptLinea servirá para buscar varias ocurrencias
// en la cadena. Indica el punto de partida de la búsqueda
while (1)
{ pos = strstr(ptLinea,cadBus);
if (pos==NULL) return;
*pos=0; //pongo un carácter de terminación al inicio de la cadena
encontrada
strcpy(aux,linea); // copio sólo la parte izquierda de la cadena
strcat(aux,cadReem); // agrega a "aux" la cadena de reemplazo
strcat(aux,pos+strlen(cadBus)); // copio la parte derecha de la
cadena
strcpy(linea,aux); // copio en "linea" la cadena modificada
ptLinea= pos+strlen(cadReem); // desplazo el puntero para permitir
ubicar una
// nueva ocurrencia
}
}

También podría gustarte