Está en la página 1de 46

¿Qué es un Arreglo?

En el ámbito informático se le conoce como Arreglo o Array a una


serie de conjuntos organizados como bien estructurados de
datos, los cuales son organizados de manera homogénea sin que
ningún dato tenga un tipo de diferencia u anomalía en su formato
como en sus cualidades.

Así mismo se organizan de forma consecutiva de manera que se


genere un orden preestablecido en su ejecución y su
almacenamiento es totalmente realizado en la Memoria RAM de
nuestros computadores, ya que sus operaciones cuentan como
actividades de almacenamiento temporal.

De la misma manera la manipulación de los datos en un Array es


totalmente flexible y pueden ser combinados como anidados los
datos que en ellos se estén usando, para así los mismos puedan
alcanzar una estructura estable y que los datos en su interior
puedan ser manipulados con eficacia como una buena velocidad de
procesamiento, el procesamiento de los datos dentro de los
Arreglos es de forma cíclica, y dicho ciclo debe cumplirse en su
totalidad para denotar que todos los datos fueron manipulados y
usados eficazmente como sin problema alguno.

Los mismo poseen cualidades similares en las listas como son el


uso de ciclos para el procesamiento de datos, como así mismo el
uso de lineamientos de orden como de posición para procesar los
datos, y tanto el orden como la posición son establecidas
previamente por los programadores en las líneas de programación
de forma detallada, además de los mismos les otorgan un orden y
posición que los programadores establezcan.
Sin embargo corren con una serie de restricciones para llevar
acabo sus operaciones y si las mismas son infringidas las
secciones e inclusive el Array completo podría dejar de funcionar
parando el programa de raíz y mostrando un mensaje de error de
sintaxis al respecto de dichas problemáticas, ya que el tipo de
dato dentro del Array debe ser del mismo formato y tipo, como
así mismo su contenido debe ser del tipo numérico y sin poseer
cambios constantes o decimales en su interior.

De la misma manera los Arreglos son comparados con las matrices


y vectores presentes en una de las cátedras más antiguas la cual
es la matemática, por dicha similitud es que está establecida su
forma y estructura, como así mismo su resolución con el uso de
algoritmo depende muchas veces de la realización de operaciones
matemáticas.

Así mismo los Arreglos poseen varios tipos de dimensiones


conocidas, siendo unidimensionales, bidemencionales e incluso
poseer en su estructura y forma igual o superior a tres
dimensiones para cumplir sus funciones programadas y
establecidas para resolver un problema en concreto, los mismo
además son tres los conocidos siendo conocidos bajos los
seudonimos de “Vectores”, “Matrices” y “Tablas
Multidimensionales”.

Tipos
Los Arreglos muchas veces se les determina su tipo y forma
primeramente estableciendo cuantas dimensiones posee como
cuantas serán utilizadas bajo el uso del Arreglo en cualquier
lenguaje de programación, para solamente ser establecidas sus
modalidades de funcionamiento como sus cualidades internas de
forma clara y totalmente objetivas sin entorpecer una sección
especial del programa que se esté realizando.

Los Arreglos que poseen una sola dimensión se les conoce y se les
denomina como “Vectores”, a los que les corresponde dos
dimensiones se les menciona como “Matrices” y por ultimo a los
arreglos cuyas dimensiones sean igual o superior a las 3
dimensiones se les conoce como “Tablas Multidimensionales”, Por
todo lo antes mencionado los tipos de Arreglos en
programación son los siguientes a exponer y explicarle a usted de
forma exhaustiva a continuación:

Arreglos Unidimensionales
Un Arreglo Unidimensional es una estructura de datos organizada
y bien coordinada, que cuenta con una cantidad pequeña de datos,
los cuales deben ser del mismo tipo para ser procesados en dicho
Arreglo, en programación se usa mayormente en la creación de la
estructura de listas en orden natural y totalmente con
elementos similares en su interior.

Los datos a manipular en su interior no solo deben poseer un tipo


de dato similar, sino que también deben poseer un seudónimo
similar entre ellos, pero los mismos se han de diferenciar con la
posición que se les otorgue dentro del Arreglo bajo el uso de sus
funciones y ordenanzas básicas estipuladas en la línea de
programación con su codificación especial.

Además un Arreglo de este tipo para ejecutar sus funciones


debe primero que todo iniciar sus variables o datos en el inicio
del programa que se esté llevando a cabo, como de la misma
manera en la misma sección donde se está realizando dicha
acción, se debe establecer tanto el nombre como el tipo de dato
que ha de ejecutar dicho Arreglo en su interior.

Arreglos Multidimensionales
Los Arreglos cuya estructura sea de dos o más dimensiones se les
conoce como “Arreglos Multidimensionales”, en ellos el termino
dimensiones se establece a los diferentes números de índices que
los mismo deben llevar en su estructura para poder llevar a cabo
sus funciones, el número de índices a utilizar deben ser
preestablecidos al igual que los datos en la misma forma que los
Arreglos unidimensionales con la diferencia que el presente
contara con una estructura más robusta y con más funciones.

Arreglos de Múltiples Índices


Estos son más y nada menos que una serie de tablas de valores,
las cuales cuentan con una serie de filas y columnas especiales,
además las mismas sirven para manipular y poder identificar la
ubicación de un valor en específico en su interior, como así mismo
para identificar a dicho valor es necesario establecer en que
parte de los índices establecidos en el arreglos esta y en qué
forma se presenta.

Los lineamientos de programación que cumplen estos Arreglos


primeramente proceden a primeramente con el uso del primer
índice identificar en que fila se encuentra ubicado el dato que
deseemos utilizar dentro del Arreglo, como de la misma manera y
de forma totalmente simultanea el segundo índice dentro de la
estructura del Arreglo identifica la columna en la cual se ubica el
otro valor a utilizar en las operaciones con el Arreglo.
Es importante mencionar que los Arreglos de Múltiples Índices
en programación son basados bajo un modelo estándar especial
llamado “ANSI” y es utilizado a nivel internacional, el mismo
estipula que un Arreglo de esta naturaleza puede utilizar más de
dos subíndices al mismo tiempo pero su uso se ve limitado a doce
subíndices en uso simultaneo para evitar un volcamiento de datos
en el uso de dichos arreglos.

Clasificación
La clasificación de los Arreglos son tres los conocidos y
establecidos en los lenguajes de programación, contando cada uno
con sus cualidades y especificaciones que les hacen únicos en
muchos sentidos siendo una de las mejores como más sofisticadas
secciones de un programa, los mismos son conocidos por ser
usados en programas de sorteos o de lotería los que le da en la
sociedad un uso fuerte que perdura con el tiempo, por todo lo
antes mencionado se clasifican los Arreglos en programación de
la siguiente manera:

Vectores
Los Vectores o también denominados bajo el seudónimo “Tablas
Unidimensionales”, son arreglos que solo poseen una sola
dimensión y no necesitan del uso de múltiples índices para
realizar sus funciones, estableciendo así sus ciclos en
operaciones cortas y poco elaboradas en un periodo de tiempo
módico como sin complicación alguna en su ejecución.

De la misma manera los datos en su interior deben ser


catalogados bajo el mismo tipo de dato, el cual mayormente es
colocado en tipo numérico, así mismo el nombre de referencia o
nombre que los datos ocuparan mientras se ejecuten en el
interior de este Arreglo debe ser el mismo y se diferencian uno
del otro con el número de posición que se lo otorga a cada dato
con su respectivo valor.

Además estos Arreglos cumplen con una cualidad un tanto


peculiar, la cual consta de que sus datos son ordenados de mayor
a menor y de la misma manera su ciclo se efectúa, siendo el valor
más bajo o con cualidades menores comienza el ciclo de procesos
del Vector y valor dentro del vector con cualidades más altas es
el que se ejecutara de ultimo cumpliendo con la culminación del
ciclo de forma efectiva.

Matrices
Las Matrices son conocidas también bajo el seudónimo definido
como “Tablas Bidimensionales” y dicho seudónimo lo adquiere
gracias a poseer solamente dos dimensiones que componen su
estructura de composición, además comparte cierta cantidad de
similitudes con los vectores.

Sin embargo se diferencian de estos últimos por poseer dos


subíndices para la generación de sus funciones, como así mismo el
ciclo de función y de realización de las operaciones a llevar a
cabo bajo el uso de una Matriz es superior a la de un vector dado
que manipulan una cantidad de datos por encima de los
mencionados anteriormente.

Los datos de una Matriz deben ser catalogados e inicializados de


manera efectiva, ya que al utilizar dos subíndices los datos
dentro de dicho Arreglo se ven ubicados en cuadrantes del mismo
y su tipo de dato siempre debe ser el mismo pero su ubicación
para ser identificados se determina bajo el uso de coordenadas
de posición y que en el lineamiento de programación son utilizados
para ir realizando las operaciones de forma efectiva en una
Matriz.

Tablas Multidimensionales
Al igual que cualquier Arreglo presentan una serie de
características similares, pero con la gran diferencia de que
estos poseen 3 o más dimensiones en su composición, así mismo el
número de pares de subíndices deben ser superiores para
abarcar cada una de las dimensiones que posea dicha tabla,
además el tamaño y la proporción que debe cumplir la Tabla
Multidimensional deben ser declaradas de forma obligatoria como
bien estipulada para evitar problemas referentes a errores de
sintaxis.

Operaciones con arreglos


Las operaciones en arreglos pueden clasificarse de la siguiente forma:

• Lectura: este proceso consiste en leer un dato de un arreglo y asignar un valor a


cada uno de sus componentes
• Escritura: Consiste en asignarle un valor a cada elemento del arreglo.
• Asignación: No es posible asignar directamente un valor a todo el arreglo
• Actualización: Dentro de esta operación se encuentran las operaciones de
eliminar, insertar y modificar datos. Para realizar este tipo de operaciones se debe
tomar en cuenta si el arreglo está o no ordenado.
• Ordenación.
• Búsqueda.
• Insertar.
• Borrar.
• Modificar.

Métodos de ordenamiento.
La ordenación o clasificación es el proceso de organizar datos en algún
orden o secuencia específica, tal como creciente o decreciente, para
datos numéricos, o alfabéticos, para datos de caracteres. Los métodos
de ordenación más directos son los que se realizan en el espacio
ocupado por el array. Los más populares son:

Método de Intercambio o de Burbuja:

Se basa en el principio de comparar pares de elementos adyacentes e


intercambiarlos entre si hasta que estén todos ordenados. Supongamos
que se desea clasificar en orden ascendente el vector o lista:
9, 8, 0, 2, 5, 1, 3, 2, 9

A[0] A[1] A[2] A[3] A[4] A[5] A[6] A[7] A[8]

Los pasos a dar son:

- CompararA[1] yA[2] si están en orden, se mantienen como están, en


caso contrario se intercambian entre si.

- A continuación se comparan los elementos 2 y 3; de nuevo se


intercambian si es necesario.

- El proceso continua hasta que cada elemento del vector ha sido


comparado con sus elementos adyacentes y se han realizado los
intercambios necesarios.

Este video muestra de manera simple el ordenamiento de burbuja:

Ejemplo Práctico
/*Ordenamiento Burbuja */

#include <stdio.h>
#include <conio.h>
#define TAM 9

int main()
{
int a[TAM] = { 9, 8, 0, 2, 5, 1, 3, 2, 9};
int i, pasada, aux;

printf("Datos en el orden inicial:\n\n");


for(i=0;i<=TAM-1;i++)
printf("%4d",a[i]);
for (pasada=1;pasada<=TAM-1;pasada++) /*pasadas*/
for (i=0;i<=TAM-2;i++)
if (a[i]>a[i+1]) /*comparación */
{
/*intercambio*/
aux=a[i];
a[i] = a[i+1];
a[i+1] = aux;
}
printf( "\n\nDatos ordenados en sentido ascendente:\n\n" );
for (i=0;i<=TAM-1;i++ )
printf("%4d", a[i]);
printf("\n");
getch();
return 0;
}

Ordenamiento por inserción (Insertion Sort).

Consiste en insertar un elemento en el vector en una parte ya ordenada


de este vector y comenzar de nuevo con los elementos restantes. Por
ser utilizado generalmente por los jugadores de cartas se le conoce
también por el método de la baraja. Por ejemplo, supóngase que se
tiene la lista desordenada;
5 14 24 39 43 65 84 45

Para insertar el elemento 45, habrá que insertar entre 43 y 65, lo que
supone desplazar a la derecha todos aquellos números de valor superior
a 45, es decir, saltar sobre 65 y 84.
5 14 24 39 43 65 84 45

El método se basa en comparaciones y desplazamientos sucesivos. El


algoritmo de clasificaciones de un vector X para N elementos se realiza
con un recorrido de todo el vector y la inserción del elemento
correspondiente en el lugar adecuado. El recorrido se realiza desde el
segundo elemento al n-ésimo.

Veamos el siguiente ejemplo.

Ejemplo Práctico.
#include <stdio.h>
int arreglo[10] = {3,10,1,8,15,5,12,6,5,4}; /*Declaracion e inicialización
del arreglo. */

/*imprimearreglo - Funcion que muestra por pantalla


el contenido de un arreglo.*/
void imprimearreglo() {
int i; for (i=0;i<10;i++)
printf("Elemento %d: %d \n",i,arreglo[i]);
}

void main() /*Funcion Principal del Programa*/


{
int i,j,k;
imprimearreglo();
for (i=1; i<10; i++) {
j=i;
while (j>=0 && arreglo[j]<arreglo[j-1]) {
k=arreglo[j];
arreglo[j]=arreglo[j-1];
arreglo[j-1]=k;
j--;
}
}
printf("\n\nArreglo ordenado \n\n");
imprimearreglo();
}

Ordenamiento Rápido (Quicksort).

El ordenamiento rápido (quicksort en inglés) es un algoritmo basado en


la técnica de divide y vencerás, que permite, en promedio, ordenar n
elementos en un tiempo proporcional a n log n. Esta es la técnica de
ordenamiento más rápida conocida. El algoritmo fundamental es el
siguiente:

• Elegir un elemento de la lista de elementos a ordenar, al que


llamaremos pivote.
• Resituar los demás elementos de la lista a cada lado del pivote,
de manera que a un lado queden todos los menores que él, y al
otro los mayores. En este momento, el pivote ocupa exactamente
el lugar que le corresponderá en la lista ordenada.
• La lista queda separada en dos sublistas, una formada por los
elementos a la izquierda del pivote, y otra por los elementos a su
derecha.
• Repetir este proceso de forma recursiva para cada sublista
mientras éstas contengan más de un elemento. Una vez terminado
este proceso todos los elementos estarán ordenados. Como se
puede suponer, la eficiencia del algoritmo depende de la posición
en la que termine el pivote elegido.
Veamos el siguiente ejemplo.

Pseudocódigo QuickSort:
Nombre Función: OrdRap
Parámetros:
lista a ordenar (lista)
índice inferior (inf)
índice superior (sup)

// Inicialización de variables
1. elem_div = lista[sup];
2. i = inf - 1;
3. j = sup;
4. cont = 1;

// Verificamos que no se crucen los límites


5. if (inf >= sup)
6. retornar;

// Clasificamos la sublista
7. while (cont)
8. while (lista[++i] < elem_div);
9. while (lista[--j] > elem_div);
10. if (i < j)
11. temp = lista[i];
12. lista[i] = lista[j];
13. lista[j] = temp;
14. else
15. cont = 0;

// Copiamos el elemento de división


// en su posición final
16. temp = lista[i];
17. lista[i] = lista[sup];
18. lista[sup] = temp;

// Aplicamos la función
19. OrdRap (lista, inf, i - 1);
20. OrdRap (lista, i + 1, sup);

Ejemplo de Implementación de Quicksort en C


void SortArray (int array[],int first,int last)
{
int i,j,p,t;

// i se hace igual al índice del primer elemento


i= first;
// y j igual al índice del último elemento
j= last;
// p se hace igual al elemento pivote del arreglo
p= array[(first+last)/2];

do {
// se hace la partición del arreglo
while (array[i]<p) i++;
while (p<array[j]) j--;
if (i<=j) {

// se intercambian los elementos i-esimo y j-esimo del


arreglo
t= array[i];
array[i]= array[j];
array[j]= t;
i++; j--;
}
} while (i<=j);
if (first<j) SortArray(array,first,j);
if (i<last) SortArray(array,i,last);
}

Métodos de búsqueda.
La búsqueda es una operación que tiene por objeto la localización de un
elemento dentro de la estructura de datos (arreglo). A menudo un
programador estará trabajando con grandes cantidades de datos
almacenados en arreglos y pudiera resultar necesario determinar si un
arreglo contiene un valor que coincide con algún valor clave o buscado.

búsqueda secuencial

Este algoritmo compara uno a uno los elementos del arreglo hasta
recorrerlo por completo indicando si el número buscado existe.

Su implementación es la siguiente:
#include <stdio.h>
#include <conio.h>
#include <stdlib.h>
#define TAM 10

void main() {
int a[TAM], temp, i, j, num;

randomize(); //Inicializa el generador de numeros aleatorios


printf ("Llenando arreglo con números aleatorios\n");
for (i=0; i< TAM; i++)
a[i]=random(100);
printf ("Numero a buscar? ");
scanf ("%d", &num);
for (i=0; i< TAM; i++)
if (a[i] == num){
printf ("\nValor encontrado");
printf ("\nPosicion: %d", i);
}
else
printf ("\nNo existe");
printf ("El arreglo era:\n");
for (i=0; i< TAM; i++)
printf ("%d ", a[i]);
getch();
}

Búsqueda binaria

Este algoritmo permite buscar de una manera más eficiente un dato


dentro de un arreglo, para hacer esto se determina el elemento central
del arreglo y se compara con el valor que se esta buscando, si coincide
termina la búsqueda y en caso de no ser así se determina si el dato es
mayor o menor que el elemento central, de esta forma se elimina una
mitad del arreglo junto con el elemento central para repetir el proceso
hasta encontrarlo o tener solo un elemento en el arreglo.

Para poder aplicar este algoritmo se requiere que el arreglo este


ordenado. Su implementación es la siguiente:
#include <stdio.h>
#include <conio.h>
#include <stdlib.h>
#define TAM 15

void main(){
int a[TAM], busca, temp, bajo, alto, central;

printf("Llenando el arreglo con números aleatorios\n");


randomize(); //Inicializa el generador de aleatorios
for (int i=0; i< TAM; i++)
a[i]=random(100);
//Implementacion de Ordenamiento por burbuja de menor a mayor
printf ("Ordenando arreglo...\n");
for (int j=1; j <= TAM; j++)
for (i=0; i< TAM-1; i++)
if (a[i] > a[i+1]){
temp = a[i];
a[i] = a[i+1];
a[i+1] = temp;
}

//Implementacion de busqueda binaria


printf ("\nIntroduce un numero a buscar: ");
scanf ("%d", &busca);

bajo = 0;
alto = TAM-1;
central = (bajo+alto)/2;
while (bajo < alto && busca != a[central]){
if(busca > a[central])
bajo = central+1;
else
alto = central-1;
central=(bajo+alto)/2;
}

if (busca == a[central])
printf("\n%d encontrado en posicion %d", busca, central);
else
printf("\n%d no existe", busca);
printf ("\n\nEl arreglo ordenado era\n\n");
for (i=0; i< TAM; i++)
printf ("%d ", a[i]);
getch();
}

Estructuras de Regristros.
Definición

Una estructura no es más que un conjunto de variables de distinto tipo


agrupadas con un mismo nombre para que su manejo sea simple.
En la imagen podemos ver que la estructura de datos contine 4 tipos de
datos diferentes.
char

int

float

tipo_nodo

El tipo de dato llamado tipo_nodo nos indica que las estructuras de datos
pueden contener tantos datos básicos como datos creados por nosotros
mismos.

Declaración de estructuras.

Las estructuras se pueden declarar de la siguente forma:


struct nombre_estructura {
campo/miembro estructura;
};

Donde:

--- structes una palabra reservada de C que indica la composición de


una estructura.

--- nombre_estructura asigna el nombre a dicha estructura.

son tipos de datos que contiene, se les


--- campo/miembro estructura;
puede llamar campo ó miembro.

Si desearamos hacer una agenda telefónica, la forma para declararla


podría ser:
struct agenda_entrada {
char nombre[50];
char apellido[60];

char telefono[10];
char edad;
};
Otra forma sería:
struct agenda_entrada {
char nombre[50];
char apellido[60];
char telefono[10];
char edad;
}familiar, laboral;

e incluso podríamos declararla como:


struct {
char nombre[50];
char apellido[60];
char telefono[10];
char edad;
}familiar, laboral;

En el primer ejemplo estamos declarando la estructura, luego, cuando


la necesitemos, le asingaremos las variables. Para el segundo y tercer
ejemplo hemos declarado las variables junto a la estructura, esto nos
trae el inconveniente de no poder declarar más variables a lo largo del
programa pues las estructuras se tienen que declarar antes de la
función main.

Tomando el primer ejemplo, agenda_entrada es un nuevo tipo de dato que


hemos creado. Para poner a trabajar nuestra creación solo tenemos que
asignarle una variable:
struct agenda_entrada agenda;

como vemos, nuestra variable "agenda" es de tipo agenda_entrada. Si


por ejemplo queremos ir al contenido del campo "nombre" solo tenemos
que escribir:
agenda.nombre;

Estructura y arreglos.

Aplicando un poco de lógica, nos daremos cuenta que nuestra agenda


solo almacenaría una entrada, cosa poco práctica. Para solucionar esto
solo tenemos que declarar un array ó arreglo de estructura:
struct estructura_agenda agenda[30]
como vemos, hemos declarado que "agenda" sea un vector de 30
elementos. La manera de acceder a cada elemento sería:
amigo[número_de_elemento].campo_estructura

Donde:

--- amigo[número_de_elemento] hace referencia a la posicion del elemento


dentro del vector. amigo[0] hace referencia al primer elemento.

--- .campo_estructura apunta hacia un miembro del elemento


referenciado. amigo[0].edad nos mostraría la edad contenida en el primer
elemento.

Cadenas de Caracteres.
Cadenas de Caracteres (Definición)

Las cadenas de caracteres son vectores de tipo carácter (char) que


reciben un tratamiento especial para simular el tipo de datos “string”,
presente en otros lenguajes de programación. Para que un vector de
caracteres pueda ser considerado como una cadena de caracteres, el
´ultimo de los elementos útiles del vector debe ser el carácter nulo
(código ASCII 0). Según esto, si se quiere declarar una cadena formada
por N caracteres, deberá declararse un vector con N + 1 elementos de
tipo carácter. Por ejemplo, la declaración char cadena[6]; reserva
suficiente espacio en memoria para almacenar una cadena de 5
caracteres, como la palabra "casco":

En C pueden definirse constantes correspondientes a cadenas de


caracteres. Se usan comillas dobles para delimitar el principio y el final
de la cadena, a diferencia de las comillas simples empleadas con las
constantes de tipo carácter. Por ejemplo, la cadena constante "H" tiene
muy poco que ver con el carácter constante ’H’, si observamos la
representación interna de ambos:
Asignación.

Mientras que la consulta de elementos de una cadena de caracteres se


realiza de la misma forma que con los vectores, las asignaciones tienen
ciertas peculiaridades. Como en toda tabla, puede asignarse cada
carácter de la cadena individualmente. No debería olvidarse en ningún
caso que el ´ultimo carácter valido de la misma debe ser el carácter
nulo (’\0’). El siguiente ejemplo inicializa la cadena de caracteres
cadena con la palabra "casco". Nótese que las tres ´ultimas posiciones
del vector no se han usado. Es más, aunque se les hubiese asignado
algún carácter, su contenido sería ignorado. Esto es, el contenido del
vector en las posiciones posteriores al carácter nulo es ignorado.
char cadena[10];
. . .
cadena[0] = ’c’;
cadena[1] = ’a’;
cadena[2] = ’s’;
cadena[3] = ’c’;
cadena[4] = ’o’;
cadena[5] = ’\0’;

La inicialización de una cadena de caracteres durante la declaración


puede hacerse del mismo modo que en los vectores, aunque no debe
olvidarse incluir el carácter nulo al final de la cadena. Sin embargo,
existe un método de inicialización propio de las cadenas de caracteres,
cuyo formato general es:
char nombre [tamaño] = "cadena";

Usando este tipo de inicialización, el carácter nulo es añadido


automáticamente al final de la cadena. Así pues, una inicialización
típica de vectores como la siguiente:
char nombre[10] = { ’J’, ’U’, ’A’, ’N’, ’A’, ’\0’};

Puede hacerse también de forma equivalente como:


char nombre[10] = "JUANA";

Finalmente, la inicialización anterior puede hacerse sin necesidad de


especificar el tamaño del vector correspondiente. En este caso, el
compilador se encarga de calcularlo automáticamente, reservando
espacio de memoria suficiente para almacenar la cadena, incluyendo el
carácter nulo al final. Así pues, la siguiente declaración reserva
memoria para almacenar 6 caracteres y los inicializa adecuadamente
con las letras de la palabra JUANA:
char nombre[] = "JUANA";

La cadena vacía.

Otra curiosidad de las cadenas de caracteres se refiere a la cadena


vacía, "", que consta únicamente del carácter nulo. Puesto que los
caracteres posteriores al carácter nulo son ignorados, convertir una
cadena con cualquier valor almacenado a la cadena vacía es tan simple
como asignar el carácter nulo a la posición 0 de dicha cadena. He aquí
un ejemplo:
char cadena [12] = "Una frase";
. . .
cadena[0] = ’\0’; /* Ahora es una cadena vacía */

Cadenas de Caracteres.
Funciones Asociadas al Manejo de cadenas de caracteres

Aunque C no incorpora en su definición operadores para el manejo de


cadenas de caracteres, todo compilador de C proporciona una librera
estándar (string.h) con funciones para facilitar su utilización. Destacar
algunas de ellas:

strcpy: La función strcpy se encuentra en la biblioteca <string.h> y se


utiliza para copiar una cadena de caracteres (fuente) en el lugar que
ocupaba otra (destino). Esta copia es destructiva, o sea, que todos los
caracteres que estaban en la cadena destino desaparecen, aunque la
cadena destino fuera más larga que la cadena fuente .La cadena destino
se pone como primer argumento de la función y la cadena fuente como
segundo. Vamos a verlo con un ejemplo.
#include<stdio.h>
#include<string.h>

int main()
{
char texto1[]="corta";
char texto2[]="mediana";
char texto3[]="larguisima";

strcpy(texto2,texto1);
printf("%s\n",texto2);
strcpy(texto2,texto3);
printf("%s\n",texto2);
getch();
return 0;
}

Resultado:

strcat: En el programa anterior vimos que la función strcpy es


desctructiva, pero hay otra función en la librería <string.h> que copia
una cadena (fuente) en otra (destino) sin destruir ésta, es decir, que
copia una cadena detrás de la otra esta función es conocida
como strcat. Vamos a hacer un ejemplo:
#include<stdio.h>
#include<string.h>
int main()
{
char texto1[]="Don Pepito";
char texto2[]=" y ";
char texto3[]="Don Jose";printf("%s\n",texto1);
strcat(texto1,texto2);
printf("%s\n",texto2);
strcat(texto1,texto3);
printf("%s\n",texto2);
getchar();
return 0;
}

Resultado:

strlen: esta función devuelve el total (entero) de caracteres que


conforman una cadena (excluyendo el caracter nulo \0). Vamos a hacer
un ejemplo:
#include <stdio.h>
#include <string.h>
#include <conio.h>
#define MAXLON 80

int main(void)
{
char a[MAXLON+1];
int longitud;

clrscr();
printf ("Introduce una cadena (max. %d caracteres): ", MAXLON);
scanf("%s",&a);
longitud = strlen(a);
printf ("\nLongitud de la cadena: %d\n", longitud);
getch();
return 0;
}
Resultado:

strcmp: strcmp (abreviatura de ((string comparison))). La función strcmp


recibe dos cadenas, a y b, devuelve un entero. El entero que resulta de
efectuar la llamada strcmp(a, b) codifica el resultado de la
comparación:

es menor que cero si la cadena a es menor que b,

es 0 si la cadena a es igual que b, y

es mayor que cero si la cadena a es mayor que b.

Naturalmente, menor significa que va delante en orden alfabético, y


mayor que va detrás.
#include <stdio.h>
#include <string.h>
int main()
{
char s1[6] = "Abeja";
char s2[6] = "abeja";
int i;

printf( "s1=%s\t", s1 );
printf( "s2=%s\n", s2 );

i = strcmp( s1, s2 );
printf( "s1 es " );
if( i < 0 ) printf( "menor que" );
else if( i > 0 ) printf( "mayor que" );
else printf( "igual a" );
printf( " s2\n" );

return 0;
}

Resultado:

Otras Funciones útiles para operar cadenas de caracteres.

No sólo string.h contiene funciones útiles para el tratamiento de


cadenas. En ctype.h se encuentran unas funciones que permiten hacer
cómodamente preguntas acerca de los caracteres, como si son
mayúsculas, minúsculas, dígitos, etc:

isalnum(caracter): devuelve cierto (un entero cualquiera distinto de


cero) si caracter es una letra o dígito, y falso (el valor entero 0) en caso
contrario.

isalpha(caracter): devuelve cierto si caracter es una letra, y falso en


caso contrario.

isblank(caracter): devuelve cierto si caracter es un espacio en blanco


o un tabulador.

isdigit(caracter) devuelve cierto si caracter es un digito, y falso en


caso contrario.
isspace(caracter): devuelve cierto si caracter es un espacio en blanco,
un salto de línea, un retorno de carro, un tabulador, etc., y falso en
caso contrario.

islower(caracter): devuelve cierto si caracter es una letra minúscula, y


falso en caso contrario.

isupper(caracter): devuelve cierto si caracter es una letra mayúscula,


y falso en caso contrario.

toupper(caracter): devuelve la mayúscula asociada a caracter, si la


tiene; si no, devuelve el mismo caracter.

tolower(caracter): devuelve la minúscula asociada a caracter, si la


tiene; si no, devuelve el mismo caracter.

Cadenas de Caracteres.
Operaciones con cadenas:

Entrada/salida de cadenas.

Las cadenas se muestran con printf y la adecuada marca de formato sin


que se presenten dificultades especiales. Lo que sí resulta problemático
es leer cadenas. La función scanf presenta una seria limitación: solo
puede leer ((palabras)), no ((frases)). Ello nos obliga a presentar una
nueva función (gets).

Salida con printf:

Empecemos por considerar la función printf, que muestra cadenas con


la marca de formato %s. Aquí se tiene un ejemplo de uso:
#include <stdio.h>
#define MAXLON 80
int main()
{
char cadena[MAXLON+1] = "una cadena";

printf ("El valor de cadena es %s.\n", cadena);


return 0;
}
El resultado es el siguiente:

Se puede alterar la presentación de la cadena con modificadores:


#include <stdio.h>
#define MAXLON 80
int main() {
char cadena[MAXLON+1] = "una cadena";

printf("El valor de cadena es (%s).\n", cadena);


printf("El valor de cadena es (%20s).\n", cadena);
printf("El valor de cadena es (%-20s).\n", cadena);
return 0;
}

Teniendo como resultado:

Si se desea mostrar una cadena carácter a carácter, se Puede hacer


llamando a printf sobre cada uno de los caracteres, pero debe recordar
que la marca de formato asociada a un carácter es %c:
#include <stdio.h>
#define MAXLON 80
int main(void) {
char cadena[MAXLON+1] = "una cadena";

int i;
i = 0;
while (cadena[i] != ’\0’) {
printf ("%c\n", cadena[i]);
i++;
}
return 0;
}

Este es el resultado de la ejecución:

Entrada con scanf:

La función scanf es un reto mayor. He aquí un ejemplo que pretende


leer e imprimir una cadena en la que podemos guardar hasta 80
caracteres (sin contar el terminador nulo):
#include <stdio.h>
#define MAXLON 80
int main(void) {
char cadena[MAXLON+1];

printf ("Introduce una cadena: ");


scanf ("%s", cadena);
printf ("La cadena leída es %s\n", cadena);
return 0;
}

Debe notar que con las cadenas no hay que poner el caracter & del
identificador al usar scanf. Recordar: cadena[0] es un char, pero cadena,
sin mas, es la dirección de memoria en la que empieza el vector de
caracteres. Al ejecutar el programa introduciendo la cadena "una" se
obtiene el siguiente resultado por pantalla.

Hay un problema práctico con scanf: solo lee una (palabra), es decir,
una secuencia de caracteres no blancos. Si al ejecutar el programa
tecleamos un par de palabras (una prueba), sólo se muestra la primera.
Por pantalla se obtendría lo siguiente:

Entrada con gets:

La función gets lee todos los caracteres que hay hasta encontrar un
salto de línea. Dichos caracteres, excepto el salto de línea, se
almacenan a partir de la dirección de memoria que se indique como
argumento y se añade un terminador.
#include <stdio.h>
#define MAXLON 11
int main(void)
{
char a[MAXLON+1], b[MAXLON+1];

printf ("Introduce una cadena: "); gets(a);


printf ("Introduce otra cadena: "); gets(b);
printf ("La primera es %s y la segunda es %s\n", a, b);
return 0;
}
Este es el resultado de la ejecución:

Entrada con sscanf:

La función sscanf es similar a scanf (se diferencia en la ((s)) inicial), pero


no obtiene información leyéndola del teclado, sino que la extrae de una
cadena. Un ejemplo para entender el procedimiento:
#include <stdio.h>
#define MAXLINEA 80
#define MAXFRASE 40
int main()
{
int a, b;
char frase[MAXFRASE+1];
char linea[MAXLINEA+1];

printf ("Dame el valor de un entero:");


gets(linea); sscanf (linea, "%d", &a);
printf ("Introduce ahora una frase:");
gets(frase);
printf ("Y ahora, dame el valor de otro entero:");
gets(linea); sscanf (linea, "%d", &b);
printf ("Enteros leídos: %d, %d.\n", a, b);
printf ("Frase leída: %s.\n", frase);
return 0;
}

En el programa se ha definido una variable auxiliar, linea, que es una


cadena con capacidad para 80 caracteres mas el terminador (puede
resultar conveniente reservar mas memoria para ella en según que
aplicación). Cada vez que deseamos leer un valor escalar, leemos en
línea un texto que introduce el usuario y obtenemos el valor escalar
(numérico) con la función sscanf. Dicha función recibe, como primer
argumento, la cadena en línea; como segundo, una cadena con marcas
de formato; y como tercer parámetro, la dirección de la variable
escalar en la que queremos depositar el resultado de la lectura.

Este es el resultado:

Escritura en cadenas sprintf:

Hay una función que puede simplificar notablemente la creación de


cadenas cuyo contenido se debe calcular a partir de uno o mas valores:
sprintf , disponible incluyendo la cabecera stdio.h (se trata, en cierto
modo, de la operación complementaria de sscanf ). La función sprintf se
comporta como printf , salvo por un ((detalle)): no escribe texto en
pantalla, sino que lo almacena en una cadena.

Ejemplo:
#include <stdio.h>
#define MAXLON 80
int main(void)
{
char a[MAXLON+1] = "una";
char b[MAXLON+1] = "cadena";
char c[MAXLON+1];

sprintf (c, "%s %s", a, b);


printf ("%s\n", c);
return 0;
}

Si se ejecuta el programa mostrara por pantalla…


Asignación y copia de cadenas:

Para efectuar una copia de una cadena, has de hacerlo carácter a


carácter, o en su defecto usar las función strcpy correspondiente
incluidas en <string.h>
#include <string.h>
#define MAXLON 10 ***
int main()
{
char original[MAXLON+1] = "cadena";
char copia[MAXLON+1];
int i;

for (i = 0; i <= MAXLON; i++)


copia[i] = original[i];
return 0;
}

Se Debe notar que el bucle recorre los 10 caracteres que realmente hay
en original pero, de hecho, solo se requieren copiar los caracteres que
hay hasta el terminador, incluyéndole a él.
#define MAXLON 10
int main()
{
char original[MAXLON+1] = "cadena";
char copia[MAXLON+1];
int i;

for (i = 0; i <= MAXLON; i++) {


copia[i] = original[i];
if (copia[i] == ’\0’)
break;
}
return 0;
}

Este sería el resultado:


Longitud de una cadena:

El convenio de terminar una cadena con el carácter nulo permite


conocer fácilmente la longitud de una cadena:
#include <stdio.h>
#define MAXLON 80
int main(void)
{
char a[MAXLON+1];
int i;

printf ("Introduce una cadena (max. %d cars.): ", MAXLON);


gets(a);
i = 0;
while (a[i] != ’\0’) i++;
printf ("Longitud de la cadena: %d\n", i);
return 0;
}

Calcular la longitud de una cadena es una operación frecuentemente


utilizada, así que está predefinida en la biblioteca de tratamiento de
cadenas <string.h> (strlen). Acá un ejemplo de conteo de caracteres
usando strlen (conteo de vocales minúsculas) leída la cadena desde
teclado.
#include <stdio.h>
#include <string.h>
#define MAXLON 80
int main()
{
char a[MAXLON+1];
int i, contador=0, longitud;

printf ("Introduce una cadena (max. %d cars.): ",MAXLON); gets(a);


longitude = strlen(a);
for (i = 0; i < longitud; i++)
if (a[i] == ’a’ || a[i] == ’e’ || a[i] == ’i’ || a[i] == ’o’ ||
a[i] == ’u’)
contador++;
printf ("Vocales minúsculas: %d\n", contador);
return 0;
}

Concatenación:

En C existe la posibilidad de concatenar cadenas con bucles. Este


programa, por ejemplo, pide dos cadenas y concatena la segunda a la
primera:
#include <stdio.h>
#define MAXLON 80
int main(void)
{
char a[MAXLON+1], b[MAXLON+1];
int longa, longb;
int i;

printf ("Introduce un texto (max. %d cars.): ", MAXLON);


gets(a);
printf ("Introduce otro texto (max. %d cars.): ", MAXLON);
gets(b);
longa = strlen(a);
longb = strlen(b);
for (i=0; i<longb; i++)
a[longa+i] = b[i];
a[longa+longb] = ’\0’;
printf ("Concatenación de ambos: %s", a);
return 0;
}

Escribamos como ejemplo "casa grande" y veamos lo que pasa:

Punteros.
Definición:
Un puntero, tambien llamado apuntador, es una variable que contiene
una dirección de memoria, por lo tanto, su valor hace referencia a una
posición dentro de esta.

Se dice que p (variable de tipo puntero) apunta a v (varible que


almacena un valor) pues el primero hace referencia al la posición que
ocupa en memoria la variable v.

veamos la siguente representación gráfica.

Representación gráfica del funcionamiento de un puntero.

Declaración:

Para declarar un puntero hay que tener en cuenta que estos deben ir
precedidos de un "*". La forma sería la siguiente:
tipo_dato *puntero;

Donde:

--- punteroes el nombre de la variable tipo puntero. Esta puede tener


cualquier nombre.
--- tipo_datoes el tipo de dato contenido en la variable a la que aputa
el puntero. Es de señalar que un puntero debe siempre ir dirigido a una
variable de su mismo tipo, por tal, un puntero de tipo char deberá
apuntar a una variable char.

Operadores.

En lenguaje C existen dos operadores especiales para trabajar con


puteros:

"&"llamado operador dirección, nos devolverá la dirección en memoria


de su operando.

"*"llamado operador de indirección, quien nos devolverá el valor


contenido en la variable apuntada por el puntero.

Punteros.
Funciones.

Los punteros proporcionan el soporte necesario para el potente sistema


de asignación dinámica de memoria de C. La asignación dinámica es la
forma en la que un programa puede obtener memoria mientras se está
ejecutando.

El centro del sistema de asignación dinámica está compuesto por las


funciones (existentes en la biblioteca stdlib.h) malloc(), que asigna
memoria; y free() que la devuelve.

El prototipo de la función malloc() es: stdlib.h malloc(), que asigna


memoria; y free() que la devuelve .void *malloc(size_t número de bytes);

Tras una llamada fructífera, malloc() devuelve un puntero, el primer


byte de memoria dispuesta. Si no hay suficiente memoria libre para
satisfacer la petición de malloc(), se da un fallo de asignación y devuelve
un nulo. El fragmento de código que sigue asigna 1000 bytes de
memoria:
char *p;
p = (char *) malloc(1000);
Después de la asignación, p apunta al primero de los 1000 bytes de la
memoria libre. El siguiente ejemplo dispone espacio para 50 enteros.
Obsérvese el uso de sizeof para asegurar la portabilidad: p apunta al
primero de los 1000 bytes de la memoria libre. El siguiente ejemplo
dispone espacio para 50 enteros. Obsérvese el uso de sizeof para
asegurar la portabilidad:
int *p;
p= (int *) malloc(50*sizeof(int));

La función free() es la opuesta de malloc() porque devuelve al sistema la


memoria previamente asignada. Una vez que la memoria ha sido
liberada, puede ser reutilizada en una posterior llamada a malloc(). El
prototipo de la función free() es:
void free (void *p);
free(p);

Punteros y estructuras.
Al igual que con el resto de tipos de variables, C permite crear variables
punteros a estructuras. La forma de declarar estas variables es:
struct nombre_estructura *nombre_varible_estructura;

Para poder acceder a los elementos individuales de una variable puntero


a estructura se utiliza el operador -> (el operador, denominado
comunmente flecha, está formado por un signo menos seguido de un
signo de mayor, sin ningún espacio en blanco entre ellos). Siguiendo con
el ejemplo anterior de las coordenadas, vamos a definir un puntero a
una variable de estructura de la siguiente forma:
struct coordenada a, b, *p, *q;

a.x = 5;
a.y = 23;
a.z = 10;

b = a;
p = &b; /* &b nos devuelve la dirección de la estructura b */

p->x = 2;
p->y = a.y;
p->z = a.z;
q = p; /* p y q apuntan a la misma estructura */

Al igual que ocurría en el apartado anterior también existe la


posibilidad de declarar tablas de estructuras. El formato sería el
siguiente:
struct nombre_estructura *nombre_varible_estructura[N];

ó
struct nombre_estructura *nombre_varible_estructura[N][M];

Por supuesto también se pueden declarar tablas de punteros a


estructuras de más de dos dimensiones pero al igual que ocurría con la
declaración de tablas de tipos de datos básicos, no suelen ser muy
usadas.

Un ejemplo de declaración de un vector de punteros a estructuras y un


acceso al campo de una estructura sería la siguiente:
struct coordenada coor1, *vector_punteros_coordenadas[10];

vector_punteros_coordenadas[4] = &coor1;
vector_punteros_coordenadas[4]->y = 2;

Al igual que ocurría con los punteros a tipos básicos de datos también se
pueden pasar punteros a estructuras en las llamadas a funciones. Así por
ejemplo tendríamos:
struct coordenada coordenada1, *p_coordenada1;
flota distancia;
..................................
coordenada1.x = 5;
coordenada1.y = -11;
p_coordenada1 = &coordenada1;
..................................
cambiar_a_punto_simétrico_en_cuadrante (p_coordenada1);

ó
cambiar_a_punto_simetrico_en_cuadrante (&coordenada1);
..................................

....
....
....
/* La siguiente función intercambia la coordenada x por la y */
void cambiar_a_punto_simétrico_en_cuadrante(struct coordenada *c)
{
int aux;

aux = (*c).x;
(*c).x = (*c).y;
(*c).y = aux;
}

Nótese la equivalencia entre la notación c->x y (*c).x

Archivos.
Definición:

Los archivos informáticos son el medio de que disponemos para


almacenar información no volátil en un dispositivo de almacenamiento.
Los Sistemas de archivos de que disponen los sistemas operativos
disponen de mecanismos para que un usuario pueda manipular los
archivos (seleccionar, editar, ejecutar, borrar, ...). Desde el punto de
vista de un programador un archivo es un medio para poder leer datos
de entrada para su programa o donde poder guardar los resultados de su
ejecución. Todo lenguaje de programación debe disponer de algún
mecanismo para que el programador pueda manipular archivos desde un
programa. Estos mecanismos pueden ser más o menos sofisticados o
versátiles dependiendo del lenguaje de programación que estemos
considerando, pero deben haber unas funciones básicas para poder
acceder a un archivo, estas son:

• Lectura (consulta).-Esta operación consiste el leer la información


contenida en fichero sin alterarla.
• Escritura (modificación).- Consiste en actualizar el contenido del
fichero bien añadiéndole nuevos datos o borrando parte de los que
contenía.
• Apertura.- Antes de acceder a un fichero, tanto para consultar
como para actualizar su información, es necesario abrirlo. Esta
operación se debe realizar previamente a las operaciones de
lectura o escritura.
• Cierre.- Cuando se ha terminado de consultar o modificar un
fichero, por lo general, del mismo modo que se tuvo que abrir
para realizar alguna operación de lectura/escritura sobre él, éste
deberá ser cerrado.

Archivos.
Ficheros

El estándar de C contiene funciones varias para la edición de ficheros,


estas están definidas en la cabecera stdio.h y por lo general empiezan
con la letra f, haciendo referencia a file. Adicionalmente se agrega un
tipo <FILE

, el cual se usará como apuntador a la información del fichero. La


secuencia que usaremos para realizar operaciones será la siguiente:

• Crear un apuntador del tipo FILE *


• Abrir el archivo utilizando la función fopen y asignándole el
resultado de la llamada a nuestro apuntador.
• Hacer las diversas operaciones (lectura, escritura, etc).
• Cerrar el archivo utilizando la función fclose.

fopen

Esta función sirve para abrir y crear ficheros en disco.

El prototipo correspondiente de fopen es:


FILE * fopen (const char *filename, const char *opentype);

Los parámetros de entrada de fopen son:

una cadena que contiene un nombre de fichero válido.


filename:
opentype: especifica el tipo de fichero que se abrirá o se creará.

Una lista de parámetros opentype para la función fopen son:

• "r" : abrir un archivo para lectura, el fichero debe existir.


• "w" : abrir un archivo para escritura, se crea si no existe o se
sobreescribe si existe.
• "a" : abrir un archivo para escritura al final del contenido, si no
existe se crea.
• "r+" : abrir un archivo para lectura y escritura, el fichero debe
existir.
• "w+" : crear un archivo para lectura y escritura, se crea si no
existe o se sobreescribe si existe.
• "a+" : abrir/crear un archivo para lectura y escritura al final del
contenido

fclose

Esta función sirve para poder cerrar un fichero que se ha abierto.

El prototipo correspondiente de fclose es:


int fclose (FILE *stream);

Un valor de retorno cero indica que el fichero ha sido correctamente


cerrado, si ha habido algún error, el valor de retorno es la constante
EOF.

Un ejemplo pequeño para abrir y cerrar el archivo llamado fichero.in en


modo lectura:
#include <stdio.h>
int main(int argc, char** argv)
{
FILE *fp;

fp = fopen ( "fichero.in", "r" );


fclose ( fp );
return 0;
}

Como vemos, en el ejemplo se utilizó el opentype "r", que es para la


lectura.

Otra cosa importante es que el lenguaje C no tiene dentro de si una


estructura para el manejo de excepciones o de errores, por eso es
necesario comprobar que el archivo fue abierto con éxito "if (archivo ==
NULL)". Si fopen pudo abrir el archivo con éxito devuelve la referencia al
archivo (FILE *), de lo contrario devuelve NULL y en este caso se debera
revisar la direccion del archivo o los permisos del mismo. En estos
ejemplos solo vamos a dar una salida con un retorno de 1 que sirve para
señalar que el programa termino por un error.

feof

Esta función sirve para determinar si el cursor dentro del archivo


encontró el final (end of file). Existe otra forma de verificar el final del
archivo que es comparar el caracter que trae fgetc del archivo con el
macro EOF declarado dentro de stdio.h, pero este método no ofrece la
misma seguridad (en especial al tratar con los archivos "binarios"). La
función feof siempre devolverá cero (Falso) si no es encontrado EOF en el
archivo, de lo contrario regresará un valor distinto de cero (Verdadero).

El prototipo correspondiente de feof es:


int feof(FILE *fichero);

rewind

Literalmente significa "rebobinar", sitúa el cursor de lectura/escritura al


principio del archivo.

El prototipo correspondiente de rewind es:


void rewind(FILE *fichero);

Lectura
Un archivo generalmente debe verse como un string (una cadena de
caracteres) que esta guardado en el disco duro. Para trabajar con los
archivos existen diferentes formas y diferentes funciones. Las funciones
que podríamos usar para leer un archivo son:

• char fgetc(FILE *archivo)


• char *fgets(char *buffer, int tamano, FILE *archivo)
• size_t fread(void *puntero, size_t tamano, size_t cantidad, FILE
*archivo);
• int fscanf(FILE *fichero, const char *formato, argumento, ...);
Las primeras dos de estas funciones son muy parecidas entre si. Pero la
tercera, por el numero y el tipo de parámetros, nos podemos dar cuenta
de que es muy diferente, por eso la trataremos aparte junto
al fwrite que es su contraparte para escritura.

fgetc

Esta función lee un caracter a la vez del archivo que esta siendo
señalado con el puntero *archivo. En caso de que la lectura sea exitosa
devuelve el caracter leído y en caso de que no lo sea o de encontrar el
final del archivo devuelve EOF.

El prototipo correspondiente de fgetc es:


char fgetc(FILE *archivo);

Esta función se usa generalmente para recorrer archivos de texto. A


manera de ejemplo vamos a suponer que tenemos un archivo de texto
llamado "prueba.txt" en el mismo directorio en que se encuentra el
fuente de nuestro programa. Un pequeño programa que lea ese archivo
será:
#include <stdio.h>
#include <stdlib.h>
int main()
{
FILE *archivo;
char caracter;

archivo = fopen("prueba.txt","r");
if (archivo == NULL){
printf("\nError de apertura del archivo. \n\n");
}
else {
printf("\n El contenido del archivo de prueba es \n\n");
while (feof(archivo) == 0){
caracter = fgetc(archivo);
printf("%c",caracter);
}
}
return 0;
}

fgets
Esta función está diseñada para leer cadenas de caracteres. Leerá hasta
n-1 caracteres o hasta que lea un retorno de línea. En este último caso,
el carácter de retorno de línea también es leído.

El prototipo correspondiente de fgets es:


char *fgets(char *buffer, int tamaño, FILE *archivo);

El primer parámetro buffer lo hemos llamado así porque es un puntero a


un espacio de memoria del tipo char (podríamos usar un arreglo de
char). El segundo parámetro es tamaño que es el limite en cantidad de
caracteres a leer para la funcion fgets. Y por ultimo el puntero del
archivo por supuesto que es la forma en que fgets sabra a que archivo
debe leer.
#include <stdio.h>
#include <stdlib.h>
int main()
{
FILE *archivo;
char caracteres[100];
archivo = fopen("prueba.txt","r");
if (archivo == NULL)
exit(1);
printf("\nEl contenido del archivo de prueba es \n\n");
while (feof(archivo) == 0){
fgets(caracteres,100,archivo);
printf("%s",caracteres);
}
return 0;
}

Este es el mismo ejemplo de antes con la diferencia de que este hace


uso de fgets en lugar de fgetc. La función fgets se comporta de la
siguiente manera, leerá del archivo apuntado por archivo los caracteres
que encuentre y a ponerlos en buffer hasta que lea un caracter menos
que la cantidad de caracteres especificada en tamaño o hasta que
encuentre el final de una linea (\n) o hasta que encuentre el final del
archivo (EOF).

El beneficio de esta función es que se puede obtener una linea completa


a la vez. Y resulta muy útil para algunos fines como la construcción de
un parser de algún tipo de archivo de texto.
fread

size_t fread ( void * ptr, size_t size, size_t count, FILE * stream );

Esta función lee un bloque de una "stream" de datos. Efectúa la lectura


de un arreglo de elementos "count", cada uno de los cuales tiene un
tamaño definido por "size". Luego los guarda en el bloque de memoria
especificado por "ptr". El indicador de posición de la cadena de
caracteres avanza hasta leer la totalidad de bytes. Si esto es exitoso la
cantidad de bytes leídos es (size*count).

PARAMETROS:

ptr : Puntero a un bloque de memoria con un tamaño mínimo de


(size*count) bytes.

size : Tamaño en bytes de cada elemento (de los que voy a leer).

count : Número de elementos, los cuales tienen un tamaño "size".

stream: Puntero a objetos FILE, que especifica la cadena de entrada.

fscanf

La función fscanf funciona igual que scanf en cuanto a parámetros, pero


la entrada se toma de un fichero en lugar del teclado.

El prototipo correspondiente de fscanf es:


int fscanf(FILE *fichero, const char *formato, argumento, ...);

Podemos ver un ejemplo de su uso, abrimos el documento "fichero.txt"


en modo lectura y leyendo dentro de el.
#include <stdio.h>
int main ( int argc, char **argv )
{
FILE *fp;
char buffer[100];

fp = fopen ( "fichero.txt", "r" );


fscanf(fp, "%s" ,buffer);
printf("%s",buffer);
fclose ( fp );
return 0;
}

Escritura
Así como podemos leer datos desde un fichero, también se pueden crear
y escribir ficheros con la información que deseamos almacenar, Para
trabajar con los archivos existen diferentes formas y diferentes
funciones. Las funciones que podríamos usar para escribir dentro de un
archivo son:

• int fputc(int caracter, FILE *archivo)


• int fputs(const char *buffer, FILE *archivo)
• size_t fwrite(void *puntero, size_t tamano, size_t cantidad, FILE
*archivo);
• int fprintf(FILE *archivo, const char *formato, argumento, ...);

fputc

Esta función escribe un carácter a la vez del archivo que esta siendo
señalado con el puntero *archivo. El valor de retorno es el carácter
escrito, si la operación fue completada con éxito, en caso contrario
será EOF.

El prototipo correspondiente de fputces:

int fputc(int carácter, FILE *archivo);

Mostramos un ejemplo del uso de fputc en un "fichero.txt", se escribira


dentro del fichero hasta que presionemos la tecla enter.
#include <stdio.h>
int main ( int argc, char **argv )
{
FILE *fp;
char caracter;

fp = fopen ( "fichero.txt", "r+" );


printf("\nIntrouce un texto al fichero: ");
while((caracter = getchar()) != '\n') {
printf("%c", fputc(caracter, fp));
}
fclose ( fp );
return 0;
}

fputs

La función fputs escribe una cadena en un fichero. No se añade el


carácter de retorno de línea ni el carácter nulo final. El valor de retorno
es un número no negativo o EOF en caso de error. Los parámetros de
entrada son la cadena a escribir y un puntero a la estructura FILE del
fichero donde se realizará la escritura.

El prototipo correspondiente de fputs es:

int fputs(const char *buffer, FILE *archivo)

para ver su funcionamiento mostramos el siguiente ejemplo:


#include <stdio.h>
int main ( int argc, char **argv )
{
FILE *fp;
char cadena[] = "Mostrando el uso de fputs en un fichero.\n";
fp = fopen ( "fichero.txt", "r+" );
fputs( cadena, fp );
fclose ( fp );
return 0;
}

fwrite

Esta función está pensada para trabajar con registros de longitud


constante y forma pareja confread. Es capaz de escribir hacia un fichero
uno o varios registros de la misma longitud almacenados a partir de una
dirección de memoria determinada. El valor de retorno es el número de
registros escritos, no el número de bytes. Los parámetros son: un
puntero a la zona de memoria de donde se obtendrán los datos a
escribir, el tamaño de cada registro, el número de registros a escribir y
un puntero a la estructura FILEdel fichero al que se hará la escritura.

El prototipo correspondiente de fwritees:

size_t fwrite(void *puntero, size_t tamano, size_t cantidad, FILE


*archivo);
fprintf

La función fprintffunciona igual que printf en cuanto a parámetros, pero


la salida se dirige a un archivo en lugar de a la pantalla.

El prototipo correspondiente de fprintf es:


int fprintf(FILE *archivo, const char *formato, argumento, ...);

También podría gustarte