Pergunta Extremamente Difícil C++ string [RESOLVIDO]

13. Re: Pergunta Extremamente Difícil C++ string [RESOLVIDO]

Paulo
paulo1205

(usa Ubuntu)

Enviado em 06/07/2020 - 09:40h

Nick-us escreveu:

Apenas informando! ESSE foi mesmo o causador do problema! Removi como sugeriu e coloquei no lugar provisóriamente um for para todos os registros para testar o problema!

for(int x = 0; x < 1000; x++) {
Database[x][0].clear();
Database[x][1].clear();
Database[x][2].clear();
Database[x][3].clear();
Database[x][4].clear();
Database[x][5].clear();
Database[x][6].clear();
}


Você pode usar uma sintaxe mais curta, usando dois níveis de laços de repetição, e que vale tanto para arrays quanto para classes de containers.
for(auto &linha: Database)
for(auto &coluna: linha)
coluna.clear();

Só que você *não precisa* fazer isso se tiver acabado de declarar Databse e ela ainda não tiver sido usada, pois cada elemento já terá sido construído com uma string vazia. Você só precisará fazer essa limpeza se houver algum outro conteúdo anterior que você tenha de apagar.

Agora tentarei entender melhor os famosos vectors, que inicialmente me deixou a dúvida se declaro vector de string simples, ou se declaro vector de vector de string
É que vector simples de string me pareceu a primeira vista que é apenas uma lista de string.

Se eu declarar
std::vector<std::string> Database[5][3]; 

Eu estaria informando do mesmo jeito Qtd de Registros, embora eu desconfie que de para declarar
std::vector<std::string> Database; 

E Adicionar linhas e a Qtd de colunas que eu desejar igual eu faria abaixo, apenas não sei se é possível!


Você pode pensar em std::vector como um tipo de array dinâmico, cuja tamanho (i.e. quantidade de elementos) pode ser alterado ao longo de seu tempo de vida, através de operações como resize(), insert(), erase(), push_back() e outras.

A primeira declaração cria um array com 5 elementos do tipo array com 3 elementos do tipo array dinâmico com elementos do tipo string. A segunda cria um array dinâmico com elementos do tipo string.

Nenhuma das duas corresponde ao que você tinha antes. Você tinha uma matriz de strings. Acima, a primeira alternativa seria um cubo (ou paralelepípdedo) de strings, e a segunda seria uma tripa de strings. Só pela diferença de dimensões enovolvidas já daria para ver que está errado.

Assim. sei que posso eu mesmo definir a Qtd de linhas e Colunas, criando vetor de vetores, embora eu goste mais da forma acima se eu conseguir!
std::vector<std::vector<std::string>> Database;

std::vector<std::string> Row1 = { "Linha 1", "Linha 1", "Linha 1" };
std::vector<std::string> Row2 = { "Linha 2", "Linha 2", "Linha 2" };
std::vector<std::string> Row3 = { "Linha 3", "Linha 3", "Linha 3" };

Database.push_back(Row1);
Database.push_back(Row2);
Database.push_back(Row3);


Dá para fazer de modo mais curto.
std::vector<std::vector<std::string>> matriz{
{"abc", "bcd", "cde"},
{"def", "efg", "fgh"},
{"ghi", "hij", "ijk"},
{"jkl", "klm", "lmn"}
};


Uma possível desvantagem de ter vector de vector é que cada linha pode acabar ficando com um número de colunas diferente do número de colunas das demais linhas. Você tem de estudar o seu problema para saber se isso pode ser bom ou ruim para você.

Se você quiser um número fixo de colunas em cada linha, pode usar std::array.
#include <array>
#include <string>
#include <vector>

std::vector<std::array<std::string, 7>> Database; // Array dinâmico com elementos do tipo array fixo com 7 elementos do tipo string.


Parece-me, no entanto, que você tem papéis fixos para cada coluna. Nesse caso, talvez seja melhor usar uma estrutura com campos devidamente nomeados do que um array de strings, cuja função seja conhecida apenas pelos índices.
#include <string>
#include <vector>

struct dados_biblio {
std::string autor, titulo, titulo_orig, editora, isbn, revisao, observacoes;
};

std::vector<dados_biblio> Database;

/* ... */

Database[n].titulo="O Pequeno Príncipe";
Database[n].titulo_orig="Le Petit Prince";
Database[n].autor="Antoine de Saint-Exupéry";

/* ... */



... Então Jesus afirmou de novo: “(...) eu vim para que tenham vida, e a tenham plenamente.” (João 10:7-10)


  


14. Re: Pergunta Extremamente Difícil C++ string [RESOLVIDO]

Nick Us
Nick-us

(usa Slackware)

Enviado em 06/07/2020 - 14:27h

paulo1205 escreveu:
Você pode usar uma sintaxe mais curta, usando dois níveis de laços de repetição, e que vale tanto para arrays quanto para classes de containers.
for(auto &linha: Database)
for(auto &coluna: linha)
coluna.clear();

Só que você *não precisa* fazer isso se tiver acabado de declarar Databse e ela ainda não tiver sido usada, pois cada elemento já terá sido construído com uma string vazia. Você só precisará fazer essa limpeza se houver algum outro conteúdo anterior que você tenha de apagar.

Gostei desse for!

Você pode pensar em std::vector como um tipo de array dinâmico, cuja tamanho (i.e. quantidade de elementos) pode ser alterado ao longo de seu tempo de vida, através de operações como resize(), insert(), erase(), push_back() e outras.

Dá para fazer de modo mais curto.
std::vector<std::vector<std::string>> matriz{
{"abc", "bcd", "cde"},
{"def", "efg", "fgh"},
{"ghi", "hij", "ijk"},
{"jkl", "klm", "lmn"}
};

Bom saber!

Uma possível desvantagem de ter vector de vector é que cada linha pode acabar ficando com um número de colunas diferente do número de colunas das demais linhas. Você tem de estudar o seu problema para saber se isso pode ser bom ou ruim para você.

Eu imaginei que isso seria possível, mas não tinha certeza! Sua resposta respondeu essa dúvida, claro que neste caso eu não preciso, mas eu já havia imaginado a possibilidade para outro caso!

Se você quiser um número fixo de colunas em cada linha, pode usar std::array.
#include <array>
#include <string>
#include <vector>

std::vector<std::array<std::string, 7>> Database; // Array dinâmico com elementos do tipo array fixo com 7 elementos do tipo string.

Eu não conhecia essa opção std::array, vou aproveitar e estudar sobre ela também, eu conhecia apenas o vector

Parece-me, no entanto, que você tem papéis fixos para cada coluna. Nesse caso, talvez seja melhor usar uma estrutura com campos devidamente nomeados do que um array de strings, cuja função seja conhecida apenas pelos índices.
#include <string>
#include <vector>

struct dados_biblio {
std::string autor, titulo, titulo_orig, editora, isbn, revisao, observacoes;
};

std::vector<dados_biblio> Database;

/* ... */

Database[n].titulo="O Pequeno Príncipe";
Database[n].titulo_orig="Le Petit Prince";
Database[n].autor="Antoine de Saint-Exupéry";

/* ... */

Obrigado por mais esse exemplo. Eu não sabia que podia usar junto com uma Struct, no caso do meu Database atual, tenho poucos campos, então é fácil de lidar, mas no caso de um Database de Contacts por exemplo que vou criar para mim ele possue muitos campos, E chamá-los pelo nome é mais fácil de trabalhar!
Muito Obrigado pela Aula!



01 02



Patrocínio

Site hospedado pelo provedor RedeHost.
Linux banner

Destaques

Artigos

Dicas

Tópicos

Top 10 do mês

Scripts