Ir ao conteúdo
  • Cadastre-se

Problema de arquivo pra classe


sidyo
Ir à solução Resolvido por V!OLADOR,

Posts recomendados

Oi, estou tendo problemas com um sistema de matrículas. Preciso cadastrar turmas declaradas com um número da turma, uma string com o código da disciplina e um vetor com o numero da matrícula de alunos:

 

nº da turma  cod. da disciplina  numero de matrículas

490               4612A                   1, 3, 6
590               4612A                   2, 4, 5
128               4613A                   4, 5, 6
168               4610R                   1, 4
 

 

Pensei em algo deste gênero, mas n sei como colocar os alunos no vetor já q ele é varíavel(mas nunca será mais que 10):

 

while(!disciplinas.eof()){
        int n, m;
        string c;
        alunos >> n;
        alunos >> c;
        if(!disciplinas.eof()){
            Turma tur(n, c);
            int j=0;
            while() // onde adicionaria os alunos
              
        }
 
    }
Link para o comentário
Compartilhar em outros sites

Ou seja, cada posição do vetor é um aluno e nele você guarda o numero de matriculas? sendo assim o problema é que cada turma tem um numero diferente de alunos (vetores de tamanhos diferentes)? Bom, se não entendi errado, recomendo o uso da biblioteca <vector> do C++, e guardar as matriculas com a função std::vector::push_back(). Essa função permite ir guardando coisas no vetor sem que tenha definido explicitamente o tamanho dele (ela vai re-alocando o conteúdo sempre que necessário). Exemplo:
 

#include <iostream>#include <vector>//////    int var;    std::vector<int> matriculas;//////    alunos >> var;    matriculas.std::vector<int>::push_back(var); // Adiciona var ao vetor matriculas sem nunca ter definido o tamanho dele.
Link para o comentário
Compartilhar em outros sites

Ok. O problema era ler o arquivo. Acho que a solução trivial (sem fazer a vida mais difícil :P ) é abusar do layout do arquivo. Por exemplo, o tamanho do numero da turma será de 3 dígitos sempre? O código do curso 4 caracteres sempre? e a distancia entre eles também?

Se sim, então, sugiro ler o arquivo por linhas usando a função std::getline():

std::string linha;std::ifstream arquivo("nome.txt");do{    std::getline(arquivo, linha);    //    // Tratar a linha aqui antes do fim do loop.    //}while(!arquivo.std::ifstream::eof()); // Checa se ainda não chegou ao final do arquivo.

Daí, por "tratar linha" eu quis dizer, copiar os segmentos que você quer usando a função std::string::copy(). Mas antes nos livremos dos espaços e das virgulas:

//// Removendo todos os espaços em branco://linha.std::string::erase(remove(linha.std::string::begin(), linha.std::string::end(), ' '), linha.std::string::end());//// Removendo as virgulas://linha.std::string::erase(remove(linha.std::string::begin(), linha.std::string::end(), ','), linha.std::string::end());

E começamos a copiar os pedaços da linha que nos interessa:

std::string turma;linha.std::string::copy(turma.std::string::c_str(), 0, 3); // copy(destino, inicio, fim)

Com isso você copia os primeiros 3 caracteres do objeto linha pro objeto turma (os números ficaram como string, se por acaso você precisar de números de verdade, basta converter). Daí então, chame std::string::copy() novamente dando a posição do primeiro e ultimo carácter do código da disciplina. Por fim, você pode abrir um mini loop e ir usando std::string::copy(recursivamente, lendo cada numero (de matriculas) até chegar no fim da linha, dada pela função std::string::end().

Obviamente só te dei os ingredientes básicos (dá pra resolver só com isso). Agora basta ir brincando pra ter o resultado que você quer.

  • Curtir 1
Link para o comentário
Compartilhar em outros sites

A leitura do arquivo funcionou perfeitamente! Só que estou com outro problema, não estou conseguindo mudar valores com set's. Por exemplo: a Classe Faculdade tem um vetor de Disciplinas, que é composta de um código e um nome.

 

Utilizo estes métodos para troca:

 

Disciplina Faculdade::get_disciplina(int pos){
    return baseDis[pos];
}
 
void Disciplina::set_nome(string n){
    nome = n;
}

 

Não apresenta erro de compilação, mas não há troca. Porém isso é apenas na classe faculdade, caso eu declare uma disciplina no main isso funciona:

 

Faculdade facul;
Disciplina di;
 
     di = facul.get_disciplina(0);
     cout <<"DI: "<< di.get_nome() << endl;
     di.set_nome("Troca");
     cout << "DI: "<< di.get_nome()<< endl;
     cout << "facul: " << facul.get_disciplina(0).get_nome() << endl;
     facul.get_disciplina(0).set_nome("Troca");
     cout << "facul: "<< facul.get_disciplina(0).get_nome();
 
A saída na tela fica assim: 

 

DI: Teste

DI: Troca

facul: Teste

facul: Teste

 

Alguma ideia do motivo?

Link para o comentário
Compartilhar em outros sites

Não há erro de compilação mesmo. Eu acho que o problema está aqui:

//// O compilador provavelmente cria um temporário aqui.//Disciplina temp;temp = facul.get_disciplina(0).set_nome("Troca");//// ...e destrói aqui. set_nome() foi aplicado num objeto que já não existe.//cout << "facul: "<< facul.get_disciplina(0).get_nome();

Na verdade não é exatamente assim que funciona (as reais palavras-chave do problema são rvalue e lvalue) mas por motivos... didáticos, digamos, eu explicaria assim: Como você não atribui o retorno de facul.get_disciplina(0).set_nome("Troca") a nenhum objeto, o compilador deve criar um momentaneamente, temp, e destruí-lo imediatamente após o uso. A vida útil desses objetos é, em geral, o de uma linha (da linha onde forem invocados). Ele não vive o suficiente pra chegar na linha do cout, e então ser escrito na tela. Provavelmente na linha do cout um novo temporário estará sendo usado (depende da implementação do seu compilador).

 

Bom, a regra de ouro pra evitar esse tipo de efeito colateral é: se você tem uma função com um retorno e precisa trata-lo depois, você deve atribuir o valor de retorno explicitamente a um objeto declarado por você, porque assim você tem total controle da vida útil dele.

Link para o comentário
Compartilhar em outros sites

Visitante
Este tópico está impedido de receber novas respostas.

Sobre o Clube do Hardware

No ar desde 1996, o Clube do Hardware é uma das maiores, mais antigas e mais respeitadas comunidades sobre tecnologia do Brasil. Leia mais

Direitos autorais

Não permitimos a cópia ou reprodução do conteúdo do nosso site, fórum, newsletters e redes sociais, mesmo citando-se a fonte. Leia mais

×
×
  • Criar novo...

 

GRÁTIS: ebook Redes Wi-Fi – 2ª Edição

EBOOK GRÁTIS!

CLIQUE AQUI E BAIXE AGORA MESMO!