# data[].attributes.body
Hay un ejemplo de un programa en C

# data[].attributes.attachment_link.description
Create a new document and edit with others at the same time -- from your computer, phone or tablet. Get stuff done with or without an internet connection. Use Docs to edit Word files. Free from Google.

# data[].attributes.attachment_link.title
Instalación de Visual Studio Code para Programar en C

# data[].attributes.attachment_link.title
Cap 2 - Vectores y Arreglos n-dimensionales

# data[].attributes.attachment_link.readable_text
/*
Nombre de archivo: hw0.c (No cambiar el nombre de este archivo)
El repositorio donde esta tu HW0 es: github.com/unlu-edu-ar/prog1-2022-hw-0-TuNombreDeUsuarioGithub
Importante: No cambiar el nombre del archivo

Completa con tu nombre, apellido y DNI
Nombre y Apellido: Lucia Vanini
DNI: 44242654
*/

#include <stdio.h>

/* Programe una funcion que reciba dos numeros enteros
   como parametros, y returne la suma de dichos numeros.
 */
int sumar_dos_numeros(int a, int b){
   int suma = 0;
   suma = a + b;
   return suma;
   return 0;
}

/* Programe una funcion que reciba un numero entero como parametro. 
   La funcion debe retornar 1, si el numero es mayor a o igual a cero. 
   La funcion debe retornar cero, si el numero fuese menor a cero.
 */
int positividad(int b){
   int m = 1;
   int n = 0;
   if (b>= 0){
      return m;
   }else {
      return n;
   }
  return 0;
  
}

/* Programe una funcion que recibe dos numeros enteros positivos n1 y n2 
   como parametros, donde n1 < n2, y retorna el resultado de sumar 
   los numeros enteros contenidos en el intervalo [n1...n2]
*/
int sumar_intervalo(int n1, int n2){
   int suma; int x; suma = 0;
   if (n1<n2 && n1>0 && n2>0){
      for(x=n1;x<=n2;++x){
         suma = suma +x;
      }
   }
   return suma; 
   return 0;
}

# data[].attributes.attachment_link.title
Cap. 2 - Métodos de Búsqueda y Ordenamiento

# data[].attributes.attachment_link.title
PT02-3 - Arreglos -Algoritmos de Búsqueda.pptx

# data[].attributes.attachment_link.title
TP02 - Parte 02 - Arreglos_Ordenamiento.docx

# data[].attributes.attachment_link.title
PT02-4 - Arreglos - Algoritmos de Ordenamiento.pptx

# data[].attributes.attachment_link.title
PT02-5 - Vectores - Búsqueda y Ordenamiento - Eficiencia.pptx

# data[].attributes.attachment_link.description
You can't perform that action at this time. You signed in with another tab or window. You signed out in another tab or window. Reload to refresh your session. Reload to refresh your session.

# data[].attributes.attachment_link.title
PT03 - Vectores - Operaciones - Mezcla .pptx

# data[].attributes.attachment_link.readable_text
/*
Nombre de archivo: hw1.c (No cambiar el nombre de este archivo)
El repositorio donde esta tu HW1 es: github.com/unlu-edu-ar/prog1-2022-hw-1-TuNombreDeUsuarioGithub
Importante: No cambiar el nombre del archivo

Completa con tu nombre, apellido y DNI
Nombre y Apellido: Lucia Vanini
DNI: 44242654
*/

/* Programe una funcion que recibe como parametros un vector v 
de numeros enteros, su cantidad de elementos n, y un entero k, 
y devuelve la cantidad de apariciones de k en v.
*/
int apariciones(int v[], int n, int k){
   int apariciones = 0;
   int i = 0;
   for (i; i<n; i++){ 
      if (v[i]== k){
         apariciones +=1;
      }
   }
   return apariciones;
   }


/* Programe una funcion que reciba como parametro un vector v 
de numeros enteros mayores o iguales a cero, y su cantidad de 
elementos n, y retorne el mayor elemento del vector.
 */
int mayor(int v[], int n){
   int i = 1;
   int mayor = v[0];
   for (i; i<n; i++){
       if (v[i]> mayor){
         mayor = v[i];
       }
   }
   return mayor;
   return 0;
}

/* Programe una- funcion que reciba como parametros dos vectores de 
numeros enteros v1 y v2, y su longitud n (los vectores tienen igual
longitud), y devuelva 1 si v2 es el orden reverso de v1, y 0 si no. 
Ejemplo: 
Si v1 = {3,4,1} su reverso es v2 = {1,4,3}, y la funcion retorna 1.
 */
int reverso(int v1[], int v2[], int n){
 int i = 0;
 int j = n-1;
 int rta = 0;
   while (v1[i] == v2[j]){
      rta = 1;
      i++;
      j--;
   }
 return rta; 
} 


/* Programe una funcion que recibe un vector v de numeros enteros, 
y su longitud n, y devuelve 1 si esta ordenado (ya sea creciente o 
decrecientemente), y 0 si no.
Ejemplo:
{1,1,2} esta ordenado en forma ascendente y retorna 1.
{6,4} esta ordenado en forma descendente y retorna 1.
{1,3,2} esta desordenado y retorna 0.
*/
int ordenado(int v[], int n){
   int ordenado = 1;
   const char* forma ="";
   int i = 1;
   if (n <= 1){
      ordenado = 1;
   }
   
   for (i; i<n; i++){
      if (v[i] < v[i-1]){
         if (forma == ""){
            forma = "decreciente";
         }
         if (forma == "creciente"){
            ordenado = 0;
         }
      }else if (v[i] > v[i-1]) {
         if (forma == ""){
         forma = "creciente";
         }
         if(forma == "decreciente"){
         ordenado = 1;
         }
      }
   }
return ordenado;
}



# data[].attributes.attachment_link.description
You can't perform that action at this time. You signed in with another tab or window. You signed out in another tab or window. Reload to refresh your session. Reload to refresh your session.

# data[].attributes.attachment_link.title
PT05-2 - Registros- Arreglo de Registros.pptx

# data[].attributes.attachment_link.title
Cap. 7 - Archivos en C - Organización y Accesos (1)

# data[].attributes.attachment_link.description
You can't perform that action at this time. You signed in with another tab or window. You signed out in another tab or window. Reload to refresh your session. Reload to refresh your session.

# data[].attributes.attachment_link.readable_text
/*
Nombre de archivo: hw2.c (No cambiar el nombre de este archivo)
El repositorio donde esta tu HW2 es: github.com/unlu-edu-ar/prog1-2022-hw-2-TuNombreDeUsuarioGithub
Importante: No cambiar el nombre del archivo

Completa con tu nombre, apellido y DNI
Nombre y Apellido: Lucia Vanini
DNI: 44242654
*/


/* Programe una funcion para agregar un elemento al final de un vector.
INPUT: v (vector de numeros enteros), n (entero), util (int*), elem (int) 
OUTPUT: s (int)
siendo v el vector al que se desea agregar un elemento, n la longitud maxima del
vector v, util un puntero a la variable que almacena la cantidad de elementos 
actualmente utilizados de v, y elem el elemento a agregar.
La funcion debera agregar elem al final de los elmentos utilizados del vector v, 
e incrementar el valor de la variable apuntada por util en 1.
La función debe retonar cero si pudo agregar exitosamente el elemento, y 1 en 
el caso de que el vector v este lleno y no se pueda agregar el elemento al vector.

Ejemplo: 
Si v = {3,4,1,8}, n = 4, *util = 2, elem = 7, tras llamar a la funcion debe quedar
   v = {3,4,7,8}, *util = 3, s = 0
Si v = {3,4,1,8}, n = 4, *util = 4, elem = 7, tras llamar a la funcion debe quedar
   v = {3,4,1,8}, *util = 4, s = 1
*/
int agregar(int v[], int n, int* util, int elem){ 
	int respuesta = 1;
	int cantidadDeElementos = *util;
	if (*util < n){
		v[cantidadDeElementos] = elem;
		*util = *util+1;
		respuesta = 0;
	}
	return respuesta;
	
}


/* Programe una funcion para eliminar el elemento en el indice pos de un vector.
INPUT: v (vector de numeros enteros), n (entero), util (int*), pos (int) 
OUTPUT: s (int)
siendo v el vector al que se desea eliminar un elemento, n la longitud maxima del
vector v, util un puntero a la variable que almacena la cantidad de elementos 
actualmente utilizados de v, y pos el indice del elemento a eliminar.
Para eliminar el elemento de la posición pos, la funcion debe mover los elementos 
utilizados una posicion hacia la izquierda (hasta la posicion pos).
La funcion tambien debe decrementar en 1 la variable apuntada por util.
La función debe retonar cero si pudo eliminar exitosamente el elemento, y 1 en 
el caso de que no haya podido eliminar el elemento.

Ejemplo: 
Si v = {3,4,1,8}, n = 4, *util = 3, pos = 1, tras llamar a la funcion debe quedar
   v = {3,1,1,8}, *util = 2, s = 0
Si v = {3,4,1,8}, n = 4, *util = 1, pos = 2, tras llamar a la funcion debe quedar
   v = {3,4,1,8}, *util = 1, s = 1
 */
int eliminar(int v[], int n, int* util, int pos){ 
	int cantidaDeElementos = *util;
	int i;
	int respuesta = 1;
		if (pos < cantidaDeElementos){
			for(i= pos; i < cantidaDeElementos-1; i++){
				v[i] = v[i+1];
			}
			*util = *util - 1;
			respuesta = 0;
		}
	return respuesta;
}


/* Programe una funcion que reciba una matriz de enteros, de m filas por n 
columnas como entrada. Si su cantidad de filas es mayor o igual que su
cantidad de columnas, la funcion debe retornar la sumatoria de los elementos
de la matriz. Si su cantidad de filas es menor que su cantidad de columnas, 
la funcion debe retornar la productoria de los elementos de la matriz. 
INPUT: m (int), n (int), arr (matriz de numeros enteros de mxn)
OUTPUT: s (int) 
*/
int sumaprod_matriz(int m, int n, int arr[m][n]){ 
	// m = filas
	// n = columnas
	int respuesta = 0;
	int respuesta1 = 1;
	int i, j;
	int elementoactual = 0; 

	if (m >= n){
		for (i=0; i<m; i++){
			for (j=0; j<n;j++){
				elementoactual =  arr[i][j];
				respuesta = respuesta + elementoactual;
			}
		}
	}
	else if (n > m){
		for (j=0; j<n; j++){
			for (i=0; i<m; i++){
				elementoactual = arr[i][j];
				respuesta1 = respuesta1 * elementoactual;
			}
		}
		respuesta = respuesta1;
	}
	return respuesta;
}


/* Programe una funcion que reciba una matriz de enteros, de m filas por n 
columnas como entrada, y retorne el minimo de los elementos de la matriz.
INPUT: m (int), n (int), arr (matriz de numeros enteros de mxn)
OUTPUT: minimo (int) 
*/
int minimo_elem_matriz(int m, int n, int arr[m][n]){ 
	int i = 0; 
	int j = 0;
	int minimo = arr[0][0];

	for (i; i<m; i++){
		for (j; j<n; j++){
			if (arr[i][j]<minimo){
				minimo = arr[i][j];
			}
		}
	}
	return minimo;

}


/*
Programe una funcion que reciba una matriz de enteros, de m filas por n 
columnas como entrada, un vector v de dimension m, y un vector w de 
dimension n, y coloque la sumatoria de sus elementos de sus filas en
el vector v, y la sumatoria de los elementos de sus columnas en w.
INPUT: m (int), n (int), arr (matriz de numeros enteros de mxn), 
v (vector de enteros), w (vector de enteros)
OUTPUT: void 
*/
void suma_filas_col(int m, int n, int arr[m][n], int v[m], int w[n]){ 
	int i, j, sumacolumna, sumafila;
	//suma de las filas.
	for (i = 0; i<m; i++){
		//reinicio el contador
		sumafila = 0;
		for (j= 0; j<n; j++){
			sumafila= sumafila + arr[i][j];
		}
		//guardo el resultado en el vector en la posicion i
		v[i] = sumafila;
	}
	//para las columnas 
	for (j=0;j<n;j++){
		//reinicio el contador
		sumacolumna = 0;
		for (i=0; i<m; i++){
			sumacolumna = sumacolumna + arr[i][j];
		}
		//guardo el resultado en el vector en la posicion j
		w[j] = sumacolumna;
	}
}

	
	


# data[].attributes.attachment_link.readable_text
Resumen: Entrega nº36 del tutorial "Curso básico de programación en lenguaje C desde cero".

Codificación aprenderaprogramar.com: CU00536F

LEER Y ESCRIBIR ARCHIVOS USANDO LENGUAJE C

Advertencia: una manipulación incorrecta de ficheros puede dar lugar a la pérdida de datos, al malfuncionamiento de programas o a fallos del sistema operativo del ordenador. Es necesario disponer de copias de seguridad de toda información que se considere importante.

Guardar datos a un disco o recuperar los datos previamente guardados son procesos fundamentales en cualquier programa informático. La importancia del almacenamiento de contenidos es obvia: envío de información a otros usuarios, posponer el trabajo varios días o semanas sin tener que introducir manualmente los datos de nuevo, acceso a información almacenada en sistemas remotos, etc. Incluso para desarrollos de software de relativamente corta longitud resulta relevante la gestión de datos, por ahorrar una cantidad de tiempo considerable.

Ficheros y bases de datos constituyen un cuerpo de conocimiento de cierta complejidad y extensión. Por motivos de espacio no vamos a hacer más que una breve introducción.

Podemos pensar en los ficheros o archivos de forma análoga a lo que sería un archivo físico: un lugar donde hay información almacenada. Ahora bien, eso no nos dice cómo se encuentra esa información: si está ordenada (alfabéticamente, de mayor a menor, en impresos con campos predefinidos), si son datos de un tipo o de varios tipos (numéricos, tipo texto, mezcla de tipos de datos...), si se leen usando alguna clave de interpretación (una partitura no se lee igual que un texto), etc. Todo esto es relevante y por ello normalmente sabremos qué tipo de datos contiene el fichero y cómo están ordenados antes de acceder a él. No es lo mismo guardar "3246" como número tipo int que como cadena de caracteres. Un tipo int ocupa un espacio en disco, p.ej. 2 bytes y tiene una "clave" para su lectura, mientras que como caracteres cada cifra ocupa un byte y se lee como si de texto se tratara.

Un asunto a considerar es si la información está contenida en campos de longitud predefinida. Consideremos un archivo donde se almacenan los nombres, números de DNI y año de nacimiento de 3 personas. Podemos considerar diferentes casos:

a) Existen campos de longitud predefinida, que pueden carecer de información por no estar disponible.

En el fichero físico la información la guardamos en hojas preimpresas donde cada apartado tiene una longitud disponible para escribir en él. En el fichero informático la información la guardamos en registros (un registro equivale a una hoja del fichero físico), constando cada registro de 3 campos (campo "Nombre", campo "DNI" y campo "Año de nacimiento"). Los campos serían por ejemplo:

Nombre: tipo texto 25 caracteres de longitud.

DNI: tipo entero largo (long).

Año de nacimiento: tipo entero (int).

Supongamos que cada registro ocupa 25 + 4 + 2 = 31 bytes. Si tenemos tres registros el fichero ocupa 31 * 3 = 93 bytes, independientemente de que los datos realmente existan o no, ya que el espacio se encuentra disponible para albergar un dato.

b) La información no está en campos de longitud predefinida.

Pedro González Aparicio. 1966.

Alfredo Pérez Pérez. 79555444. 1975.

Ramón González Pérez. 79666444. 1981.

En el fichero físico la información la guardamos en hojas donde escribimos los datos disponibles para cada persona. En el fichero informático la información la guardamos por ejemplo en líneas (cada línea equivale a la información disponible de una persona) sabiendo que cada línea puede tener información de uno o varios aspectos (nombre, DNI y edad) y una longitud variable.

No sabemos cuántos bytes nos ocupa cada línea ni cuántos bytes nos ocupa el fichero. No sabemos en qué posición se encuentra una información dada porque no tenemos referencias de situación. Ante ello, optamos por hacer una lectura tipo "texto" en la que un número de 8 cifras nos va a requerir 8 bytes frente a los 4 bytes que supondrían como tipo long.

c) La información no está en campos de longitud predefinida pero se dispone de información referente a su ubicación.

En el fichero físico la información la guardamos en hojas indexadas, donde cada dato dispone de un localizador. Por ejemplo, en la página 3 línea 3 encontramos el dato correspondiente al año de nacimiento de Ramón González. En el fichero informático la información la guardamos por bytes, sabiendo que cada tipo de dato ocupa un número de bytes determinado. Así si guardamos Importe: 3235, podríamos hacerlo ocupando 11 bytes desglosados en 9 bytes (uno por carácter, incluidos los espacios) asociados a "Importe: " como tipo texto + 2 bytes (para un tipo int) asociados al número 3235.

También podríamos guardarlo todo como tipo texto ocupando 13 bytes.

Una vez guardada la información, podríamos recuperarla indicándole al ordenador: Extrae como tipo texto los bytes comprendidos entre 1 y 9 y como número los bytes comprendidos entre 10 y 11.

Hemos tratado de introducir, a través de la analogía con un fichero físico, enfoques básicos para la comprensión y gestión de ficheros informáticos. La problemática, como se comprenderá, es muy amplia al intervenir numerosos factores (hardware y software; directorios, unidades de disco, sobreescritura de archivos, borrado accidental de datos, etc.) y posibilidades (datos ordenados, parcialmente ordenados o desordenados, diversidad de tipos de datos, tramos de ficheros con registros y campos, etc.).

Vamos a ver simplificadamente cómo podemos gestionar ficheros con el lenguaje C.

ACCESO A FICHEROS CON C: SECUENCIAL, ALEATORIO O BINARIO.

C nos permite el acceso a ficheros gracias a la biblioteca studio.h, que nos facilita todo lo necesario para el trabajo con ficheros. El acceso a un fichero puede ser:

a) Acceso secuencial: orientado a su uso en archivos donde la información está dispuesta como tipo texto.

b) Acceso aleatorio: orientado a su uso en archivos con datos contenidos en registros de longitud fija, que a su vez pueden estar subdivididos en campos. Un campo puede contener un valor numérico o ser tipo texto.

c) Acceso binario: permite guardar datos con el orden y estructura que se desee, siendo posible acceder a ellos conociendo la posición (número de byte) en que se encuentran.

Al existir distintas formas de acceso, se habla de "archivos secuenciales", "archivos aleatorios" y "archivos binarios", aunque esta terminología debe tomarse con precaución. Es decir, un "archivo binario" hace referencia a un archivo donde habitualmente guardamos y extraemos datos usando el acceso binario. Sin embargo, podríamos usar este archivo con otro tipo de acceso. En resumen, un archivo es "información" y la información puede reordenarse, cambiar, manipularse de distintas maneras, etc. Usar un tipo de acceso en un momento dado no obliga a usarlo siempre, aunque así pueda ser.

En la analogía fichero físico - fichero informático, las equivalencias aproximadas serían las de:

- Archivo secuencial = La información no está en campos de longitud predefinida.

- Archivo aleatorio = Existen campos de longitud predefinida, que pueden carecer de información por no estar disponible.

- Archivo binario = La información no está en campos de longitud predefinida pero se dispone de información referente a su ubicación.

Repetimos que todo es lo suficientemente complejo como para que sea difícil dar definiciones exactas. Nosotros vamos a estudiar únicamente ciertas formas de extraer y guardar datos de un fichero secuencial a través de algunas funciones disponibles en el lenguaje para este fin. Esto será suficiente para poder crear programas que leen y guardan datos desde archivos de forma simple. El resto de instrucciones y posibilidades de acceso no será objeto de estudio ya que quedan fuera de nuestros objetivos.

ABRIR Y CERRAR FICHEROS SECUENCIALES EN C. FILE, FOPEN, FCLOSE.

Para manipular información de un fichero, por ejemplo guardar datos en él o leer datos desde él, lo primero que hemos de hacer es abrir el fichero. El proceso a seguir es:

Abrir el fichero --> Manipular datos (extraer, guardar, modificar, etc.) -->Cerrar el fichero

fopen --> Manipular datos --> fclose

A su vez, cada vez que accedemos a un fichero hemos de indicar "bajo qué modalidad" vamos a utilizar ese fichero: si es para leer datos, para escribir datos, y a su vez si se trata de escribir si debemos añadir los datos a los que ya existieran en el fichero o si debemos desechar lo existente y crear el fichero como si fuera nuevo.

La sintaxis que emplearemos para escribir o leer datos en ficheros secuenciales será la siguiente:

FILE* nombreInternoFichero;

nombreInternofichero = fopen ("rutaNombreFichero.txt", "modoDeAcceso");

operación 1; operación 2; ... ; operación n;

...

fclose (nombreInternofichero)

FILE* nombreInternoFichero: para manipular un fichero necesitamos "algo" que el programa utilizará para almacenar información sobre el fichero (como el modo de acceso, ruta, etc.). Ese "algo" (estructura de datos) lo creamos escribiendo FILE* y el nombre que queramos utilizar para referirnos a la estructura de datos que almacenará la información relacionada con el fichero. Cuando creamos esta estructura de datos (en realidad deberíamos usar el término puntero, pero vamos a mantener las ideas claras usando simplificaciones) la creamos vacía (su contenido es NULL), a la espera de rellenarla con información.

nombreInternoFichero = fopen ("nombreFichero.txt", "modoDeAcceso"): es la instrucción que da lugar a que la estructura de datos deje de estar vacía y comience a contener información y a ser útil para poder actuar sobre un fichero. Para aportar la información necesaria se usa la función fopen, que abre el fichero cuya ruta y nombre se especifica en rutaNombreFichero.txt (no necesariamente tiene que ser un fichero txt, pero de momento vamos a suponer que es así) y define el modo de acceso. El modo de acceso indica para qué se abre y cómo debe tratarse el fichero según si existía previamente o si no existía.

Operación 1; Operación 2; ...: indica las operaciones que se ejecutan. Pueden ser bucles, condicionales, o instrucciones simples que normalmente se encargarán de extraer información del fichero (leer datos) o incorporar información al fichero (escribir datos).

fclose (nombreInternoFichero): da lugar a la conclusión de procesos abiertos, al cierre del fichero y a que "la línea de comunicación" quede libre para una posterior ocasión. Siempre que abramos un fichero con fopen deberemos cerrarlo con fclose.

MODOS DE ACCESO O APERTURA DE ARCHIVOS CON C. LEER (READ), ESCRIBIR (WRITE) O AÑADIR (APPEND).

Para acceder a un fichero se escriben sentencias similares a estas:

FILE* fichero; fichero = fopen("cursoAF1.txt", "wt");

wt es una clave identificadora que consta de dos componentes: w y t. Vamos a definir cuál es el significado de las dos componentes de "wt" y qué valores pueden aparecer en este lugar y su significado. La comprensión se facilita si tenemos en cuenta que r proviene de read, w proviene de write y a proviene de append.

El primer componente puede ir acompañado de un símbolo +, por ejemplo r+. El símbolo + indica que se permite la lectura y la escritura. Por ejemplo r+ indica apertura de un archivo existente para lectura o escritura, w+ indica creación de un nuevo archivo para lectura o escritura y a+ indica apertura de un archivo para lectura o escritura al final.

El segundo componente indica el tipo de archivo que se abre.

EJERCICIO

En un programa escrito en C nos hemos encontrado esta línea:

fichero = fopen("cursoAF1.txt", "wt");

En otro programa nos hemos encontrado esta otra línea:

fichero = fopen("cursoAF2.txt", "rt");

Responde a estas preguntas:

a) ¿Manejan ambos programas el mismo tipo de archivo? ¿Por qué?

b) ¿Qué ocurrirá en cada programa si el archivo no existe?

c) ¿Con qué fin se abren los archivos en cada programa?

Para comprobar si tus respuestas son correctas puedes consultar en los foros aprenderaprogramar.com.

Para acceder a la información general sobre este curso y al listado completo de entregas pulsa en este link: Ver curso completo.

Para hacer un comentario o consulta utiliza los foros aprenderaprogramar.com, abiertos a cualquier persona independientemente de su nivel de conocimiento.

# data[].attributes.attachment_link.title
Leer y escribir archivos o ficheros en C. fopen, fclose, modos de acceso read, write y append (CU00536F)

# data[].attributes.attachment_link.description
Entrega nº36 del curso básico de programación en lenguaje C desde cero. Guardar datos a un disco o recuperar los datos previamente guardados son procesos fundamentales en cualquier programa informático. Para manipular información de un fichero, por ejemplo guardar datos en él o leer datos desde él, lo abrimos con fopen y lo cerramos con fclose.

# data[].attributes.attachment_link.title
Cap. 7 - Archivos en C - Organización y Accesos (2)

# data[].attributes.attachment_link.title
Resumen Funciones para manejo de Archivos

# data[].attributes.attachment_link.description
You can't perform that action at this time. You signed in with another tab or window. You signed out in another tab or window. Reload to refresh your session. Reload to refresh your session.

# data[].attributes.attachment_link.readable_text
/*
Nombre de archivo: hw3.c (No cambiar el nombre de este archivo)
El repositorio donde esta tu HW3 es: github.com/unlu-edu-ar/prog1-2022-hw-3-TuNombreDeUsuarioGithub
Importante: No cambiar el nombre del archivo

Completa con tu nombre, apellido y DNI
Nombre y Apellido:Lucia Vanini
DNI: 44242654
*/
 
 /* 
 Se disponen de archivos de texto, donde se guardan los datos del clima. 
 Cada linea de un archivo de clima se corresponde a un dia del anio. 
 Los datos en cada linea estan separados por tabuladores (a los archivos de texto 
 que tienen los datos separados por tabuladores, se los acostumbra guardar con 
 la extension .tsv, que viene del ingles tab separated values).
 Los datos guardados en cada linea son numeros enteros, y estan en el siguiente orden:
 - dia
 - mes
 - anio 
 - cantidad de lluvia caida 
 - temperatura minima
 - temperatura maxima

 Nota: para evitar errores de incompatilidades, no hemos puesto tildes, ni caracteres
 propios del lenguaje castellano.
 */

#include <stdio.h>

/* 
Programe una funcion que recibe los datos de un archivo de clima, y un mes, 
y devuelva cuantos dias hubo sin lluvias en ese mes.
INPUT: fp (puntero a archivo), mes (int)
OUTPUT: sin_lluvias (int)
*/

int sin_lluvias(FILE* fp, int mes){ 
	fp = fopen("datos_lluvia_temp.tsv","r");  //fp el puntero al archivo= abro(nombre del arch, modo lectura(read))
		if (fp == NULL){   //valido si el puntero de abrio de forma adecuada 
			printf ("ERROR");
			return 1;
		}
		int lluviasino, mesarch,dia,anio, temp1, temp2;
		int contador = 0;
		while (feof(fp)==0){ /*mientras que no sea  el final del archiv cuando llega al final da -11*/
			fscanf(fp,"%d%d%d%d%d%d",&dia, &mesarch,&anio, &lluviasino, &temp1, &temp2);
			if (mesarch == mes && lluviasino == 0){
				contador = contador +1;
			}
		}
	fclose(fp); //cierro el archivo 
	return contador;
}

/* 
Programe una funcion que recibe los datos de un archivo de clima, y devuelva cuantos dias 
llovio menos de x mm, y cuantos dias llovio x mm o mas que x mm, en el anio.
INPUT: fp (puntero a archivo), x (int), lluvias_menor_x (int*), lluvias_mayorigual_x (int*)  
OUTPUT: void
*/

void llovio_umbral(FILE* fp, int x, int* lluvias_menor_x, int* lluvias_mayorigual_x){ 
		fp = fopen("datos_lluvia_temp.tsv","r");  //fp el puntero al archivo= abro(nombre del arch, modo lectura(read)
		rewind(fp);
		int lluviasino, mesarch, day, anio, temp1, temp2;
		int lluvias_menor = 0;
		int lluvias_mayor = 0;
		fscanf(fp,"%d%d%d%d%d%d",&day, &mesarch, &anio, &lluviasino, &temp1, &temp2);
		while (feof(fp)== 0){ /*mientras que no sea  el final del archivo*/
				if (lluviasino>= x){
					lluvias_mayor++;
					*lluvias_mayorigual_x = lluvias_mayor;
				}
				else{
					lluvias_menor ++;
					*lluvias_menor_x = lluvias_menor;
				}
				fscanf(fp,"%d%d%d%d%d%d",&day, &mesarch, &anio, &lluviasino, &temp1, &temp2);
		}
		fclose(fp); //cierro archivo
}

	

/* 
Programe una funcion que recibe los datos de un archivo de clima, y un mes, y
devuelva cuantos dias se registro la maxima temperatura del mes. 
INPUT: fp (puntero a archivo), mes (int)
OUTPUT: cant_dias_maximo_calor (int) 
*/

int contador_dias_maximo_calor(FILE* fp, int mes){ 
	fp = fopen("datos_lluvia_temp.tsv", "r");
	rewind(fp);
	int contador = 0;
	int contador_max = 0;
	int temperatura_maxima;
	int dia, es_mes, anio, cant_lluvia, temp_min, temp_max;
	fscanf(fp, "%i %i %i %i %i %i", &dia, &es_mes, &anio, &cant_lluvia, &temp_min, &temp_max);
	while(feof(fp) == 0){
		fscanf(fp, "%i %i %i %i %i %i", &dia, &es_mes, &anio, &cant_lluvia, &temp_min, &temp_max);
		if(mes == es_mes){
			if(contador == 0){
				temperatura_maxima = temp_max;
			}
			if(temp_max >= temperatura_maxima){
				temperatura_maxima = temp_max;
			}
			contador++;
		}

	}
	rewind(fp);
	fscanf(fp, "%i %i %i %i %i %i", &dia, &es_mes, &anio, &cant_lluvia, &temp_min, &temp_max);
	while(feof(fp) == 0){
		fscanf(fp, "%i %i %i %i %i %i", &dia, &es_mes, &anio, &cant_lluvia, &temp_min, &temp_max);
		if(mes == es_mes){
			if(temp_max == temperatura_maxima){
				contador_max++;
			}
		}
	}
	return contador_max;
	fclose(fp);
}

/* 
Programe una funcion que recibe los datos de un archivo de clima, y un mes, y
devuelva el dia donde se registro la minima temperatura del mes y cual fue dicha temperatura. 
En el caso de haber varios dias con temperatura minima, debe devolver el primer dia.
INPUT: fp (puntero a archivo), mes (int), dia (int*), temp_minima (int*)  
OUTPUT: void
*/

void dia_mas_frio_mes(FILE* fp, int mes, int* dia, int* temp_minima){ 
	fp = fopen("datos_lluvia_temp.tsv","r");  //fp el puntero al archivo= abro(nombre del arch, modo lectura(read)
		int lluviasino, mesarch, day, anio, temp1, temp2;
		int v = 1;
		int menor = 99;
		fscanf(fp,"%d%d%d%d%d%d",&day, &mesarch, &anio, &lluviasino, &temp1, &temp2);
		while (!feof(fp) && v == 1){ /*mientras que no sea  el final del archivo*/
			if (mesarch == mes){
				while (!feof(fp) && mesarch == mes && v == 1){
					if (temp1 < menor){
						menor = temp1;
						*temp_minima = temp1;
						*dia = day;
					}
					fscanf(fp,"%d%d%d%d%d%d",&day, &mesarch, &anio, &lluviasino, &temp1, &temp2);
				}
				v = 0;
			}
			if (v==1){
				fscanf(fp,"%d%d%d%d%d%d",&day, &mesarch, &anio, &lluviasino, &temp1, &temp2);
			}		
		}
		fclose(fp); //cierro archivo
}


/* 
Programe una funcion que recibe los datos de un archivo de clima, y un mes, y
devuelva el promedio de lluvias de dicho mes. 
INPUT: fp (puntero a archivo), mes (int) 
OUTPUT: promedio_lluvia (float) 
*/

float promedio_lluvias_mes(FILE* fp, int mes){ 
	fp = fopen("datos_lluvia_temp.tsv","r");  //fp el puntero al archivo= abro(nombre del arch, modo lectura(read))
		if (fp == NULL){   //valido si el puntero de abrio de forma adecuada 
			printf ("ERROR");
			return 1;
		}
		int lluviasino, mesarch, dia, anio, temp1, temp2;
		int totalmm = 0;
		int totaldias = 0;
		float promedio;
		while (feof(fp)== 0){
			fscanf (fp, "%d%d%d%d%d%d",&dia, &mesarch, &anio, &lluviasino, &temp1, &temp2 ); //leo todos los datos 
			if (mesarch == mes){
				totalmm = totalmm + lluviasino;
				totaldias = totaldias + 1;
			}
		}	
		promedio = totalmm / totaldias;
		fclose(fp);
		return promedio;
}

# data[].attributes.attachment_link.title
La Función fflush en C - Curso de Lenguaje C
de Carlos Pes

# data[].attributes.attachment_link.description
Explicación de qué es y para qué se puede utilizar la función fflush en un programa escrito en lenguaje C.

# data[].attributes.attachment_link.title
Referencia: C - strlen - AprendeAProgramar.com

# data[].attributes.attachment_link.readable_text
Cuando hablamos de cadenas de caracteres es importante resaltar cuales son las funciones que se utilizan para manejar este tipo de datos. En este artículo analizaremos las funciones básicas para entrada y salida de una cadena de caracteres.

gets: Función que se encarga de leer y almacenar una cadena de caracteres introducida mediante el teclado. La variable es guardada hasta que haya un salto de línea ("\n"), sin embargo, el salto de línea NO se guarda. La función gets en C automáticamente agrega un carácter de terminación NULL ("\0"); además es capaz de guardar cualquier tipo de caracter, incluido los espacios en blanco y no tiene ninguna limitante en cuanto al tamaño de la cadena de caracter que se introduce. Para poder utilizar esta función es necesario incluir la librería " string.h ". La sintaxis para utilizar la función es la siguiente:

fgets: Función que se encarga de leer o almacenar una cadena de caracteres introducida mediante el teclado. La variable es guardada hasta que haya un salto de línea ("\n"), el salto de línea SI se guarda. La función fgets automáticamente agrega un carácter de terminación NULL ("\0"); además es capaz de guardar cualquier tipo de caracter, incluido los espacios en blanco, pero SI tiene limitante en cuanto al tamaño de la cadena de caracter que se introduce. Para poder utilizar esta función es necesario incluir la librería "string.h". La sintaxis para utilizar la función es la siguiente:

Donde:

nombre_cadena: Es el nombre de nuestra variable donde queremos almacenar la cadena de caracteres.

numero_caracteres: El la cantidad de caracteres que queremos aceptar en nuestra variable.

FILE: Hace referencia a la fuente de donde obtendremos la variable, puede ser un archivo externo, pero en nuestro caso, como queremos manejar cadenas de caracteres introducidas mediante el teclado, debemos indicarle con la palabra "stdin" cuyo significado es "standard input".

Por ejemplo, si queremos guardar una cadena de caracteres con el nombre "palabra", que tenga un máximo de 25 caracteres, y que la fuente provenga de lo que introduzca el usuario, la sintaxis seria la siguiente:
puts: Función que se encarga de mostrar (Dato de salida) una cadena de caracteres especifica. Es el equivalente al " printf", sin embargo, por cuestiones de seguridad es recomendado utilizar puts para el uso de cadena de caracteres ( string). Para poder utilizar esta función es necesario incluir la librería " string.h ". La sintaxis para utilizar la función es la siguiente:

Diferencia entre gets y fgets: La diferencia entre la función gets y fgets es que la función gets no tiene ninguna limitante en cuanto al tamaño de la cadena de caracter que se guarda, mientras que la función fgets si tiene un numero de caracteres limite aceptados y establecidos por el programador. La función fgets también tiene como diferencia que sí guarda el salto de línea "\n", mientras que la función gets no. fgets es una función más segura, pues al tener una cantidad de caracteres limitado, se previene un desbordamiento de búfer ( buffer overflow), que los datos se sobrescriban en partes de memoria que no se desee y perder información de variables.

Diferencia entre scanf y gets: La diferencia es que scanf no puede guardar un espacio en blanco como cadena de caracteres, por ejemplo, si intentas guardar "Comprar artículo" no podrás porque scanf detecta el espacio como señal de fin de cadena, solo guardaría "Comprar", en cambio, gets si guarda el espacio también y lo incluye como parte de la cadena. Por lo tanto, gets se utiliza solo para guardar datos tipo string (cadenas de caracteres), y scanf para el resto, por ejemplo valores numéricos.

Declarar librería string: Como hemos comentado, para utilizar gets, fgets y puts es necesario declarar la librería string.h, la sintaxis para hacerlo es la siguiente:

Ejercicio 1: Realizar un programa donde el usuario pueda ingresar una cadena de caracteres (limitado a 20 caracteres) y posteriormente mostrarlo, utilizar función "gets".

Ejercicio 2: Realizar un programa donde el usuario pueda ingresar una cadena de caracteres (limitado a 20 caracteres) y posteriormente mostrarlo, utilizar función "fgets".

Ejercicio 1: Como podemos observar, al utilizar la función gets no pone ninguna limitante en cuanto a la cantidad de caracteres que puede guardar, permitiendo así guardar y mostrar una cadena de más de 20 caracteres, incluso aunque la capacidad de nuestra variable sea 20 caracteres, por lo tanto, podemos decir que es un error.

Ejercicio 2: En este caso, al utilizar la función fgets y decirle que la cantidad máxima es 20 caracteres, al intentar guardar una cadena de más de 20 caracteres no lo permite, y solo guarda los primeros 20 caracteres. En este ejemplo no hay ningún error, por lo tanto, concluimos que la mejor forma guardar cadenas de caracteres es con fgets.

Saber la diferencia entre las distintas funciones para manejar cadenas de caracteres es algo muy importante a la hora de programar. Si no hacemos el uso correcto de las funciones y respetamos las limitantes con las cuales fueron creadas podríamos crear un error de programación e inclusive hacer vulnerable nuestro programa ante ataques de seguridad. En este artículo analizamos que es una función gets, fgets y puts, además de analizar sus diferencias y en que situaciones debemos utilizarlas.

# data[].attributes.attachment_link.title
Función gets, fgets y puts - Programación en C

# data[].attributes.attachment_link.description
Cuando hablamos de cadenas de caracteres es importante resaltar cuales son las funciones que se utilizan para manejar este tipo de datos. En este artículo analizaremos las funciones básicas para entrada y salida de una cadena de caracteres. gets : Función que se encarga de leer y almacenar una cadena de caracteres introducida mediante el teclado.

# data[].attributes.attachment_link.title
Corte de Control Y Actualización de Archivos

# data[].attributes.attachment_link.readable_text
// Se cuenta con un archivo de texto “movi.txt”  que contiene un conjunto de facturas y la cantidad de artículos vendidos en cada una de ellas. 
// Se encuentra ordenado por número de factura. 
// archivo “movi.txt”  
// Nro. de factura 
// Código de artículo (1001 – 2000) 
// Cantidad vendida  
// Además, en el archivo “produ.dat” , se encuentra almacenado el código (clave primaria), el precio unitario de cada artículo y el stock actual.  
// archivo “produ.dat”  
// - Cód. Artículo…..integer 
// - Precio…………...real 
// - Stock…………....integer 
// Realizar los procedimientos y/o funciones necesarios para:  
// 1-Crear los dos archivos.
// 2-Imprimir un listado que contenga: Nro. de factura (una sola vez por factura), los artículos vendidos para cada factura, la cantidad, 
// el precio unitario y el precio total de cada artículo y el monto total de la factura. Se deben realizar pausas cada vez que sea necesario. 
// 3-Con los datos de “movi.txt” actualizar el stock productos.dat”. 
 //NOTAS:
// El archivo binario se encuentra ordenado eficientemente y posee datos válidos desde el registro 1
// (el registro ubicado en la posición 1 del archivo corresponde al producto cuyo código es 1001).
// El archivo “movi.txt” puede leerse una única vez en todo el programa.
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <time.h>

typedef struct
{
    int codigo_articulo;
    float precio;
    int stock;
} t_producto;


void crear_archivo_movi(int count){
    FILE * fp = fopen("movi.txt", "w");
    for (int i = 0; i < count; i++)
    {
        int codigo_articulo =  (rand() % 20) + 1001;
        int cantidad_vendida = rand() % 30;
        fprintf(fp, "%i %i %i\n", i, codigo_articulo, cantidad_vendida);
    }
    fclose(fp);
}

void crear_archivo_producto(int count){
    FILE * fp = fopen("produ.dat", "wb");
    t_producto producto;
    for (int i = 0; i < count; i++)
    {
        producto.codigo_articulo = i + 1001;
        producto.precio = (rand() % 1000) + 100;
        producto.stock = rand() % 1000;
        fwrite(&producto, sizeof(t_producto), 1, fp);
    }
    
    fclose(fp);
}

float obtener_precio(int codigo_articulo){
    FILE * fp = fopen("produ.dat", "rb");
    int posicion = codigo_articulo - 1000 - 1;
    fseek(fp, posicion * sizeof(t_producto), SEEK_SET);
    t_producto producto;
    fread(&producto, sizeof(t_producto), 1, fp);
    fclose(fp);
    return producto.precio;
}

void actualizar_stock(int codigo_articulo, int cantidad_vendida){
    FILE * fp = fopen("produ.dat", "r+b");
    int posicion = codigo_articulo - 1000 - 1;
    fseek(fp, posicion * sizeof(t_producto), SEEK_SET);
    t_producto producto;
    fread(&producto, sizeof(t_producto), 1, fp);
    if (producto.stock - cantidad_vendida >= 0)
    {
        producto.stock -= cantidad_vendida;
        fseek(fp, -sizeof(t_producto), SEEK_CUR);
        fwrite(&producto, sizeof(t_producto), 1, fp);
    }
    
    fclose(fp);
}

void imprimir_listado(){
    FILE * fp = fopen("movi.txt", "r");
    int numero_factura;
    int codigo_articulo;
    int cantidad_vendida;
    while (!feof(fp))
    {
       //fprintf(fp, "%i %i %i\n", i, codigo_articulo, cantidad_vendida); 
       fscanf(fp, "%i %i %i\n", &numero_factura, &codigo_articulo, &cantidad_vendida);
       float precio_unitario = obtener_precio(codigo_articulo);
       float precio_total = cantidad_vendida * precio_unitario;
       printf("%i %i %i %2.f %2.f \n", numero_factura, codigo_articulo, cantidad_vendida, precio_unitario, precio_total);
       actualizar_stock(codigo_articulo, cantidad_vendida);
    }
    fclose(fp);
}

void mostrar_productos(){
    FILE * fp = fopen("produ.dat", "rb");
    t_producto producto;
    while (!feof(fp))
    {
        fread(&producto, sizeof(t_producto), 1, fp);
        printf("cod: %i, precio: %2.f, stock: %i \n", producto.codigo_articulo, producto.precio, producto.stock);
    }
    fclose(fp);
}

int main(int argc, char const *argv[])
{
    srand(time(NULL));
    //crear_archivo_movi(20);
    //crear_archivo_producto(20);
    mostrar_productos();
    imprimir_listado();
    mostrar_productos();

    return 0;
}

# data[].attributes.attachment_link.readable_text
Si queremos que nuestros datos perduren en el tiempo no podemos confiar en la RAM, puesto que se borra cuando el fluido eléctrico se detiene. Para hacer que sean permanentes debemos guardarlos en un archivo.

Los archivos son ristras de datos que se guardan en un sistema de archivo dentro de un dispositivo de almacenamiento masivo; disco duro, pendrive, cdrom, dvdrom, cinta magnética, etc.

Los archivos pueden ser de cualquier tipo: fotos, música, películas, hojas de calculo, documentos de texto. Todo depende de que información deseemos guardada en ellos.

Si bien todos los archivos son información binaria, para los efectos de su uso en C reconoceremos dos tipos de archivos, los archivos de texto y los archivos binarios.

Para comenzar a usar un archivo dentro de nuestro programa debemos asignarlo a una variable, en el siguiente listado podemos ver como se hace.

En la línea 8 encuentra la declaración de la variable que usaremos para manipular el archivo, es una variable puntero de tipo FILE.

Haciendo uso de la instrucción le pedimos al sistema operativo que nos localice el archivo nombrado en el primer parámetro, y que lo abra en el modo solicitado en el segundo parámetro. Este archivo esta ubicado en un sistema de archivos *NIX,si el sistema de archivo fuese de Windows el nombre de archivo comenzaría con una unidad, por ejemplo "C:\\archivo".

Modos de apertura de un archivo

El segundo parámetro de indica la forma en que se manipulara el archivo. En el ejemplo anterior en la linea 16 estamos abriendo el archivo para solo leerlo. ¿Que quiere decir? Que el archivo debe existir para poderlo abrir y que no se le añadirá o modificara el contenido actual del archivo.

Las formas de abrir el archivo son estas:

r - abre el archivo en modo de solo lectura.

w - abre el archivo para escritura (si no existe lo crea, si existe lo destruye).

a - abre el archivo para agregar información (si no existe lo crea).

r+ - abre el archivo para lectura/escritura (comienza al principio del archivo).

w+ - abre el archivo para lectura/escritura, sobre-escribe el archivo si este ya existe o lo crea si no).

a+ - abre el archivo para lectura/escritura (se sitúa al final del archivo).

Si vamos a trabajar con archivos binarios usamos la letra b así que los modos de acceso quedan "rb", "wb", "ab", "rb+", "wb+", "ab+".

Luego de trabajar con un archivo lo recomendable es cerrarlo, esto hace que el sistema operativo escriba cualquier dato que pudiera estar en memoria a disco. Como se puede ver en el ejemplo, en la linea 32 la instrucción cierra el archivo. Recibe un parámetro, que es, la variable con la que se maneja el archivo.

Cuando se trabaja con archivos se cuenta con lo que se llama un cursor, un número que indica la posición del archivo en la que nos encontramos. La instrucción regresa el cursor al principio del archivo. Recibe un parámetro, la variable con la que se maneja el archivo.

El cursor de archivo indica el punto a partir del cual se leerán o escribirán datos.

Es posible mover el cursor de archivo haciendo uso de la instrucción que acepta 3 parámetros. El primer parámetro es la variable de archivo, el segundo parámetro es la posición en bytes, y el tercero es uno de estos tres:

SEEK_SET cuenta la posición a partir del principio del archivo.

SEEK_CURRENT cuenta la posición a partir de la posición actual del cursor.

SEEK_END cuenta la posición desde el final del archivo.

¿Como saber si estamos al final de un archivo? La instrucción nos retorna 1 o true si estamos efectivamente al final del archivo. Recibe un solo parámetro, la variable del archivo.

Los archivos de texto son archivos que están conformados por caracteres de texto plano (ASCII, UTF-8, o algún otro tipo de codificación de texto). Estos archivos podemos editarlos con un editor de textos sencillo como notepad en Windows o gedit en Linux.

Los archivos de texto al fin y al cabo son también archivos binarios, pero los tratamos como un tipo de archivo distinto, porque los podemos ver y editar desde un editor de texto.

Leer del archivo de texto

Para leer datos desde un archivo de texto contamos con las siguientes funciones:

permite leer un carácter desde el archivo, recibe un parámetro y es la variable del archivo. Devuelve el carácter leído.

lee cadenas completas desde el archivo, hasta que encuentra un retorno de carro \n o un eof. Acepta tres parámetros el nombre de el arreglo de caracteres donde se va a guardar lo leído, cantidad de bytes a leer y variable de archivo.

funciona de la misma forma que un tradicional pero con un parámetro al principio que indica el archivo a leer.

Escribir en el archivo de texto

escribe un carácter en el archivo, recibe dos parámetros, el carácter a escribir y la variable de archivo.

escribe una cadena en el archivo, recibe dos parámetros, la cadena a escribir, y la variable de archivo.

funciona de la misma forma que pero su primer parámetro es la variable de archivo.

Las anteriores funciones sirven para manejar archivos donde se guardan caracteres. Es decir si queremos guardar el numero 123456 ocupara 6 bytes, o 12 bytes dependiendo de la codificación que estemos usando. En ocasiones esto no es deseable. Queremos guardar la mayor cantidad de información ocupando la menor cantidad de espacio. Usando un formato binario nuestro numero 123456 ocupara ahora 4 bytes (lo que mide un int en C).

Cuando trabajamos en formato binario muy a menudo trabajamos con estructuras, que nos permiten empaquetar un conjunto de datos y tratarlo como si fuese una unidad.

Para escribir en archivos binarios

se usa para escribir datos binarios en un archivo, recibe tres parámetros, el primero es la variable a guardar, el segundo el tamaño de la variable a guardar, el tercero cuantas veces se va a guardar y por ultimo la variable de archivo.

Para leer de un archivo binario

fread() se usa para leer datos binarios de un archivo, recibe tres parámetros, el primero es la variable donde se van a guardar los datos, el segundo el tamaño de la variable a leer, el tercero cuantas veces se va a leer y por ultimo la variable de archivo.

En el siguiente enlace podrán encontrar un proyecto de anjuta con ejemplos para cada proceso.

# data[].attributes.attachment_link.description
Si queremos que nuestros datos perduren en el tiempo no podemos confiar en la RAM, puesto que se borra cuando el fluido eléctrico se detiene. Para hacer que sean permanentes debemos guardarlos en un archivo. Los archivos son ristras de datos que se guardan en un sistema de archivo dentro de un dispositivo de almacenamiento masivo; disco duro, pendrive, cdrom, dvdrom, cinta magnética, etc.

# data[].attributes.attachment_link.readable_text
Una empresa de colectivos tiene organizada su información en los siguientes
vectores:
INTERNOS (vector de registros): datos de las líneas internas de la empresa
de colectivo
RECORRIDOS (vector de enteros): datos de la longitud en km de los recorridos

Los registros del vector INTERNOS tienen la siguiente forma:
Número de interno: Integer (1001 al 3000, consecutivos)
Km recorridos: integer
Dinero recaudado: float

El vector de recorridos (vector de enteros de longitud 10)  contiene la
longitud en Kilómetros de cada uno de los 10 recorridos. El índice del vector
indica el código del recorrido. La longitud en km de los recorridos es
[12,9,13,10,8,7,9,22,11,5]

Se cuenta además con un archivos de texto MENSUAL.TXT con la siguiente información:
Día: Integer (1 al 30)
Número de interno: integer (1001 al 3000)
Código recorrido: integer (del 0 al 9)
Pasajeros transportados: integer
Recaudación: float
El archivo MENSUAL.TXT está agrupado por Número de Interno.

Se pide:

1) Crear las estructuras de datos INTERNOS y RECORRIDOS.
Inicializar el vector RECORRIDOS con los datos de las longitudes en kilómetros
de los recorridos.
Inicializar el vector INTERNOS con los registros correspondientes, donde los
números de interno deben tener numeración consecutiva del 1001 al 3000, y los
kilómetros recorridos y el dinero recaudado deben estar inicializados en forma
random del 10 al 100.

2) Procesar el archivo MENSUAL.TXT, utilizando la técnica de corte de control para:
a) actualizar la recaudación y los kilómetros recorridos del vector INTERNOS
b) Informar por pantalla el recorrido que más recaudó ese mes.

Restricción: El archivo MENSUAL.TXT puede leerse por completo SOLAMENTE UNA VEZ
en todo el programa durante el corte de Control.

Es un error descalificante actualizar cualquiera de los vectores de registros 
por cada lectura del archivo de texto.

# data[].attributes.attachment_link.readable_text
// Una empresa de colectivos tiene organizada su información en los siguientes
// vectores:
// INTERNOS (vector de registros): datos de las líneas internas de la empresa
// de colectivo
// RECORRIDOS (vector de enteros): datos de la longitud en km de los recorridos

// Los registros del vector INTERNOS tienen la siguiente forma:
// Número de interno: Integer (1001 al 3000, consecutivos)
// Km recorridos: integer
// Dinero recaudado: float

// El vector de recorridos (vector de enteros de longitud 10)  contiene la
// longitud en Kilómetros de cada uno de los 10 recorridos. El índice del vector
// indica el código del recorrido. La longitud en km de los recorridos es
// [12,9,13,10,8,7,9,22,11,5]

// Se cuenta además con un archivos de texto MENSUAL.TXT con la siguiente información:
// Día: Integer (1 al 30)
// Número de interno: integer (1001 al 3000)
// Código recorrido: integer (del 0 al 9)
// Pasajeros transportados: integer
// Recaudación: float
// El archivo MENSUAL.TXT está agrupado por Número de Interno.

// Se pide:

// 1) Crear las estructuras de datos INTERNOS y RECORRIDOS.
// Inicializar el vector RECORRIDOS con los datos de las longitudes en kilómetros
// de los recorridos.
// Inicializar el vector INTERNOS con los registros correspondientes, donde los
// números de interno deben tener numeración consecutiva del 1001 al 3000, y los
// kilómetros recorridos y el dinero recaudado deben estar inicializados en forma
// random del 10 al 100.

// 2) Procesar el archivo MENSUAL.TXT, utilizando la técnica de corte de control para:
// a) actualizar la recaudación y los kilómetros recorridos del vector INTERNOS
// b) Informar por pantalla el recorrido que más recaudó ese mes.

// Restricción: El archivo MENSUAL.TXT puede leerse por completo SOLAMENTE UNA VEZ
// en todo el programa durante el corte de Control.

// Es un error descalificante actualizar cualquiera de los vectores de registros
// por cada lectura del archivo de texto.

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <ctype.h>
#define MAX 2000

typedef struct  // 1 Crear estructuras
{
    int num_interno; // 1001 a 3000 consecutivos
    int km_recorr;
    float dinero_recaud;
} t_internos;

typedef t_internos t_tabla_internos[MAX];
void mensual(int * recorridos, t_internos * internos);

int main()
{
    // 1 Inicializar internos y recorridos
    int recorridos[10] = {12, 9, 13, 10, 8, 7, 9, 22, 11, 5};
    t_tabla_internos tabla_internos;
    t_internos interno;
    srand(time(NULL));
    int i;
    for (i = 0; i < MAX; i++)
    {
        interno.num_interno = i  + 1001;
        interno.dinero_recaud = 10 + rand() % 100;
        interno.km_recorr = 10 + rand() % 100;
        tabla_internos[i] = interno;
    }
    // 2 corte de control 
    mensual(recorridos, tabla_internos);
}

// 2) Procesar el archivo MENSUAL.TXT, utilizando la técnica de corte de control para:
// a) actualizar la recaudación y los kilómetros recorridos del vector INTERNOS
// b) Informar por pantalla el recorrido que más recaudó ese mes.

void mensual(int * recorridos, t_internos * internos)
{
    FILE * fp = fopen("MENSUAL.TXT", "r");
    
    int dia;
    int numero_interno;
    int codigo_recorrido;
    int pasajeros_transport;
    float recaudacion;

    float recaudacion_por_recorrido[10] = {0};
    float recaudacion_por_interno[2000] = {0};
    float km_recorridos_por_interno[2000] = {0};

    fscanf(fp, "%i %i %i %i %f\n", &dia, &numero_interno, &codigo_recorrido, &pasajeros_transport, &recaudacion);
    while (!feof(fp))
    {
        int num_ant_intern = numero_interno;
        float suma_recaudacion = 0;
        int suma_km = 0;
        while ((!feof(fp)) && num_ant_intern == numero_interno)
        {
            recaudacion_por_recorrido[codigo_recorrido] += recaudacion;
            suma_recaudacion += recaudacion;
            suma_km = suma_km + recorridos[codigo_recorrido];
            fscanf(fp, "%i %i %i %i %f\n", &dia, &numero_interno, &codigo_recorrido, &pasajeros_transport, &recaudacion);
        }
        recaudacion_por_interno[num_ant_intern - 1001] = suma_recaudacion;
        km_recorridos_por_interno[num_ant_intern - 1001] = suma_km;
    }
    float mayor = recaudacion_por_recorrido[0];
    int indice_mayor = 0;
    for (int i = 1; i < 10; i++)
    {
        if (mayor < recaudacion_por_recorrido[i])
        {
            mayor = recaudacion_por_recorrido[i];
            indice_mayor = i;
        }
        
    }
    printf("El recorrido con mayor recaudación es: %i", indice_mayor); 
    fclose(fp);
    // 2 a) Actualizar internos
    // En caso de que el vector de internos esté en un archivo binario seguir los pasos comentados
    // Abrir el archivo binario
    for (int i = 0; i < 2000; i++)
    {
        // t_internos interno;
        // // Posicionarnos en la posicion donde dice el codigo
        // fseek(fp, sizeof(t_internos)*i, SEEK_SET);
        // fread(&interno, sizeof(t_internos), 1, fp);

        internos[i].km_recorr += km_recorridos_por_interno[i];
        internos[i].dinero_recaud += recaudacion_por_interno[i];

        // // Posicionarnos en la posicion donde dice el codigo
        // fseek(fp, -sizeof(t_internos), SEEK_CUR);
        // // Actualizar el registro en el archivo binario
        // fwrite(&interno, sizeof(t_internos), 1, fp);
    }
    // Cerrar el archivo binario
}

# data[].attributes.attachment_link.readable_text
/*Ejercicio 1*/

void proceso(FILE *fp); //pasaje por referencia

int main(){
    FILE *fp = fopen("sueldos.txt","r")//abro archivo
    proceso(fp);//ejecuto la fucion del corte
}
//CORTE DE CONTROL
void proceso(FILE*fp){ 
    rewind(fp);
    int codigo_sucursal, cod_empleado, sucursal_anterior;
    float salario, salario_total;
    //leo el archivo
    fscanf(fp, "%i,%i,%f", &codigo_sucursal,&cod_empleado,&salario);
    while(!feof(fp)){
        sucursal_anterior = codigo_sucursal;
        salario_total = 0;
        printf("\n\nSUCURSAL %i", sucursal_anterior);
        printf("\n Codigo empleado\t\tSueldo\n");
        while(!feof(fp) && codigo_sucursal == sucursal_anterior){
            printf("%i\t\t\t%.2f\n", cod_empleado,salario);
            salario_total += salario;

        fscanf(fp,"%i,%i,%f", &codigo_sucursal,&cod_empleado,&salario);
        }
        printf("\n Total Sucursal: %.2f", salario_total);
    }
    fclose(fp);
}


/*EJERCICIO 2*/

/*Archivo ordenado por nº de cuenta
Movimientos.txt en el orden:
Nro.cunetas (int)
Movimiento = codi (int)
Importe (float)

Codi es
1= deposito
2 = extraccion

Output: Imprimir lsitado con los
 clientes que hayn tenido movimeintos 
 y saldo neto de dichos movimientos*/


void proceso2(FILE *fp);

int main (){
    FILE *fp= fopen("movimientos.txt", "r");
    proceso2(fp);
}

void proceso2(FILE *fp){
    int nro_cuenta, codi, cuenta_anterior;
    float importe, saldo_neto;

    fscanf(fp,"%i,%i,%f",&nro_cuenta,&codi,&cuenta_anterior);
    while(!feof(fp)){
        cuenta_anterior = nro_cuenta;
        saldo_neto = 0;
        printf("\t\t\t\t INFORME MOVIMIENTOS DE CUENTA CORRIENTE");
        printf("\nNUMERO DE CUENTA \t\t\t SALDO");
        while(!feof(fp) && nro_cuenta == cuenta_anterior){
           printf("\n%i\t\t\t $ %.2f",n_cuenta_ant, saldo_neto);
             if(codi == 1){
                saldo_neto = saldo_neto + importe;
            }
            else if(codi == 2){
                saldo_neto = saldo_neto - importe;
            }
        }
        pritnf("\n SALARIO ACTUAL: %.2f",saldo_neto);
    }
    fclose(fp);
}


/*EJERCICIO 3*/

/*El registro de cada empleado es asi:
Codigo de sucursal(int)
Codigo de departamento (int)
Codigo de empleado (int)
Sueldo mensual (float)

Archivo Sueldos2.txt ordenado por codigo de sucursal
y en cada sucursal por departamento

output: 
*/

void proceso3(FILE *fp);

int main(){
   FILE*fp =fopen("sueldos2.txt","r");
   proceso3(fp);
}

void proceso3(FILE *fp){
    //para leer necesito
    int cod_suc, cod_dpto, cod_emp;
    float sueldo;
    //para trabajar
    int sucursal_anterior, dpto_anterior;
    float total_dpto, total_suc;
    fscanf(fp,"%i,%i,%i,%f",&cod_suc,&cod_dpto,&cod_emp,&sueldo);    
    while(!feof(fp)){
        sucursal_anterior = cod_suc;
        total_suc = 0;
        printf("Sucursal %i",sucursal_anterior);
        while(!feof(fp) && cod_suc == sucursal_anterior){
            dpto_anterior = cod_dpto;
            total_dpto = 0;
            while(!feof(fp) && cod_dpto == dpto_anterior){
             printf("Departamento %i", cod_dpto);
             total_dpto += sueldo;
             fscanf(fp,"%i,%i,%i,%f",&cod_suc,&cod_dpto,&cod_emp,&sueldo);
            }
            total_suc += total_dpto;
            printf("\nTotal Departamento %i\t$%.2f", dpto_anterior,total_dpto);
        }
        printf("\n\nTotal Sucursal %i\t$%.2f",sucursal_anterior,total_suc);
 
    }
    fclose(fp);
}

# data[].attributes.attachment_link.description
Get access to files anywhere through secure cloud storage and file backup for your photos, videos, files and more with Google Drive.

# data[].attributes.attachment_link.readable_text
Tamaño leído // Si se pudieron leer todos los datos.  0 // Se produjo un error, o no se leyeron todos los datos pedidos.
Descripción:
Esta función permite leer datos de un archivo abierto con la función fopen(), a partir de la posición indicada por el puntero de lectura/escritura.

El archivo se debe haber abierto en un modo de lectura, o que la permita.

El puntero se sitúa inicialmente al comienzo del archivo, al abrirse el mismo, y avanza secuencialmente según se vayan leyendo datos. No obstante puede situarse este puntero del archivo en cualquier posición, utilizando la función fseek() y la función ftell() permite obtener la posición actual del puntero de un archivo.

La función fread() requiere como primer parámetro el OFFSET de los datos en los que deben leerse los datos del archivo, es decir, la dirección de memoria a partir de la cual se deben colocar los datos que se vayan leyendo del archivo.

Como segundo parámetro se requiere la longitud o tamaño total de los datos que se quieren leer, es decir, el número de posiciones de memoria que ocupan dichos datos. La longitud de un dato se puede obtener con la
función sizeof().

El último parámetro debe ser el handle o identificador de archivo que se obtuvo al abrir el archivo como valor de retorno de fopen().

int tabla1[4] = {11,22,33,44};int tabla2[4];FILE * mihandle;MAIN_PROGRAM_CDIV BEGIN_PROGRAM     mihandle =fopen("../help.dat","w");fwrite(tabla1, 4, 4, mihandle);fclose(mihandle);     mihandle =fopen("../help.dat","r");fread(tabla2, 4, 4, mihandle); // Lee el archivo sobre tabla2fclose(mihandle);END_PROGRAM

Este programa ejemplo tiene definidas dos tablas globales; tabla1 con cuatro valores inicializados a 11, 22, 33 y 44, y tabla2 con cuatro sin inicializar (a cero).

Se utilizan las funciones de archivos para escribir en un archivo el contenido de la tabla1 y después cargarlo sobre la tabla2. Al finalizar el programa, se habrán copiado los datos de la primera tabla en la segunda.

Se llama a la función fopen() en dos ocasiones, la primera para crearlo y escribir en él, y la segunda para abrirlo y leer su contenido.

Es importante resaltar que cada vez que se abra o cree un archivo, se tiene que cerrar después con la función fclose() (se puede ver como, en el ejemplo, se cierra el archivo en dos ocasiones).

La función inversa a fopen(), es decir, la que permite escribir datos en un archivo en lugar de leerlos, es fwrite(). La forma de utilizar esta función y sus parámetros son idénticos a los de fread().

# data[].attributes.attachment_link.description
Tamaño leído // Si se pudieron leer todos los datos. 0 // Se produjo un error, o no se leyeron todos los datos pedidos. Descripción: Esta función permite leer datos de un archivo abierto con la función fopen(), a partir de la posición indicada por el puntero de lectura/escritura.