Prerrequisitos y Entorno de Ejecución Requerido¶
Para compilar y verificar las soluciones de este módulo bajo el estándar C11 estricto de cátedra, se requiere:
Compilador C11: GCC 9+ o Clang 11+ configurado con flags
-Wall -Wextra -Werror -pedantic -std=c11.Entorno POSIX: Linux o WSL con utilidades estándar, soporte de aserciones deterministas y verificación lógica.
Herramientas de Verificación: Valgrind (memcheck) y AddressSanitizer (
-fsanitize=address,undefined) para auditar la integridad de acumuladores y descartar lazos infinitos o desbordamientos aritméticos.Conocimientos Previos: Operadores relacionales (
<,<=,>,>=,==,!=), operadores lógicos con cortocircuito (&&,||,!), bifurcacionesif/switchy lazos estructuradosfor/while/do-while.
Objetivos Pedagógicos y Competencias (Taxonomía de Bloom)¶
Nivel 2 (Comprensión): Analizar diagramas de flujo, tablas de verdad booleanas, orden de precedencia y evaluación por cortocircuito.
Nivel 3 (Aplicación): Implementar algoritmos de clasificación condicional, iteraciones deterministas acotadas e invariantes de terminación en C11.
Nivel 4 (Análisis): Evaluar equivalencia formal entre estructuras de control iterativas y refactorizar código eliminando sentencias prohibidas (
break,continue,goto).Nivel 5 (Evaluación): Demostrar la corrección de algoritmos iterativos mediante matrices de vectores de prueba y suites ejecutables con
assert().Andamiaje Progresivo: Ejercicios andamiados con contratos formales (precondiciones/postcondiciones), tablas de vectores de prueba y suites ejecutables con
assert().
Capítulos de Apunte Correspondientes¶
Cuestiones de Estilo Aplicables¶
Desacoplamiento de E/S: De acuerdo con la 0x2002h: Las funciones no deben contener printf o scanf, a menos que ese sea su propósito explícito, las funciones de cálculo no deben contener
printfniscanf.Prohibición de saltos auxiliares: Según la 0x2001h: Las funciones deben usar cláusulas de guarda y retornos anticipados para reducir la anidación profunda, está prohibido el uso de
break,continueogotopara el control de lazos.Uso estricto de llaves: Toda estructura condicional e iterativa debe delimitar su bloque con llaves
{}alineadas.
Estructuras Condicionales¶
Ejercicio 1.03b.01 - Condición de Aprobación ⭐⭐☆☆☆¶
```c #include <stdio.h> #include <string.h> #include <assert.h> const char *evaluar_condicion_aprobacion(int nota) { if (nota >= 6) { return "Promociona"; } else if (nota >= 4) { return "Aprueba"; } else { return "Desaprueba"; } } int main(void) { assert(strcmp(evaluar_condicion_aprobacion(10), "Promociona") == 0); assert(strcmp(evaluar_condicion_aprobacion(6), "Promociona") == 0); assert(strcmp(evaluar_condicion_aprobacion(5), "Aprueba") == 0); assert(strcmp(evaluar_condicion_aprobacion(4), "Aprueba") == 0); assert(strcmp(evaluar_condicion_aprobacion(3), "Desaprueba") == 0); assert(strcmp(evaluar_condicion_aprobacion(0), "Desaprueba") == 0); return 0; } ```
---
## Estructuras de Repetición (Lazos)
(ej_b1_c03b_02)=
### Ejercicio 1.03b.02 - Cuenta descendente ⭐⭐☆☆☆
:::{exercise}
:label: lazo_while
:enumerator: while-1
Implementá una función `void cuenta_descendente(int inicio, int fin, int *salida, size_t cap)` que genere la secuencia decreciente desde `inicio` hasta `fin` paso unitario en el arreglo `salida`.
**Nivel de Bloom:** Nivel 3 (Aplicación).
**Conceptos requeridos:** Lazo `while`, condición de corte (`i >= fin`), decremento ordenado y límites de arreglo.
**Techo conceptual:** Prohibido el uso de lazos infinitos con `break`.
#### Contrato de la Función
- **Firma:** `size_t cuenta_descendente(int inicio, int fin, int *salida, size_t cap);`
- **Precondiciones:** `salida != NULL`, `cap >= (size_t)(inicio - fin + 1)` cuando `inicio >= fin`.
#### Tabla de Vectores de Prueba Obligatorios
| Caso de Prueba | Entrada (`inicio`, `fin`) | Capacidad | Elementos Generados | Secuencia Resultante | Justificación Técnica |
| :--- | :--- | :--- | :--- | :--- | :--- |
| **Cuenta Estándar** | `10, 1` | `10` | `10` | `[10, 9, ..., 1]` | 10 iteraciones decrecientes |
| **Paso Unitario** | `5, 5` | `1` | `1` | `[5]` | Caso base inicio igual a fin |
| **Rango Invertido** | `1, 5` | `5` | `0` | `[]` | Condición falsa inmediata |
(ej_b1_c03b_03)=
### Ejercicio 1.03b.03 - Múltiplos de 3 ⭐⭐☆☆☆
:::{exercise}
:label: lazo_for
:enumerator: for-1
Usá un lazo `for` para mostrar o recolectar los números múltiplos de 3 comprendidos en el rango de 0 a `limite` inclusive dentro de un arreglo.
**Nivel de Bloom:** Nivel 3 (Aplicación).
**Conceptos requeridos:** Lazo `for`, operador módulo (`%`), incremento de contador y comprobación de divisibilidad.
**Techo conceptual:** Prohibido el uso de lazos `while` o saltos incondicionales.
#### Contrato de la Función
- **Firma:** `size_t recolectar_multiplos_tres(int limite, int *salida, size_t cap);`
- **Precondiciones:** `salida != NULL`, `limite >= 0`.
- **Postcondiciones:** Almacena los múltiplos de 3 en `[0, limite]` dentro de `salida` sin desbordar `cap` y retorna la cantidad de elementos almacenados.
#### Tabla de Vectores de Prueba Obligatorios
| Caso de Prueba | Límite Máximo | Capacidad Buffer | Cantidad Retornada | Secuencia Almacenada | Justificación Técnica |
| :--- | :--- | :--- | :--- | :--- | :--- |
| **Rango Regular 30** | `30` | `15` | `11` | `[0, 3, 6, ..., 30]` | 11 múltiplos en $[0, 30]$ |
| **Límite Cero** | `0` | `5` | `1` | `[0]` | $0$ es divisible por 3 |
| **Límite No Múltiplo**| `8` | `5` | `3` | `[0, 3, 6]` | Múltiplos menores a 8 |
| **Capacidad Insuficiente** | `30` | `3` | `3` | `[0, 3, 6]` | Truncamiento seguro por cota `cap` |
Ejercicio 1.03b.04 - Verificación de Clave con Límite de Intentos ⭐⭐☆☆☆¶
```c #include <stdio.h> #include <stdbool.h> #include <assert.h> bool verificar_clave_intentos(const int *intentos, size_t n, int clave_secreta) { if (intentos == NULL || n == 0) { return false; } size_t i = 0; bool concedido = false; do { if (intentos[i] == clave_secreta) { concedido = true; } i++; } while (i < n && !concedido); return concedido; } int main(void) { int intentos_ok[] = {1111, 2222, 1234}; assert(verificar_clave_intentos(intentos_ok, 3, 1234)); int inmediato[] = {1234}; assert(verificar_clave_intentos(inmediato, 1, 1234)); int fallidos[] = {9999, 8888, 7777}; assert(!verificar_clave_intentos(fallidos, 3, 1234)); assert(!verificar_clave_intentos(NULL, 0, 1234)); return 0; } ```
---
## Control de Flujo Seguro
(ej_b1_c03b_05)=
### Ejercicio 1.03b.05 - Refactorización de break ⭐⭐☆☆☆
:::{exercise}
:label: lazo_break
:enumerator: break-1
Modificá el siguiente programa para eliminar la instrucción `break` prohibida por las normas de estilo institucionales ({ref}`0x2001h`), estructurando correctamente la iteración mediante una bandera booleana:
```{code-block} c
:linenos:
#include <stdio.h>
int main()
{
int i;
for (i = 0; i < 10; i++)
{
printf("valor actual: %d\n", i);
if (i == 4)
{
break;
}
}
return 0;
}
```
<!-- {code-block} c -->
**Nivel de Bloom:** Nivel 3 (Aplicación) y Nivel 4 (Análisis).
**Conceptos requeridos:** Control de flujo estructurado, variables booleanas (`<stdbool.h>`), condición compuesta de lazo.
**Techo conceptual:** Prohibido el uso de `break`, `continue` o `goto`.
Solution to lazo_break #
Se reestructura el lazo reemplazando el for e implementando un lazo while
controlado por una bandera lógica booleana (bool) del encabezado <stdbool.h>
que se establece en false al alcanzar la condición de parada:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17#include <stdbool.h> #include <stdio.h> int main(void) { int i = 0; bool continuar = true; while (i < 10 && continuar) { printf("valor actual: %d\n", i); if (i == 4) { continuar = false; } i++; } return 0; }
Ejercicio 1.03b.06 - Refactorización de continue ⭐⭐☆☆☆¶
Solution to Exercise continue-1 #
Se reestructura el lazo de forma segura eliminando la instrucción continue y
encerrando el cuerpo restante del lazo dentro de una condición positiva que
filtra los elementos que se desean procesar (en este caso, los impares):
1 2 3 4 5 6 7 8 9 10 11 12#include <stdio.h> int main(void) { for (int i = 0; i <= 10; i++) { if (i % 2 != 0) { printf("i = %d\n", i); } } return 0; }
Ejercicio 1.03b.07 - Lazo de Clave con Bandera y Timeout ⭐⭐☆☆☆¶
---
(ejercicio_4_8)=
## Ejercicios de Práctica de Control
(ej_b1_c03b_08)=
### Ejercicio 1.03b.08 - Mayor de dos números reales ⭐⭐☆☆☆
Escribí un programa que solicite dos números reales al usuario y muestre cuál es
el mayor.
:::{hint} Lógica y ConsideracionesEjercicio 1.03b.09 - Números del 1 al 100 ⭐⭐☆☆☆¶
Diseñá un programa que imprima en pantalla los números enteros del 1 al 100
utilizando un lazo for.
Ejercicio 1.03b.10 - Suma de pares del 1 al 100 ⭐⭐☆☆☆¶
Desarrollá un algoritmo que sume los números pares comprendidos en el rango del 1 al 100 inclusive.
Ejercicio 1.03b.11 - Verificación de número primo ⭐⭐☆☆☆¶
Escribí un programa que solicite un número entero positivo e indique si es un número primo (divisible únicamente por 1 y por sí mismo).
Ejercicio 1.03b.12 - Estado de aprobación de calificación ⭐⭐⭐☆☆¶
Escribí un programa que pida una calificación (0 a 10) e indique si el estudiante aprobó (calificación mayor o igual a 4).
Ejercicio 1.03b.13 - Contraseña de caracteres iterativa ⭐⭐☆☆☆¶
Escribí un programa que solicite repetidamente una contraseña de caracteres al usuario hasta que coincida con un valor establecido de acceso seguro.
Ejercicio 1.03b.14 - Contar del 1 al 10 ⭐☆☆☆☆¶
Mostrá los números del 1 al 10 usando un lazo for.
Orientación:
for (int i = 1; i <= 10; i++)Imprimí cada número en una línea
Ejercicio 1.03b.15 - Suma de N Números ⭐☆☆☆☆¶
Leé un número N y calculá la suma de los primeros N números naturales.
Orientación:
Usá lazo
forde 1 a NAcumulá la suma en una variable
Alternativa: fórmula directa suma = N × (N+1) / 2
Ejercicio 1.03b.16 - Tabla de Multiplicar ⭐⭐☆☆☆¶
Mostrá la tabla de multiplicar de un número ingresado por el usuario (1 a 10).
Orientación:
Leé el número
Lazo de 1 a 10:
printf("%d x %d = %d\n", num, i, num * i);
Ejercicio 1.03b.17 - Factorial con While ⭐⭐☆☆☆¶
Calculá el factorial de N usando un lazo while.
Orientación:
Inicializá resultado = 1, contador = N
Mientras contador > 0: resultado *= contador, contador--
Manejá caso especial: 0! = 1
Ejercicio 1.03b.18 - Números Pares en Rango ⭐⭐☆☆☆¶
Mostrá todos los números pares entre dos valores ingresados.
Orientación:
Leé inicio y fin
Lazo de inicio a fin
Usá
if (i % 2 == 0)para detectar paresAlternativa:
for (i = inicio; i <= fin; i += 2)empezando en par
Ejercicio 1.03b.19 - Suma hasta Cero ⭐⭐☆☆☆¶
Leé números enteros hasta que el usuario ingrese 0, luego mostrá la suma total.
Orientación:
Usá
while (true)odo-whileLeé número
Si es 0,
breakCaso contrario, sumá al acumulador
Ejercicio 1.03b.20 - Validación de Entrada ⭐⭐⭐☆☆¶
Leé un número entre 1 y 100. Si está fuera de rango, pedí nuevamente hasta que sea válido.
Orientación:
do-whilees ideal aquído { leer numero } while (numero < 1 || numero > 100);Mostrá mensaje de error en cada intento inválido
Ejercicio 1.03b.21 - Contar Dígitos ⭐⭐⭐☆☆¶
Contá cuántos dígitos tiene un número entero.
Orientación:
Usá lazo
while (n > 0)Dividí por 10 en cada iteración:
n /= 10Incrementá contador
Caso especial: 0 tiene 1 dígito
Ejercicio 1.03b.22 - Número Primo ⭐⭐⭐☆☆¶
Determiná si un número es primo probando divisibilidad.
Orientación:
Si N <= 1: no primo
Si N = 2: primo
Probá divisores de 2 a √N
Si alguno divide exacto: no primo
Optimización: después del 2, probar solo impares
Ejercicio 1.03b.23 - Secuencia de Fibonacci ⭐⭐⭐☆☆¶
Generá los primeros N números de Fibonacci.
Orientación:
Inicializá
a = 0, b = 1Lazo N veces:
Mostrá
aCalculá siguiente:
temp = a + b; a = b; b = temp
Ejercicio 1.03b.24 - Búsqueda en Array ⭐⭐⭐☆☆¶
Buscá un valor en un array. Si lo encontrás, mostrá su posición y break.
Orientación:
Recorré array con
forCompará cada elemento con el buscado
Si coincide: guardá índice,
breakDespués del lazo: verificá si se encontró
Ejercicio 1.03b.25 - Validador de Fechas Gregorianas y Regla de Bisiestos ⭐⭐⭐☆☆¶
Solution to Exercise 2
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64#include <stdbool.h> #include <assert.h> bool es_bisiesto(int anio) { if (anio <= 0) { return false; } return (anio % 4 == 0 && (anio % 100 != 0 || anio % 400 == 0)); } bool fecha_es_valida(int dia, int mes, int anio) { if (anio < 1 || mes < 1 || mes > 12 || dia < 1) { return false; } int dias_mes = 31; switch (mes) { case 2: dias_mes = es_bisiesto(anio) ? 29 : 28; break; case 4: case 6: case 9: case 11: dias_mes = 30; break; default: dias_mes = 31; break; } return (dia <= dias_mes); } int main(void) { /* Pruebas de bisiestos */ assert(es_bisiesto(2024) == true); assert(es_bisiesto(1900) == false); assert(es_bisiesto(2000) == true); assert(es_bisiesto(2023) == false); /* Fechas válidas */ assert(fecha_es_valida(29, 2, 2024) == true); assert(fecha_es_valida(29, 2, 2000) == true); assert(fecha_es_valida(31, 12, 2023) == true); assert(fecha_es_valida(30, 4, 2023) == true); /* Fechas inválidas */ assert(fecha_es_valida(29, 2, 1900) == false); assert(fecha_es_valida(29, 2, 2023) == false); assert(fecha_es_valida(31, 4, 2023) == false); assert(fecha_es_valida(0, 5, 2023) == false); assert(fecha_es_valida(15, 13, 2023) == false); assert(fecha_es_valida(15, 5, 0) == false); return 0; }
Ejercicio 1.03b.26 - Mayor y Menor de N Números ⭐⭐⭐☆☆¶
Leé N números y encontrá el mayor y menor.
Orientación:
Inicializá
mayorymenorcon el primer númeroLazo desde el segundo número:
Si actual > mayor: actualizar mayor
Si actual < menor: actualizar menor
Ejercicio 1.03b.27 - Invertir un Número ⭐⭐⭐⭐☆¶
Invertí los dígitos de un número (ej: 1234 → 4321).
Orientación:
invertido = 0Mientras n > 0:
digito = n % 10invertido = invertido * 10 + digiton /= 10
Ejercicio 1.03b.28 - Números Perfectos ⭐⭐⭐⭐☆¶
Encontrá todos los números perfectos hasta N. Un número es perfecto si la suma de sus divisores (excluyéndolo) es igual al número.
Ejemplo: 6 = 1 + 2 + 3
Orientación:
Lazo externo: de 1 a N
Lazo interno: encontrar divisores de 2 a n/2
Sumá divisores
Si suma == número: es perfecto
Ejercicio 1.03b.29 - Patrón de Asteriscos - Triángulo ⭐⭐⭐⭐☆¶
Dibujá un triángulo de asteriscos de altura N.
Ejemplo (N=5):
*
**
***
****
*****Orientación:
Lazo externo: filas (1 a N)
Lazo interno: columnas (1 a fila_actual)
Imprimí asterisco en cada columna
Nueva línea después de cada fila
Ejercicio 1.03b.30 - Máximo Común Divisor (Euclides) ⭐⭐⭐⭐☆¶
Implementá el algoritmo de Euclides iterativo para calcular MCD.
Algoritmo:
mientras b != 0:
temp = b
b = a % b
a = temp
retornar aOrientación:
Usá lazo
while (b != 0)Guardá resto en variable temporal
Intercambiá valores
Ejercicio 1.03b.31 - Número de Armstrong ⭐⭐⭐⭐☆¶
Determiná si un número es Armstrong (suma de sus dígitos elevados a la cantidad de dígitos igual al número).
Ejemplo: 153 = 1³ + 5³ + 3³ = 153
Orientación:
Primer lazo: contar dígitos
Segundo lazo: sumar dígitos elevados a esa potencia
Comparar suma con número original
Usá
pow()de<math.h>
Ejercicio 1.03b.32 - Simulación de Cajero Automático ⭐⭐⭐⭐⭐¶
Simulá un cajero con saldo inicial. Menú: depositar, retirar, consultar, salir.
Requisitos:
No permitir retiros mayores al saldo
Validar montos positivos
Mostrar saldo después de cada operación
Lazo hasta que elija salir
Orientación:
Variable
saldoinicialLazo principal con menú
switchpara operacionesValidaciones antes de modificar saldo
Ejercicio 1.03b.33 - Criba de Eratóstenes ⭐⭐⭐⭐⭐¶
Encontrá todos los números primos hasta N usando la Criba de Eratóstenes.
Algoritmo:
Creá array booleano de tamaño N+1, todos en
trueMarcá 0 y 1 como no primos
Para cada número i de 2 a √N:
Si i es primo (marcado
true):Marcá todos sus múltiplos como no primos
Los que quedaron en
trueson primos
Orientación:
Array:
bool es_primo[N+1]Lazo externo:
ide 2 a √NLazo interno: múltiplos de
i(desde i², incrementando de i en i)Mostrá todos los marcados como primos
Ejercicios Adicionales de Patrones¶
Ejercicio 1.03b.34 - Pirámide Centrada ⭐⭐⭐⭐⭐¶
Dibujá una pirámide centrada de asteriscos.
Ejemplo (N=5):
*
***
*****
*******
*********Orientación:
Para cada fila i (de 0 a N-1):
Imprimí (N-i-1) espacios
Imprimí (2*i+1) asteriscos
Nueva línea
Ejercicio 1.03b.35 - Rombo ⭐⭐⭐⭐⭐¶
Dibujá un rombo de asteriscos.
Orientación:
Mitad superior: pirámide creciente
Mitad inferior: pirámide decreciente
Mismo principio de espacios y asteriscos
Problemas de Lazos Anidados¶
Ejercicio 1.03b.36 - Tabla de Multiplicar Completa ⭐⭐⭐⭐☆¶
Mostrá tabla de multiplicar del 1 al 10 (todas las tablas).
Orientación:
Lazo externo: números del 1 al 10
Lazo interno: multiplicadores del 1 al 10
Formato: “3 x 4 = 12”
Ejercicio 1.03b.37 - Números Primos en Rango ⭐⭐⭐⭐☆¶
Mostrá todos los números primos entre A y B.
Orientación:
Lazo externo: números de A a B
Lazo interno: verificar si es primo (función del ejercicio 9)
Imprimí solo los primos
Problemas de Validación y Control¶
Ejercicio 1.03b.38 - Juego de Adivinanza Mejorado ⭐⭐⭐⭐⭐¶
El programa elige un número aleatorio. El usuario tiene máximo 7 intentos.
Orientación:
rand() % 100 + 1para número aleatorioLazo con contador de intentos
Dar pistas (“muy alto”, “muy bajo”)
breaksi adivinaDespués del lazo: verificar si ganó o perdió
Notas Finales¶
Estas consignas cubren todos los aspectos de lazos: for, while, do-while,
lazos anidados, control de flujo y validación con repetición.
Ejercicio 1.03b.39 - Mostrar Argumentos ⭐☆☆☆☆¶
Mostrá todos los argumentos recibidos.
Orientación:
1 2 3 4 5 6 7 8int main(int argc, char *argv[]) { printf("Cantidad de argumentos: %d\n", argc); for (int i = 0; i < argc; i++) { printf("argv[%d] = %s\n", i, argv[i]); } }
argv[0]es el nombre del programa
Ejercicio 1.03b.40 - Saludo Personalizado ⭐☆☆☆☆¶
Lee un nombre desde argv y saludá.
Uso: ./saludo Juan
Orientación:
Verificá:
if (argc != 2) { fprintf(stderr, "Uso: %s <nombre>\n", argv[0]); return 1; }Usá:
printf("Hola, %s!\n", argv[1]);
Ejercicio 1.03b.41 - Suma de Dos Números ⭐⭐☆☆☆¶
Sumá dos números pasados como argumentos.
Uso: ./suma 5 3
Orientación:
Verificá
argc == 3Convertí con
atoi:int a = atoi(argv[1]);O mejor:
strtol(argv[1], NULL, 10)para validación
Ejercicio 1.03b.42 - Calculadora Simple ⭐⭐⭐☆☆¶
Implementá calculadora: ./calc <num1> <operador> <num2>
Uso: ./calc 10 + 5
Orientación:
argc == 4argv[2]es el operador:+,-,*,/Usá
switchoif-elsepara operaciónValidá división por cero
Ejercicio 1.03b.43 - Flags Booleanos ⭐⭐⭐☆☆¶
Procesá flags opcionales -v (verbose) y -h (help).
Uso: ./programa -v archivo.txt
Orientación:
Recorré
argvbuscando strings que empiecen con-if (strcmp(argv[i], "-v") == 0) verbose = true;Argumentos no-flag son archivos u otros datos
Ejercicio 1.03b.44 - Concatenar Argumentos ⭐⭐☆☆☆¶
Concatená todos los argumentos (excepto argv[0]) en un string.
Uso: ./concat Hola mundo desde C
Salida: Hola mundo desde C
Orientación:
Recorré argv desde índice 1
Concatená con espacios intermedios
Usá
strcato manualmente con índices
Ejercicio 1.03b.45 - Conversor de Temperatura ⭐⭐⭐☆☆¶
Convertí temperatura según flags.
Uso: ./temp -c 100 (Celsius a Fahrenheit)
Uso: ./temp -f 212 (Fahrenheit a Celsius)
Orientación:
Flag determina dirección de conversión
Valor viene después del flag
Mostrá resultado formateado
Ejercicio 1.03b.46 - Procesamiento de Texto desde Consola ⭐⭐⭐☆☆¶
Leé texto carácter por carácter desde la entrada estándar (stdin) hasta encontrar EOF y mostralo en mayúsculas.
Orientación:
Usá
getchar()dentro de un lazowhile ((c = getchar()) != EOF)Convertí cada letra con
toupper(c)de<ctype.h>Imprimí cada carácter procesado con
putchar()
Ejercicio 1.03b.47 - Flag con Valor ⭐⭐⭐⭐☆¶
Procesá flag que requiere un valor: -n <cantidad>
Uso: ./programa -n 10 archivo.txt
Orientación:
1 2 3 4 5 6 7 8 9 10 11 12 13 14for (int i = 1; i < argc; i++) { if (strcmp(argv[i], "-n") == 0) { if (i + 1 < argc) { cantidad = atoi(argv[++i]); // Incrementa i } else { fprintf(stderr, "Flag -n requiere valor\n"); } } }
Ejercicio 1.03b.48 - Múltiples Flags ⭐⭐⭐⭐☆¶
Implementá programa con varios flags: -v (verbose), -o <salida>, -n <num>
Uso: ./programa -v -o salida.txt -n 100 entrada.txt
Orientación:
Variables para cada flag
Lazo procesando argv
Flags pueden estar en cualquier orden
Argumentos sin
-son archivos de entrada
Ejercicio 1.03b.49 - Validación de Argumentos ⭐⭐⭐☆☆¶
Validá que números sean realmente números.
Orientación:
1 2 3 4 5 6 7char *endptr; long num = strtol(argv[1], &endptr, 10); if (*endptr != '\0') { fprintf(stderr, "Error: '%s' no es un número válido\n", argv[1]); return 1; }
strtolpone enendptrel primer carácter no-numéricoSi
*endptr != '\0', hay caracteres inválidos
Ejercicio 1.03b.50 - Ayuda Automática ⭐⭐⭐☆☆¶
Mostrá ayuda si se pasa -h o --help, o si argumentos son incorrectos.
Orientación:
1 2 3 4 5 6 7 8 9 10 11 12 13void mostrar_ayuda(const char *programa) { printf("Uso: %s [opciones] archivo\n", programa); printf("Opciones:\n"); printf(" -h, --help Mostrar esta ayuda\n"); printf(" -v Modo verbose\n"); printf(" -o <archivo> Archivo de salida\n"); } if (argc < 2 || strcmp(argv[1], "-h") == 0 || strcmp(argv[1], "--help") == 0) { mostrar_ayuda(argv[0]); return 0; }
Ejercicio 1.03b.51 - Grep Simplificado ⭐⭐⭐⭐☆¶
Buscá patrón en archivo(s).
Uso: ./grep "patron" archivo1.txt archivo2.txt
Orientación:
argv[1]es el patrónargv[2...]son archivosLeé cada archivo línea por línea
Si línea contiene patrón (
strstr), mostrala
Ejercicio 1.03b.52 - Wc (Word Count) Simplificado ⭐⭐⭐⭐☆¶
Contá líneas, palabras y caracteres de archivos.
Uso: ./wc [-l] [-w] [-c] archivo(s)
Flags:
-l: solo líneas-w: solo palabras-c: solo caracteresSin flags: todo
Orientación:
Procesá flags para saber qué contar
Para cada archivo, calculá métricas
Mostrá según flags activos
Ejercicio 1.03b.53 - Sort con Opciones ⭐⭐⭐⭐⭐¶
Ordená líneas de archivo con opciones.
Uso: ./sort [-r] [-n] archivo.txt
Flags:
-r: orden reverso-n: orden numérico (en lugar de lexicográfico)
Orientación:
Leé archivo completo en array de strings
Ordená según flags
Usá
qsortcon función comparadora apropiada
Ejercicio 1.03b.54 - Procesamiento de Lote ⭐⭐⭐⭐⭐¶
Aplicá operación a múltiples archivos.
Uso: ./batch -op <operacion> archivo1 archivo2 ...
Operaciones: upper, lower, reverse, count
Orientación:
Flag
-opdetermina operaciónAplicá a todos los archivos siguientes
Escribí resultado en archivo.out para cada uno
Ejercicio 1.03b.55 - Configuración desde Archivo y Args ⭐⭐⭐⭐⭐¶
Leé configuración de archivo, permitiendo override por línea de comandos.
Uso: ./programa -c config.txt -n 50
Orientación:
Leé config.txt primero (formato
clave=valor)Argumentos de línea de comandos sobrescriben config
Precedencia: defaults < archivo < args
Ejercicio 1.03b.56 - Pipeline Simulado ⭐⭐⭐⭐⭐¶
Implementá programa que puede leer de stdin o archivo.
Uso:
./proceso archivo.txtcat archivo.txt | ./proceso
Orientación:
1 2 3 4 5 6 7 8 9FILE *entrada; if (argc > 1) { entrada = fopen(argv[1], "r"); } else { entrada = stdin; // Lee de stdin }
Permite composición estilo Unix
Ejercicio 1.03b.57 - Getopt Simplificado ⭐⭐⭐⭐⭐¶
Implementá tu propia versión simplificada de getopt para parsear flags.
Orientación:
int getopt_simple(int argc, char *argv[], const char *optstring);optstring: “vhn:” (v y h sin valor, n con valor)Retorna carácter del flag o -1
Variable global
optargcon valor del flag
Ejercicio 1.03b.58 - Sistema de Comandos ⭐⭐⭐⭐⭐¶
Implementá programa con subcomandos estilo Git.
Uso:
./tool add archivo.txt./tool remove archivo.txt./tool list
Orientación:
argv[1]es el subcomandoargv[2...]son argumentos del subcomandoCada subcomando tiene su propia lógica
switcho tabla de funciones para dispatch
Notas Finales¶
Estas consignas cubren procesamiento de argumentos desde básico hasta sistemas complejos estilo herramientas Unix, esenciales para programas de línea de comandos profesionales.