0

El archivo termina.txt tiene dos columnas, la primera corresponde a la última terminación de un numero y la segunda al número de veces que ha aparecido un número terminado en la misma. El objetivo del programa es mostrar la terminación que mas veces ha aparecido y cuantas veces ha aparecido pero al ejecutar los dos valores tanto la terminación como el numero de veces que ha aparecido me dan 0. Ayuda pls.

#include <stdio.h>

int main() {
    int num[10], veces[10], i, x, y = 0;
    FILE *f1;
    f1 = fopen("termina.txt", "r");
    if (f1 == NULL) {
        printf("Error al abrir el archivo");
        return -1;
    } else {
        for(i = 0; i <= 9; i++) {
            fscanf(f1,"%d %d", &num[i], &veces[i]);
            if (veces[i] > y) {
                veces[i] = y;
                num[i] = x;
            }
        }
        fclose(f1);
        printf("Terminacion que mas veces ha aparecido: %d (%d veces)", x, y);
    }
    /*El archivo de texto termina.txt contiene lo siguiente:
    0 728
    1 732
    2 736
    3 697
    4 738
    5 749
    6 705
    7 732
    8 726
    9 724
    */
    return 0;
}
meegle84
  • 343
  • 2
  • 17
  • Bienvenido a [es.so]. Por favor, revisa el [tour] para conocer un poco cómo funciona este sitio y [ask] para entender qué se espera de las preguntas. En este caso la pregunta no tiene contenido. Es solo código. No cuesta nada detallar el problema que tienes y concretarlo. Vale que el título debe ser representativo, pero si no hay contenido que lo respalde sirve de poco – eferion Oct 15 '18 at 10:35

2 Answers2

4

Estás haciendo la asignación al revés. Esto:

if (veces[i]>y){
    veces[i]=y;
    num[i]=x;
    }

Debería estar así:

if (veces[i]>y){
    y=veces[i];
    x=num[i];
    }

En caso contrario lo que haces es sobreescribir veces y num.

eferion
  • 49,291
  • 5
  • 30
  • 72
1

La función printf no te devuelve 0, seguramente te devuelve un valor entre 50 y 60. El valor de retorno de printf es la cantidad de caracteres que ha escrito, en tu caso escribes una cadena de unos 50 caracteres con dos números entre 1 y 3 dígitos.

Lo que te preocupa no es lo que devuelve printf si no lo que escribe; antes de entrar en detalle en cuál es tu fallo voy a señalar unos problemas con tu código:

  • La cabecera <stdio.h> es de no de . Esta cabecera dispone de una versión adaptada a C++ que tiene el prefijo c y carece de extensión. Si realmente necesitas usar las cabeceras de C (que nunca será el caso) debes usar los equivalentes de C++ <cstdio> . Lee este hilo para saber por qué.
  • printf y scanf son las funciones de lectura de consola de C, en C++ se usan los objetos stream: std::cout y std::cin.
  • FILE, fopen, fclose y fscanf son las funciones de lectura de archivos de C, en C++ se usan objetos stream como std::ifstream.
  • Es buena práctica inicializar tus variables.
  • Es buena práctica nombrar a tus variables de manera que el nombre recibido ayude a comprender su objetivo.
  • Es buena práctica indentar el código.
  • Es buena práctica que las variables tengan el ámbito más pequeño posible.

Teniendo en cuenta los detalles anteriores, y aplicando la solución propuesta por eferion, tu código podría quedar así:

#include <iostream> // Olvida stdio.h
#include <fstream>

int main() {

// Inicializadores, las variables se crearán con valor 0, las variables tienen
// un nombre claro y autoexplicativo que ayuda a entender su cometido.
//                vv           vv              vvvv                   vvvv
    int numero[10]{}, veces[10]{}, maximo_veces = 0, mayor_terminacion = 0;

// El flujo de archivo ifstream es convertible a booleano, será verdadero
// si el archivo se pudo abrir y falso en caso contrario.
//      vvvvvvvvvvvvv
    if (std::ifstream datos{"termina.txt"})
    {
// No es necesario declarar la variable del bucle fuera del mismo, puede
// limitar su contexto al propio bucle.
//           vvvvvvvvvv
        for (int indice = 0; (indice < 10) && datos; ++indice)
        {
            datos >> numero[indice];
            datos >> veces[indice];

            if (veces[indice] > maximo_veces)
            {
                maximo_veces = veces[indice];
                mayor_terminacion = numero[indice];
            }
        }

        std::cout << "Terminacion que mas veces ha aparecido: " << mayor_terminacion
                  << " (" << maximo_veces << "veces).\n";
    }
    else
    {
        std::cout << "Error al abrir el archivo\n";
    }

    return 0;
}

Ésta es una de las posibles maneras para quedarse con el valor máximo de entre los valores leídos, yo personalmente habría guardado todos los datos en una lista de pares (std::pair ) y tras la lectura de todos los datos habría buscado el máximo con std::max_element

using elemento = std::pair<int, int>;
using lista_elementos = std::list<elemento>;

lista_elementos valores;

if (std::ifstream datos{"termina.txt"})
{
    for (int indice = 0; (indice < 10) && datos; ++indice)
    {
        elemento e;
        datos >> e.first;
        datos >> e.second;
        valores.push_back(e);
    }

    auto mayor = std::max_element(valores.begin(), valores.end(),
                 [](const elemento &a, const elemento &b) { return a.first < b.frist; });

    std::cout << "Terminacion que mas veces ha aparecido: " << mayor->first
              << " (" << mayor->second << "veces).\n";
}
else
{
    std::cout << "Error al abrir el archivo\n";
}
PaperBirdMaster
  • 44,474
  • 6
  • 44
  • 82