0

Tengo el siguiente código que crea un vector(a partir de un fichero de texto) con los elementos que cumplen el requerimiento

bool IsValid(vector<int> digits) //el primer dígito es menor que la suma de los dos últimos
{
    if(digits[0] < (digits[1] + digits[2] ))
        return true;
    else
        return false;
}

así es como lo aplico para crear el nuevo vector y el fichero de texto saliente en el que quiero escribir los elementos de este nuevo vector

int main()
{
    ofstream outfile ("test.txt");
    outfile << "512 456 789 123 123 432 \n 123 243 \n \n 412\n  " << endl;
    ifstream in("test.txt");
    ofstream out("output.txt");
    char tmp;
    vector<int> digits;
    try
    {
    while(in.get(tmp))
    {
        if(tmp!=' ' and tmp!='\n')
        {
            digits.push_back(tmp-'0');

            if(digits.size()==3)
            {
                if(IsValid(digits)){
                    cout<<"number of elements="<<digits.size()<<endl;
                    out<<digits[0]<<digits[1]<<digits[2]<<endl;
                    for(int i=0; i<digits.size();i++){
                    cout<<digits[i]<<endl;}
                }
                 digits.clear();

            }
        }

    }

    }
    catch(const std::exception& e)
    {

    }
    out.close();
    in.close();

}

Mi duda es que cuando escribo cout<<"number of elements="<<digits.size()<<endl; no recibo en consola el numero de elementos total sino me dice que hay 3 elementos cuando lo que yo quiero que me diga cuántos elementos hay en total introducir la descripción de la imagen aquí

juanchi
  • 103
  • 5

1 Answers1

1

Mi duda es que cuando escribo cout<<"number of elements="<<digits.size()<<endl; no recibo en consola el numero de elementos total.

Te equivocas, sí que recibes el número de elementos total, son exactamente tres elementos porque sólo tienes posibilidad de consultar digits.size() cuando dicho valor es exactamente tres:

if(digits.size()==3) // <--- El tamaño es exactamente tres?
{
    if(IsValid(digits)){
        cout<<"number of elements="<<digits.size()<<endl; // <--- Imprime el tamaño
        // … 
    }
    // …
}

Por otro lado, nunca tendrás más de tres elementos, ya que en el momento en que obtienes tres elementos borras el contenido y vuelves a empezar de cero:

if(digits.size()==3) // <--- El tamaño es exactamente tres?
{
    // … 
    digits.clear(); // <--- Vacía el contenedor.
}

Supongo que lo que en realidad quieres es que los números sean de exactamente tres cifras y después filtrarlos por el criterio que detallas, lo más cercano a ese objetivo conservando la mayor parte de tu código sería:

vector<int> digits;
vector<vector<int>> values;

while(in.get(tmp))
{
    if(tmp!=' ' and tmp!='\n')
    {
        digits.push_back(tmp-'0');

        if(digits.size()==3)
        {
            values.push_back(digits); // Guardar el número candidato
            digits.clear(); // Dejar el contenedor listo para el siguiente candidato
        }
    }
}

for (auto &candidate : values)
    if(IsValid(candidate)){ // Validar candidatos.
        cout<<"number of elements="<<values.size()<<endl;
        out<<candidate[0]<<candidate[1]<<candidate[2]<<endl;
        for(int i=0; i<candidate.size();i++){
            cout<<candidate[i]<<endl;}
        }
    }

Pero tu código puede ser mejorado en muchos puntos:

  1. No necesitas un condicional para devolver verdadero o falso, la propia expresión ya es verdadera o falsa:

    bool IsValid(vector<int> digits)
    {
        return digits[0] < (digits[1] + digits[2]);
    }
    
  2. No utilices vectores de dígitos para almacenar números, almacena números:

    bool IsValid(int value)
    {
        return (value / 100) < (((value / 10) % 10) + (value % 10));
    }
    
  3. No leas la información carácter a carácter, lee dato a dato:

    vector<int> values;
    
    if (ifstream in{"test.txt"}) {
        int value;
        while ((in >> value) && value < 1000) // Lee números de tres dígitos
            values.push_back(value);
    }
    
  4. Hace 30 años las pantallas eran de 80 caracteres de ancho y 20 líneas de alto, por lo tanto tenía sentido apretujar el código para mostrar en pantalla la mayor cantidad de información posible… hoy es día es completamente innecesario y absolutamente contraproducente: deja respirar a tu código, el código apretujado no mola más.
  5. main debería devolver un valor al acabar.

Propuesta.

#include <iostream>
#include <vector>
#include <fstream>

using namespace std;

bool IsValid(int valor) //el primer dígito es menor que la suma de los dos últimos
{
    return (valor / 100) < (((valor / 10) % 10) + (valor % 10));
}

int main()
{
    if (ofstream outfile{"test.txt"}) {
        outfile << "512 456 789 123 123 432 \n 123 243 \n \n 412\n  \n";
    }

    vector<int> values;

    if (ifstream in{"test.txt"}) {
        int value;
        while ((in >> value) && value < 1000)
            values.push_back(value);
    }

    if (ofstream out{"output.txt"}) {
        for (const auto &candidate : values) {
            if (IsValid(candidate)) {
                cout << "number of elements=" << values.size() << '\n'
                    << candidate << '\n';
                out << candidate << '\n';
            }
        }
    }

    return 0;
}
PaperBirdMaster
  • 44,474
  • 6
  • 44
  • 82
  • cuando ejecuto tu propuesta recibo los siguientes errores: (He cambiado los nombres de fichero de entrada y salida para no perder mi código)stack3.c++:18:18: error: variable declaration in condition must have an initializer if (ofstream outfile{"test21.txt"}) { ^ stack3.c++:18:25: error: expected ')' if (ofstream outfile{"test21.txt"}) { ^ stack3.c++:18:8: note: to match this '(' if (ofstream outfile{"test21.txt"}) { Alguna propuesta? – juanchi Jan 27 '20 at 13:35
  • Compila con C++11 o superior. – PaperBirdMaster Jan 27 '20 at 13:38
  • Creo que compilo con c++11(uso Visual Studio con la extensión de C++Intelligense y Code Runner) – juanchi Jan 27 '20 at 13:40
  • Entonces o está equivocado el compilador o lo estás tu. Creo que puede ser lo segundo, ya que ese código está funcionando en el compilador de TIO, tal y como puede verse en el enlace de la respuesta. – PaperBirdMaster Jan 27 '20 at 13:43