Error inserting elements into a vector - C++

Asked

Viewed 154 times

0

I’m trying to call the job montVetorCodigo and montVetorPeca waste of main but I have tried several ways to put the elements of a TXT file inside a vector but it only stores the columns of the last row.

There is another way for you to insert this data into the corresponding vectors??

54 ARRUELA  
93 ABRACADEIRA 
55 PINO 
49 PORCA 
60 RELE 
30 DISJUNTOR 
27 FUSIVEL 
72 MOUSE 
40 LAMPADA 
14 TECLA 
21 CAIXA 
33 TAMPA 
76 INTERRUPTOR 
26 SOQUETE  
7 BASE
63 LAMINA  
50 PLACA 
31 TUBO 
17 LATERAL 
92 VIDEO 
11 PLUG 
36 CABO 
52 SUPORTE 
83 BOTAO 
22 PARAFUSO

The code:

#include <iostream>
#include <iomanip>
#include <fstream>
#include <algorithm>

using namespace std;

void montVetorCodigo(int *v, int n, int x);
void montVetorPeca(string *vP, int n, string y);
void showVetorCodigo(int *v, int n);
void showVetorPeca(string *v, int n);

int main()
{
    fstream arquivo;
    string sArqNome,sLinha,sCodigo,sPeca;
    int iCodigo,iQtdLinhas=0,n;
    char cOp;

    cout << "Entre com o nome do arquivo: ";
    cin >> sArqNome;
    arquivo.open(sArqNome);
    if (arquivo.is_open()){
        while(!arquivo.eof()){  // contar as linhas para definir n
            getline(arquivo,sLinha);
            iQtdLinhas++;
        }
        n = iQtdLinhas;
        int iVetorCodigo[n];
        string sVetorPeca[n];
        int iQtdLinhas=0;
        arquivo.clear();
        arquivo.seekg(ios::beg);
        while(!arquivo.eof()){  // montagem do vetor coletando dados das colunas
            getline(arquivo,sLinha);
            sCodigo = sLinha.substr(0,2);
            sPeca = sLinha.substr(2,14);
            iCodigo = stoi(sCodigo);  // transformar string para int
            sPeca.erase(remove(sPeca.begin(), sPeca.end(), ' '), sPeca.end());  // remover espaços em branco da captura da string 'sPeca'
            cout << iCodigo << endl;
            cout << sPeca << endl;
            
            montVetorCodigo(iVetorCodigo,n,iCodigo);
            montVetorPeca(sVetorPeca,n,sPeca);
            iQtdLinhas++;
        }
        showVetorCodigo(iVetorCodigo,n);
        showVetorPeca(sVetorPeca,n);
    arquivo.close();
    return 0;
}

void montVetorCodigo(int *v, int n, int x){
    for (int i = 0; i < n; i++){
        v[i] = x;
    }
}

void montVetorPeca(string *vP, int n, string y){
    for (int i = 0; i < n; i++){
        vP[i] = y;
    }
}

void showVetorCodigo(int *v, int n){
    cout << "Indices:   ";
    for (int i = 0; i < n; i++){
        cout << setw(3) << i << " ";
    }
    cout << endl;
    cout << "Elementos: ";
    for (int i = 0; i < n; i++){
        cout << setw(3) << v[i] << " ";
    }
    cout << endl;
}

void showVetorPeca(string *vP, int n){
    cout << "Indices:   ";
    for (int i = 0; i < n; i++){
        cout << setw(3) << i << " ";
    }
    cout << endl;
    cout << "Elementos: ";
    for (int i = 0; i < n; i++){
        cout << setw(3) << vP[i] << " ";
    }
    cout << endl;
}

More specifically in this part:

void montVetorCodigo(int *v, int n, int x){
    for (int i = 0; i < n; i++){
        v[i] = x;
    }
}

void montVetorPeca(string *vP, int n, string y){
    for (int i = 0; i < n; i++){
        vP[i] = y;
    }
}
  • Put the contents of the file you’re reading in the post tbm, so people can test.

  • 1

    As you are treating row by row of the file then you should insert a single position in your array and not insert the same value at all positions. I believe that in calling the function instead of n should inform iQtdLinhas, the position where the part code or name will be placed.

1 answer

1

If you really need the functions as declared and the data in this format, I think the simple is to use fscanf() to consume the input and create the two vectors, more or less as did.

However how you wrote it is wrong. int* and int[] are different things and need to build the vector carefully. If you really need to write so write back and I’ll show you how to do it in the C style.

I’ll show you three other ways to write, and a fourth:

At the end I added an example to show how I could do in traditional C-style, so will have something more complete

  • using a map: so it has the advantage of already entering classified and being able to search for the direct part in a single structure.
  • using two vectors, more or less as you were writing in your program. Values are in the input order
  • using a pair vector, int and string, and so you can use sort() to classify the vector. See in the example two ways to use Sort, using a common function to compare or using a lambda function, since it only has one line after all.

the input file

To make it easier to read I only used the first 8 lines of your file

54 ARRUELA  
93 ABRACADEIRA 
55 PINO 
49 PORCA 
60 RELE 
30 DISJUNTOR 
27 FUSIVEL 
72 MOUSE

Using a map

Usando map<int><string>

id: 27 parte FUSIVEL
id: 30 parte DISJUNTOR
id: 49 parte PORCA
id: 54 parte ARRUELA
id: 55 parte PINO
id: 60 parte RELE
id: 72 parte MOUSE
id: 93 parte ABRACADEIRA

Lista pecas com id entre 90 e 95 inclusive:

Id 90:  - - -
Id 91:  - - -
Id 92:  - - -
Id 93: ABRACADEIRA
Id 94:  - - -
Id 95:  - - -

the code

#include <iostream>
 #include <fstream>
#include <istream>
#include <map>

using namespace std;


int main(int argc, char** argv)
{
    const string padrao = "pec.txt";
    string arquivo{ padrao };
    if (argc > 1) arquivo = argv[1];

    cout << "\nUsando map<int><string>\n\n";
    int id;
    string part;
    ifstream entrada { arquivo };
    map<int, string> partes;

    while (!entrada.eof())
    {
        entrada >> id;
        entrada >> part;
        partes.insert(pair(id, part));
    };  // while()

    for (auto& parte : partes)
    {
        cout << "id: "    << parte.first
             << " parte " << parte.second << endl;
    };  // for()

    // mostra as pecas entre 90 e 95
    cout << "\nLista pecas com id entre 90 e 95 inclusive:\n\n";
    for (int p = 90; p < 96; p = p + 1)
    {
        cout << "Id " << p << ": " ;
        auto x = partes.find(p);
        if (x != partes.end())
            cout << x->second << endl;
        else
            cout << " - - -\n";
    }
    return 0;
    };

Using two vectors or a pair vector

Usando dois vetores

id: 54 parte ARRUELA
id: 93 parte ABRACADEIRA
id: 55 parte PINO
id: 49 parte PORCA
id: 60 parte RELE
id: 30 parte DISJUNTOR
id: 27 parte FUSIVEL
id: 72 parte MOUSE

Usando um vetor de pares


vetor como criado

id: 54 parte ARRUELA
id: 93 parte ABRACADEIRA
id: 55 parte PINO
id: 49 parte PORCA
id: 60 parte RELE
id: 30 parte DISJUNTOR
id: 27 parte FUSIVEL
id: 72 parte MOUSE

Ordena o vetor


vetor ordenado

id: 27 parte FUSIVEL
id: 30 parte DISJUNTOR
id: 49 parte PORCA
id: 54 parte ARRUELA
id: 55 parte PINO
id: 60 parte RELE
id: 72 parte MOUSE
id: 93 parte ABRACADEIRA

The program using the vectors

#include <algorithm>
#include <fstream>
#include <iostream>
#include <istream>
#include <vector>

using namespace std;

int     compara(pair<int,string>, pair<int, string>);
 int main(int argc, char** argv)
{
    const string padrao = "pec.txt";
    string arquivo{ padrao };
    if (argc > 1) arquivo = argv[1];

    cout << "\nUsando dois vetores\n\n";
    int id;
    string part;
    ifstream entrada{ arquivo };
    vector<int> vId{};
    vector<string> vPeca{};

    while (!entrada.eof())
    {
        entrada >> id;
        entrada >> part;
        vId.push_back(id);
        vPeca.push_back(part);
    };  // while()

    for (int i=0; i< vId.size(); i+=1)
    {
        cout << "id: " << vId[i]
            << " parte " << vPeca[i] << endl;
    };  // for()


    cout << "\nUsando um vetor de pares\n\n";
    vector< pair<int, string> > vCad_ordenado{};
    entrada.seekg(0, entrada.beg);
    while (!entrada.eof())
    {
        entrada >> id;
        entrada >> part;
        vCad_ordenado.push_back( pair(id,part) );
    };  // while()

    cout << "\nvetor como criado\n\n";
    for (int i = 0; i < vCad_ordenado.size(); i += 1)
    {
        cout << "id: " << vCad_ordenado[i].first
            << " parte " << vCad_ordenado[i].second << endl;
    };  // for()

    cout << "\nOrdena o vetor\n\n";
    sort(vCad_ordenado.begin(), vCad_ordenado.end(), compara );
    // alternativa para o sort sem escrever a funcao de comparacao
    //sort(vCad_ordenado.begin(), vCad_ordenado.end(),
    //    [](pair<int, string>A, pair<int, string>B){ return A.first < B.first; });

    cout << "\nvetor ordenado\n\n";
    for (int i = 0; i < vCad_ordenado.size(); i += 1)
    {
        cout << "id: " << vCad_ordenado[i].first
            << " parte " << vCad_ordenado[i].second << endl;
    };  // for()

    return 0;
};

// para o sort
int     compara(pair<int, string> A, pair<int, string> B)
{
    return A.first < B.first;
};

And using int[] after all?

I don’t think it’s a good idea if you’re not using C, but look

the exit

Usando scanf(), malloc() e realloc() em C-style, mas seguro. Arquivo: 'pec.txt'

8 itens lidos [limite atual 50]
   1: 54 ARRUELA
   2: 93 ABRACADEIRA
   3: 55 PINO
   4: 49 PORCA
   5: 60 RELE
   6: 30 DISJUNTOR
   7: 27 FUSIVEL
   8: 72 MOUSE

Of this program

#define _BLOCO_ 50

#include <iostream>
#include <iomanip>
#include <fstream>
#include <memory>

using namespace std;

void montVetorCodigo(int* v, int n, int x);
void montVetorPeca(string* vP, int n, string y);
void showVetorCodigo(int* v, int n);
void showVetorPeca(string* v, int n);

typedef struct
{
    unsigned    limite; // tamanho alocado
    unsigned    N; // total de pecas
    int**       id; // codigo
    char**      peca; // nome

}   Cadastro;


int main(int argc, char** argv)
{
    const string padrao = "pec.txt";
    string arquivo{ padrao };
    if (argc > 1) arquivo = argv[1];

    cout << "\nUsando scanf(), malloc() e realloc() em C-style, mas seguro. Arquivo: '"
        << arquivo << "'\n\n";

    // o estoque comeca vazio e com um bloco de ponteiros
    // para nao ficar alocando toda hora
    Cadastro estoque;
    estoque.limite = _BLOCO_;
    estoque.N = 0;
    estoque.id =   (int**) malloc(_BLOCO_ * sizeof(*estoque.id));
    estoque.peca = (char**) malloc(_BLOCO_ * sizeof(*estoque.peca));

    ifstream entrada{ arquivo };
    string uma;
    Cadastro* C = &estoque; // mais curto pra escrever
    while (!entrada.eof())
    {
        C->id[C->N] = (int*) malloc(sizeof(int));
        entrada >> *C->id[C->N];
        entrada >> uma; // uma peca
        C->peca[C->N] = (char*) malloc(sizeof(uma.length() + 1));
        // copia a string para o novo lar
        strcpy(C->peca[C->N], uma.c_str());
        C->N += 1;

        // agora se gastou o ultimo lugar do bloco alocado 
        // precisa aumentar o bloco
        if (C->N == C->limite)
        {
            C->limite += _BLOCO_; // aumenta
            int* novo = (int*)realloc(C->id, C->limite * sizeof(int*));
            if (novo == NULL) return -1;
            C->id = (int**)novo;
            char * nova = (char*)realloc(C->peca, C->limite * sizeof(char*));
            if (novo == NULL) return -2;
            C->peca = (char**)nova;
        }
    };  // while()

    // leu tudo 

    cout << C->N << " itens lidos [limite atual " <<
        C->limite << "]\n";

    // mostra o estoque

    for (unsigned i = 0; i < C->N; i += 1)
    {
        cout << setw(4) << 1+i << ": " << *C->id[i]
            << " " << C->peca[i] << "\n";
    };  // for
    return 0;
    }

Note that in all these examples you can use the file name in the command line

    programa [arquivo]

Instead of compiling the program again just because it will use another input file

Browser other questions tagged

You are not signed in. Login or sign up in order to post.