Pergunta sobre matriz de strings. [RESOLVIDO]

1. Pergunta sobre matriz de strings. [RESOLVIDO]

rob
robgeek

(usa Debian)

Enviado em 03/12/2014 - 18:25h

Boa noite!

Estou querendo fazer programa onde o usuário terá que responder uma série de perguntas de diferentes categorias. Para fazer isso, eu decidi criar uma matriz de strings queria mais ou menos assim:
linha 0 seria para perguntas de Português
linha 1 seria para perguntas de Matemática
linha 2 seria para perguntas de Geografia

Bem, eu tentei fazer como no código abaixo, mas não deu certo. Pesquisando um pouco no Google eu vi que todas as vezes que falavam em matriz de strings, na verdade estavam fazendo vetores. Isso porque eles definem uma "matriz" de strings assim:
char perguntas[3][255] // [3] é o número de strings e [255] é o tamanho de cada uma 

Ora, para mim isso é um vetor, não matriz!

Como posso fazer para criar realmente uma matriz de strings, ou neste caso uma matriz é feita dessa forma mesmo.

O que tentei fazer.
#include <stdio.h>
#include <string.h>

#define CTGR 3 // Categorias
#define PRGT 5 // Perguntas

int main( ) {
int i, j;
char quiz[CTGR][PRGT];

for(i=0; i < CTGR; i++) {
for(j=0; j < PRGT; j++) {
strcpy(quiz[i][j], "vazio");
}
}

for(i=0; i < CTGR; i++) {
for(j=0; j < PRGT; j++) {
printf("%s ", quiz[i][j]);
}
}

return 0;
}


Erro no terminal:
main.c: In function ‘main’:
main.c:13:4: warning: passing argument 1 of ‘strcpy’ makes pointer from integer without a cast [enabled by default]
In file included from main.c:2:0:
/usr/include/string.h:128:14: note: expected ‘char * __restrict__’ but argument is of type ‘char’


Obrigado!


  


2. MELHOR RESPOSTA

Paulo
paulo1205

(usa Ubuntu)

Enviado em 04/12/2014 - 14:04h

robgeek escreveu:

Pensei em usar uma matriz de strings como falei, pois me pareceu a forma mais simples de se fazer, suspeitei que seria necessária mais uma dimensão, mas ainda não entendi por que é uma má ideia, apesar do ponto levantado pelo Paulo1205, sempre muito solicito, de que as perguntas terão sempre tamanho único.


Eu não disse que é má ideia. Cada uma tem suas vantagens e desvantagens. Poder colocar perguntas de qualquer tamanho sem afetar o tamanho de todas as outras perguntas é uma das possíveis vantagens de ter uma matriz de ponteiros. As desvantagens incluem a existência de um nível de indireção, com possível perda de desempenho e até mesmo maior consumo de memória, especialmente se a maioria das perguntas tiver tamanho próximo ao tamanho reservado para cada pergunta na declaração do array tridimensional.

Na verdade, a discussão “array versus ponteiro” pode se estender aos outros níveis. Por exemplo: por que todas as disciplinas têm de ter a mesma quantidade de perguntas (obrigada com arrays, livre com ponteiros)? Por que ter uma quantidade fixa de disciplinas, definida em tempo de compilação (obrigada com arrays, livre com ponteiros)?

Se você estiver usando C++, e não C, considere usar os contêineres de dados da biblioteca padrão de templates. Veja este exemplo de programa completo, escrito em C++11.

#include <map>
#include <vector>
#include <string>
#include <utility>
#include <iostream>


std::map<std::string, std::vector<std::string>> provao{
{
"Português",
{
"Qual a classe gramatical de \"gramatical\"?",
"Qual o sujeito da frase \"O objeto é manipulado pelo sujeito.\"?",
"O que é uma rima preciosa?"
}
},
{
"Matemática",
{
"Qual o valor de 3 vezes 9?",
"Qual o valor de 7!?",
"Qual o nome do polígono que possui exatamente 18 diagonais?",
"Qual a transformada inversa de Laplace de 1/(s²+5)?",
"Qual o volume de um dodecaedro regular inscrito numa esfera de raio 45cm?"
}
}
};


int main(){
/* Só para demonstrar, acrescento mais uma questão de Português. */
provao["Português"].push_back(
"Classifique as orações que compõem o seguinte período: \"João me "
"disse que, diante de tal circunstância, não poderia honrar o "
"compromisso que havia assumido com sua noiva.\"."
);

/* E para demontrar também, mais uma disciplina, com duas questões. */
provao.insert(
std::make_pair<std::string, std::vector<std::string>>(
"História",
{
"Quem descobriu o Brasil?",
"Quais foram as causas e os desdobramentos da primeira guerra dos Boers?"
}
)
);

unsigned n_parte, n_pergunta;
n_parte=n_pergunta=0;

std::cout <<
"P R O V A D E R E C U P E R A Ç Ã O\n"
"---------------------------------------\n\n"
;
for(auto &parte: provao){
std::cout << "PARTE " << ++n_parte << " - " << parte.first << "\n\n";
for(auto &pergunta: parte.second)
std::cout << ++n_pergunta << ") " << pergunta << "\n\n";
std::cout << "\n";
}
}


A saída é a seguinte.

P R O V A   D E   R E C U P E R A Ç Ã O
---------------------------------------


PARTE 1 - História

1) Quem descobriu o Brasil?

2) Quais foram as causas e os desdobramentos da primeira guerra dos Boers?


PARTE 2 - Matemática

3) Qual o valor de 3 vezes 9?

4) Qual o valor de 7!?

5) Qual o nome do polígono que possui exatamente 18 diagonais?

6) Qual a transformada inversa de Laplace de 1/(s²+5)?

7) Qual o volume de um dodecaedro regular inscrito numa esfera de raio 45cm?


PARTE 3 - Português

8) Qual a classe gramatical de "gramatical"?

9) Qual o sujeito da frase "O objeto é manipulado pelo sujeito."?

10) O que é uma rima preciosa?

11) Classifique as orações que compõem o seguinte período: "João me disse que, diante de tal circunstância, não poderia honrar o compromisso que havia assumido com sua noiva.".



3. Re: Pergunta sobre matriz de strings. [RESOLVIDO]

Paulo
paulo1205

(usa Ubuntu)

Enviado em 03/12/2014 - 19:14h

#define MAX_PERGUNTAS 3
enum assuntos {portugues, matematica, fisica, ingles, N_ASSUNTOS};
const char *const provao[N_ASSUNTOS][MAX_PERGUNTAS]={
/*portugues*/ {
"Qual a classe gramatical de \"gramatical\"?",
"Qual o sujeito de \"O objeto é controlado pelo sujeito\"?",
"O que é uma rima preciosa?"
},
/* matematica */ {
"Quanto vale 3 vezes 9?",
"Quantas diagonais tem um eneágono?",
"Qual a transformada inversa de Laplace de 1/(s²+5)?"
},
/* fisica */ {
"Qual a velocidade média de um carro que percorre 30km em 10min?",
"Qual a energia potencial gravitacional de um objeto de 5kg colocado a 10m de altura?",
"Quanto tempo será percebido pelo piloto de uma nave que viajar durante 100 anos a 99,95% da velocidade da luz?"
},
/* ingles */ {
"Translate into Portuguese: \"The car is blue.\"",
"Translate from Portuguese: \"O eneágono tem 18 diagonais.\"",
"Fill in the blanks: \"I __ (will see/had seen) the film before Susie __ (arrived/would arrive) from work.\""
}
};


/* ... */

/* Imprime a segunda pergunta da prova de fisica */
printf("%s\n", provao[fisica][1]);


A principal diferença entre minha sugestão e a do Sam L. é o lay-out em memória da tabela de perguntas. No meu caso, cada elemento é um ponteiro constante para caracteres também constantes, armazenados em locais diferentes da memória do da própria à tabela. Isso me permite ter perguntas de qualquer tamanho, ao preço de um ponteiro para cada pergunta (tamanho total ocupado é igual ao somatório de todos os caracteres das perguntas mais o produto do número de assuntos, número de perguntas e tamanho de um ponteiro). No caso do Sam L., as perguntas têm sempre tamanho exato de PRGT_TAM bytes (PRGT_TAM=64, o que na prática implica no máximo de 63 caracteres aproveitáveis mais um byte nulo por pergunta, mesmo que o texto da pergunta seja bem mais curto do que isso), todos eles dispostos em um só bloco contíguo com tamanho de PRGT_TAM*PRGT*CTGR.

Eu usei enum perguntas para facilitar a criação dos símbolos relacionados entre si e à dimensão da tabela correspondente ao assunto. Acho isso mais limpo do que definir uma porção de macros separadas para cada assunto. Note o uso do símbolo final N_ASSUNTOS, cujo valor inteiro não serve como índice da tabela, mas indica sua dimensão, já que é igual ao valor do maior índice válido (ingles, neste caso) mais 1.


4. Re: Pergunta sobre matriz de strings. [RESOLVIDO]

rob
robgeek

(usa Debian)

Enviado em 03/12/2014 - 20:46h

Sam, na verdade eu já programa há alguns anos, mas nunca precisei usar matriz de strings e sou bem preguiçoso e não estudo o que não preciso. Agora, que me surgiu essa necessidade que eu fui atrás. É errado, eu sei, mas sou assim mesmo.

Obrigado aos dois que me responderam, vou analisar bem as sugestões e ver qual caminho seguir.

Pensei em usar uma matriz de strings como falei, pois me pareceu a forma mais simples de se fazer, suspeitei que seria necessária mais uma dimensão, mas ainda não entendi por que é uma má ideia, apesar do ponto levantado pelo Paulo1205, sempre muito solicito, de que as perguntas terão sempre tamanho único.


5. Re: Pergunta sobre matriz de strings. [RESOLVIDO]

rob
robgeek

(usa Debian)

Enviado em 04/12/2014 - 19:47h

Eu não disse que era você quem tinha dito que não era uma boa ideia, Paulo, foi o Sam, mas acho que a justificativa dele é a mesma que a sua.

Não posso usar C++, o que me foi estabelecido é exclusivamente c, quem sabe um ou outro método de C++, mas definitivamente não posso suar containers.

Você trabalha neste fórum? É a primeira vez que vejo, não só neste forum, mas em outros também, alguém respponder de forma tão completa.

Obrigado e ao Sam também.






Patrocínio

Site hospedado pelo provedor RedeHost.
Linux banner

Destaques

Artigos

Dicas

Tópicos

Top 10 do mês

Scripts