* $Id$
*/
-/* Cabecera del TP. */
-#include "tp1.h"
+#include "carga.h"
+#include "calculo.h"
+#include "grafico.h"
+/* Para utilizar printf() y stderr */
+#include <stdio.h>
+/* Para utilizar EXIT_SUCCES y EXIT_FAILURE */
+#include <stdlib.h>
+/** Tiempo inicial por omisión. */
+#define DEFAULT_T0 0.0
+
+/** Tiempo final por omisión. */
+#define DEFAULT_TF 70.0
+
+/** Valor inicial de la función por omisión. */
+#define DEFAULT_F0 0.0
+
+/** Valor del pas de iteración por omisión. */
+#define DEFAULT_PASO 1.0
+
+/** Caracter usado para dibujar un punto por omisión. */
+#define DEFAULT_PUNTO '*'
+
+/** Caracter usado para dibujar un punto blanco por omisión. */
+#define DEFAULT_BLANCO ' '
+
+/**
+ * Imprime una explicación de como usar el programa.
+ *
+ * \param fh Archivo en donde imprimir el mensaje (ej: stdout o stderr).
+ */
void imprimir_uso(FILE* fh) {
fprintf(fh, "\n");
fprintf(fh, "Modo de uso:\n");
DEFAULT_F0);
}
-int argtod(const char* arg, Real* var, const char* nom) {
- /* Puntero al último caracter bien interpretado por strtod. */
- char* err = NULL;
- /* Realiza la conversión de un string a un Real */
- *var = strtod(arg, &err);
- /* Si el caracter donde apunta endptr es 0 es porque se interpretó toda la
- * cadena bien */
- if ((char)*err == '\0') {
- return TRUE;
- /* Si no, es que hubo error. */
- } else {
- fprintf(stderr, "Error: El parámetro '%s' debe ser un número ", nom);
- fprintf(stderr, "real. Usted ingresó '%s' pero '%s' no ", arg, err);
- fprintf(stderr, "pudo ser interpretado.\n");
- return FALSE;
- }
-}
-
-int cargar_datos(int argc, const char** argv, Real* paso, Real* tf, Real* f0) {
- switch (argc) {
- /* Si no tiene parámetros usa los valores por omisión. */
- case 1:
- break;
- /* Si tiene de 1 a 3 parámetros, los lee y valida, saliendo con un
- * mensaje de error en caso de haberlo. */
- case 4:
- /* Hay 3 parámetros, lee el 3er parámetro. */
- if (!argtod(argv[3], f0, "f0")) {
- return FALSE;
- }
- /* Continúa con el resto de los parámetros. */
- case 3:
- /* Hay al menos 2 parámetros, lee el 2do parámetro. */
- if (!argtod(argv[2], tf, "tf")) {
- return FALSE;
- }
- /* Continúa con el resto de los parámetros. */
- case 2:
- /* Hay al menos 1 parámetro, lee el 1er parámetro. */
- if (!argtod(argv[1], paso, "paso")) {
- return FALSE;
- }
- break; /* Finaliza el switch (no lee más parámetros). */
- /* Hay demasiados parámetros, sale con mensaje de error. */
- default:
- fprintf(stderr, "Error: Demasiados parámetros.\n");
- return FALSE;
- }
- /* TODO Verificar que el paso no sea cero y que tf > ti. */
- return TRUE;
-}
-
-size_t calcular(Resultados* res, Real paso, Real ti, Real tf, Real f0) {
- /* Índice para iterar. */
- size_t i;
- /* Calculo la cantidad de pasos necesarios según el tiempo inicial, el
- * tiempo final y el "tamaño" del paso. */
- size_t pasos = (size_t)((tf - ti) / paso);
- /* Respeto la cantidad máxima de pasos admitida. */
- if (pasos > MAX_PASOS) {
- pasos = MAX_PASOS;
- }
- /* Agrego el valor inicial de la función (para empezar a iterar). */
- (*res)[0] = f0;
- /* Itero paso a paso calculando el valor de la función. */
- for (i = 1; i < pasos; i++) {
- /* f(t+paso) = FUNCION(paso, f(t)) */
- (*res)[i] = FUNCION(paso, (*res)[i-1]);
- }
- return pasos;
-}
-
-Real resultados_max(Resultados* res, size_t pasos) {
- size_t i;
- Real max = (*res)[0];
- for (i = 1; i < pasos; i++) {
- if ((*res)[i] > max) {
- max = (*res)[i];
- }
- }
- return max;
-}
-
-Real resultados_min(Resultados* res, size_t pasos) {
- size_t i;
- Real min = (*res)[0];
- for (i = 1; i < pasos; i++) {
- if ((*res)[i] < min) {
- min = (*res)[i];
- }
- }
- return min;
-}
-
-void inicializar_linea(char* linea, char caracter, size_t cant) {
- size_t j;
- for (j = 0; j < cant; j++) {
- linea[j] = caracter;
- }
- linea[cant] = '\0';
-}
-
-void resultados_graficar(Resultados* res, size_t pasos, char punto, char blanco) {
- /* Máximo valor de la función. */
- Real min;
- /* Mínimo valor de la función. */
- Real max;
- /* Paso utilizado para la representación de las líneasMínimo valor de la función. */
- Real pasoh;
- int i;
- int j;
- char linea[ANCHO];
- min = resultados_min(res, pasos);
- max = resultados_max(res, pasos);
- pasoh = (max - min) / (ALTO);
- printf("min: %f, max: %f, pasoh: %f\n", min, max, pasoh);
- /* Inicializa la línea. */
- inicializar_linea(linea, blanco, MAX_PASOS);
- /* Por cada línea a dibujar. */
- for (i = ALTO; i >= 0; i--) {
- /* Se fija si hay algún punto que entre en el rango. */
- for (j = 0; j < pasos; j++) {
- /* Si está entre en el rango a imprimir, se agrega un punto. */
- if (((min + pasoh * i) <= (*res)[j])
- && ((*res)[j] < (min + pasoh * (i + 1)))) {
- linea[j] = punto;
- /* Si no, se lo deja en blanco. */
- } else {
- linea[j] = blanco;
- }
- }
- printf("%8.2f _%s\n", min + pasoh * i, linea);
- }
-}
-
+/**
+ * Programa principal.
+ * Este es el programa que se encarga de resolver el trabajo práctico.
+ *
+ * \param argc Cantidad de parámetros de línea de comandos ingresados.
+ * \param argv Parámetros de línea de comandos.
+ *
+ * \return EXIT_FAILURE si hubo un error, si no EXIT_SUCCESS.
+ */
int main(int argc, const char** argv) {
- /* TODO: Declaración de variables. */
- Resultados resultados;
- size_t pasos;
- Real paso = DEFAULT_PASO;
- Real tf = DEFAULT_TF;
- Real f0 = DEFAULT_F0;
- char punto = '*';
- char blanco = ' ';
-
+ /* Declaración de variables. */
+ Resultados resultados; /* Vector de resultados. */
+ size_t pasos; /* Cantidad de pasos a dibujar. */
+ Real paso = DEFAULT_PASO; /* Tamaño del paso */
+ Real t0 = DEFAULT_T0; /* Tiempo inicial */
+ Real tf = DEFAULT_TF; /* Tiempo final */
+ Real f0 = DEFAULT_F0; /* Valor inicial de la función */
+ char punto = DEFAULT_PUNTO; /* Caracter para dibujar un punto */
+ char blanco = DEFAULT_BLANCO; /* Caracter para dibujar un blanco */
/* Obtención de datos. */
- if (!cargar_datos(argc, argv, &paso, &tf, &f0)) {
+ if (!cargar_datos(argc, argv, &paso, &t0, &tf, &f0)) {
+ /* Si hay error, imprime mensaje con modo de uso y sale con error. */
imprimir_uso(stderr);
return EXIT_FAILURE;
}
-
/* Cálculo de la solución, dejando en un array los valores de cada paso. */
- pasos = calcular(&resultados, paso, T0, tf, f0);
- /* XXX - sacar o poner más lindo. */
- printf("paso = %f, tf = %f, f0 = %f, pasos = %i\n", paso, tf, f0, pasos);
-
- /* TODO: Barrido de pantalla de arriba hacia abajo consultando el array
- * y dibujando los resultados pertinentes. */
+ pasos = resultados_calcular(&resultados, paso, t0, tf, f0);
+ /* Impresión de variables principales. */
+ printf("\nt0 = %f | tf = %f | f0 = %f | paso = %f | pasos = %i\n\n", t0, tf, f0, paso, pasos);
+ /* Impresión del gráfico de la solución. */
resultados_graficar(&resultados, pasos, punto, blanco);
-
return EXIT_SUCCESS;
}