Skip to article frontmatterSkip to article content
Site not loading correctly?

This may be due to an incorrect BASE_URL configuration. See the MyST Documentation for reference.

Regla 0x2002h: Las funciones no deben contener printf o scanf, a menos que ese sea su propósito explícito

Funciones, contratos y modularizacion (0x20XX)

Universidad Nacional de Río Negro

0x2002h: Las funciones no deben contener printf o scanf, a menos que ese sea su propósito explícito

Enunciado normativo

NO DEBE mezclarse la lógica de cálculo con llamadas a printf o scanf. Una función SÓLO PUEDE leer o escribir por consola si su nombre y su documentación declaran que esa es exactamente su responsabilidad.

¿Por qué existe esta regla?

El problema

Una función que calcula y además imprime tiene dos motivos para cambiar: la fórmula y el formato de salida. Peor: su resultado vive en un efecto lateral, no en el valor de retorno, así que para verificarla hay que capturar la pantalla o simular el teclado. La función queda atada a stdin/stdout, dos flujos globales difíciles de reemplazar en una prueba automática. Separar cálculo de presentación convierte al cálculo en una caja pura que recibe datos y devuelve un resultado.

Consecuencias de violarla

Tipo de consecuenciaEfecto concreto
TestingNo se prueba con assert sin redirigir la salida (0x8001h: Una aserción por cada función de prueba).
ReutilizaciónLa lógica no sirve para otra interfaz ni para un programa sin consola.
MantenibilidadCambiar un mensaje obliga a tocar la función que calcula.
RuidoEl cuerpo se llena de formato, comas y \n ajenos al algoritmo.

Fundamento en el estándar y en la cátedra

C11 declara las funciones de E/S con formato en <stdio.h> (§7.21.6): printf escribe en stdout y scanf lee de stdin. La norma no prohíbe usarlas en cualquier función; la cátedra las restringe por diseño, siguiendo la responsabilidad única (0x2005h: Cada función debe tener una única responsabilidad (Principio de Responsabilidad Única)) y protegiendo la testabilidad de 0x8001h: Una aserción por cada función de prueba.

Alcance y excepciones

Cubre toda función cuyo propósito no sea interactuar con el usuario. se permiten printf/scanf en funciones de interfaz nombradas como tales (mostrar_resultado, leer_edades), en main y en rutinas de registro o diálogo. La E/S sobre archivos (fprintf/fscanf) se rige por 0x4001h: Manejá correctamente la apertura y cierre de archivos y 0x4002h: Validá los retornos de las operaciones de lectura y escritura de archivos.

Ejemplos exhaustivos

❌ Contraejemplo 1 — Cálculo e impresión en la misma función

double calcular_promedio(const int v[], size_t n)
{
    int suma = 0;
    for (size_t i = 0; i < n; i++) {
        suma += v[i];
    }
    double promedio = (double)suma / (double)n;
    printf("El promedio es %.2f\n", promedio);
    return promedio;
}

El nombre promete calcular, pero también imprime; probarla dispara salida por pantalla.

❌ Contraejemplo 2 — Lectura por teclado dentro de la lógica

int buscar_mayor(struct lista_t *l)
{
    int valor;
    printf("Ingrese un valor de corte: ");
    scanf("%d", &valor);
    int mayor = l->datos[0];
    for (size_t i = 1; i < l->tam; i++) {
        if (l->datos[i] > mayor) {
            mayor = l->datos[i];
        }
    }
    return mayor;
}

Mezcla una lectura interactiva con la búsqueda; además ignora el retorno de scanf (0x4002h: Validá los retornos de las operaciones de lectura y escritura de archivos) y deja valor sin uso (0x2006h: Mantené el alcance de las variables al mínimo posible).

✅ Ejemplo conforme 1 — Cálculo puro

double calcular_promedio(const int v[], size_t n)
{
    if (n == 0) {
        return 0.0;
    }
    long suma = 0;
    for (size_t i = 0; i < n; i++) {
        suma += v[i];
    }
    return (double)suma / (double)n;
}

Se prueba con assert(calcular_promedio(v, 0) == 0.0) sin tocar la consola.

✅ Ejemplo conforme 2 — Interfaz separada del cálculo

static void mostrar_promedio(double valor)
{
    printf("El promedio es %.2f\n", valor);
}

int main(void)
{
    int edades[] = {20, 30, 40};
    mostrar_promedio(calcular_promedio(edades, 3));
    return 0;
}

calcular_promedio no sabe que existe una pantalla; mostrar_promedio declara su tarea. Cada una cambia por un motivo distinto.

⚠️ Casos límite

Cómo detectarla

HerramientaComandoSeñal
gaffgaff check archivo.cprintf/scanf en funciones que no son de interfaz.
grepgrep -n "printf|scanf" modulo.cE/S presente en módulos de lógica.

Checklist de autocontrol

Reglas relacionadas