Ir ao conteúdo

Problema de arquivo pra classe


sidyo

Posts recomendados

Postado

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
              
        }
 
    }
Postado

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.
Postado

@V!OLADOR

O vetor de alunos é declarado com tamanho 10, só preciso separar as matrículas e coloca-las de uma em uma em cada posição do vetor. Mas não sei como fazer para tratar o resto da linha com as matrículas

Postado

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.

Postado

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?

Postado

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.

Postado

Entendi, então faria dessa maneira para modificar:

 

void Faculdade::set_DisciplinaNome(int pos, string n){

   baseDis[pos].set_nome(n)

}

 

Ou outra maneira mais simples?

Postado

Entendi, então faria dessa maneira para modificar:

 

void Faculdade::set_DisciplinaNome(int pos, string n){

   baseDis[pos].set_nome(n)

}

 

Ou outra maneira mais simples?

 

Eu também faria algo assim. Simples e eficiente.

Arquivado

Este tópico foi arquivado e está fechado para 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...

Ebook grátis: Aprenda a ler resistores e capacitores!

EBOOK GRÁTIS!

CLIQUE AQUI E BAIXE AGORA MESMO!