Ir ao conteúdo

arfneto

Membro Pleno
  • Posts

    6.526
  • Cadastrado em

  • Última visita

Tudo que arfneto postou

  1. Talvez possa postar o enunciado... A memória do computador é linear. Uma matriz é dada por um endereço, matriz no seu caso, e esse tal N que seria um parâmetro. Não existe forma de ver sua dimensão. Em C e C++ uma tal matriz de mais de uma dimensão é alocada por linha e o compilador faz as contas de acordo para acessar os valôres de acordo com os índices. Dias atrás postei esse programa https://www.clubedohardware.com.br/forums/topic/1427656-retornando-array-2d-de-funções/?tab=comments#comment-7701240 que mostra como usar o mesmo endereço, como esse do seu caso, int matriz[N][N] para acessar como uma matriz de várias dimensões. Talvez ajude a entender o mecanismo disso.
  2. O exercíçio pede qualquer valor de N, o usuário não pode escolher o valor de N. E aí? Quem pode escolher o tal valor de N? Você? então não há dúvida. Se é uma função, não seria apenas um parâmetro?
  3. Defina melhor uma "matriz de strings". Em geral se fala de vetor quando tem uma dimensão apenas, e matriz quando é algo como uma tabela com duas ou mais dimensões. Algo assim char vetor[20]; // 20 elementos vetor[0] a vetor[19]; char matriz[4][5]; // 20 elementos matrix[0][0] a matriz[3][4] Em relação ao seu programa e ao jogo de forca char palavra[30]; char letra[1]; char secreta[30]; Qual a razão de declarar char letra[1] ao invés de apenas char letra? Em geral para o jogo de forca o que você quer é um vetor de strings com a tabela de possíveis palavras a serem sorteadas a cada rodada. Você lê isso de um arquivo no início do jogo, ou carrega como está no programa abaixo uma única string e algumas variáveis auxiliares para controlar a evolução da palavra do jogador durante o jogo, ou vários conjuntos se for escrever uma versão multi-jogador. Talvez ajude ver esse texto Palavras: uma outra ainda outra mostrado por esse programa #include <iostream> using namespace std; int main() { string palavras[3] = { "uma", "outra", "ainda outra" }; std::cout << "Palavras:\n"; for (auto palavra : palavras) cout << palavra << endl; return 0; }; // main() É só isso. Mas em C++ provavelmente o mais produtivo seria escrever uma classe Forca que carregasse as palavras no inicio, e com métodos para sorteio das palavras e tal... Vou te mostrar um exemplo mínimo, pra você ver a diferença entre seu programa e um programa comum em C++. Espero que ajude. Em C++ é MUITO mais fácil escrever essas coisas do que em C, graças aos tais objetos. Uma classe Forca // um exemplo minimo para mostrar a mecanica class Forca { private: int total_de_palavras; string Palavras[_CH_LIMITE_DE_PALAVRAS_]; public: int carrega_palavras(const char*); // carrega do arquivo int escolhe_palavra(); // sorteia palavra int mostra_palavras(); // mostra na tela pra testar public: Forca(); }; Como funciona? Quando você declara algo tipo Forca jogo; Forca outro_jogo; São criados dois "jogos" desse tipo Forca. você pode usar as funções que estão lá declaradas, Então por exemplo jogo.carrega_palavras("arquivo.txt") vai no disco abre o arquivo e carrega as palavras para a tabela, e já salva o número de palavras lidas em jogo.total_de_palavras. Nada mal não? jogo.escolhe_palavra() sorteia uma palavra da tabela e devolve o número dela na tabela E assim por diante. Exemplo Saida Criando um jogo Mostrando 0 palavras Leu 3 palavras de palavras.txt Mostrando 3 palavras 0 [palavra] 1 [outra] 2 [aindaoutra] Sorteio: palavra nova: aindaoutra (#2) Nova palavra: 2 Leu 5 palavras de outro.txt Mostrando 5 palavras 0 [agora] 1 [tem] 2 [mais] 3 [palavras] 4 [afinal] Sorteio: palavra nova: palavras (#3) Nova palavra: #3 Sorteio: palavra nova: afinal (#4) Nova palavra: #4 Sorteio: palavra nova: tem (#1) Nova palavra: #1 O programa #define _CH_LIMITE_DE_PALAVRAS_ 20 #include <iostream> #include <fstream> #include "stdio.h" #include "stdlib.h" #include <string> using namespace std; // um exemplo minimo para mostrar a mecanica class Forca { private: int total_de_palavras; string Palavras[_CH_LIMITE_DE_PALAVRAS_]; public: int carrega_palavras(const char*); // carrega do arquivo int escolhe_palavra(); // sorteia palavra int mostra_palavras(); // mostra na tela pra testar public: Forca(); }; using namespace std; int main() { const char* nome1 = "palavras.txt"; const char* nome2 = "outro.txt"; int n, qual; Forca um_jogo; um_jogo.mostra_palavras(); n = um_jogo.carrega_palavras(nome1); cout << "Leu " << n << " palavras de " << nome1 << endl; um_jogo.mostra_palavras(); qual = um_jogo.escolhe_palavra(); cout << "Nova palavra: " << qual << endl; n = um_jogo.carrega_palavras(nome2); cout << "Leu " << n << " palavras de " << nome2 << endl; um_jogo.mostra_palavras(); qual = um_jogo.escolhe_palavra(); cout << "Nova palavra: #" << qual << endl; qual = um_jogo.escolhe_palavra(); cout << "Nova palavra: #" << qual << endl; qual = um_jogo.escolhe_palavra(); cout << "Nova palavra: #" << qual << endl; return 0; }; // main() // carrega novas palavras a partir do arquivo int Forca::carrega_palavras(const char* nome_do_arquivo) { ifstream arquivo(nome_do_arquivo); if (!arquivo.is_open()) return -1; string palavra; total_de_palavras = 0; // comeca a contar while (getline(arquivo, palavra)) { Palavras[total_de_palavras] = palavra; if (total_de_palavras == _CH_LIMITE_DE_PALAVRAS_) { // chegou no limite arquivo.close(); return total_de_palavras; } total_de_palavras += 1; // conta a palavra } return total_de_palavras; } // mostra na tela todas as palavras int Forca::mostra_palavras() { cout << "Mostrando " << total_de_palavras << " palavras" << endl; for (int i = 0; i < total_de_palavras; i++) cout << i << " [" << Palavras[i] << "]" << endl; return 0; }; // mostra_palavras() // sorteio de uma palavra para o jogo int Forca::escolhe_palavra() { int n = rand() % total_de_palavras; cout << "Sorteio: palavra nova: " << Palavras[n] << " (#" << n << ")" << endl; return n; }; // sorteio() // cria um jogo: so zera o n. de palavras Forca::Forca() { cout << "Criando um jogo" << endl; total_de_palavras = 0; srand(200229); // apenas para iniciar o mecanismo de sorteio }; // Forca() Estou postando isso porque é difícil ver em um forum de C E C++ a diferença de como começar a escrever um programa assim, e em C naturalmente funciona um aluno raramente volta a um programa que funciona Então leva meses até o cara começar a entender porque esse lance de objetos (classes) é tão comemorado afinal adicionado 2 minutos depois Note que declarando Forca como struct assim também funciona // um exemplo minimo para mostrar a mecanica struct Forca { int total_de_palavras; string Palavras[_CH_LIMITE_DE_PALAVRAS_]; int carrega_palavras(const char*); // carrega do arquivo int escolhe_palavra(); // sorteia palavra int mostra_palavras(); // mostra na tela pra testar Forca(); };
  4. Parece que você sequer corrigiu o problema com EOF de que falei. Ler esses caracteres usando scanf() é um pesadelo. Tem muitas discussões sobre isso aqui. Tem a ver com páginas de código e o modo como o sistema que está usando trata esses caracteres. Teste tudo antes de se preocupar com isso. Use apenas um arquivo com umas poucas letras e confirme que o resto funciona (a lista e a leitura do arquivo) adicionado 17 minutos depois No_Lista *l = (No_Lista*) malloc(sizeof(No_Lista)); l = cria_lista(); Estava olhando o que mais mudou em seu código... Como te disse, cria_lista() não tem razão de ser, porque não recebe parametro algum e apenas retorna NULL. Mas usar isso depois de malloc é pior ainda. Só vai perder o valor alocado em l... Insere_fim() funciona com uma lista vazia? percorre() funciona com uma lista vazia? Sugestão: Escreva uma outra, mostra_lista() por exemplo, que apenas faz o óbvio. E TESTE antes algo assim No_lista* l = cria_lista(); mostra_lista(l); insere_fim(l,1); mostra_lista(l); insere_fim(l,2); mostra_lista(l); insere_fim(l,3); mostra_lista(l); // isso deve rodar antes de tudo... // nao misture as coisas.
  5. Seu programa está um pouco confuso ainda. Talvez pudesse dar uma mensagem e simplesmente retornar se não consegue abrir o arquivo ao invés de colocar todo o código de main() dentro de um if() Se o arquivo estiver vazio, do modo que escreveu vai tentar inserir algo que não leu... E no final do arquivo fscanf() não vai ler nada mas você vai tentar inserir mesmo assim Você não testa ao inserir valores já existentes e não tenta classificar os valores ou algo assim. Se o critério é só o intervalo porque não insere logo no início? Para que uma rotina que cria a lista se retorna NULL apenas? Imagino que seja um enunciado. Poderia postar talvez. Porque inserir um valor inválido para depois descobrir? Porque não insere apenas os valores entre 32 e 126? Sugiro Escreva primeiro a leitura do arquivo, depois a criação da lista. Depois a crítica da lista. Na criação da lista escreva primeiro a função que lista, depois a que insere. Escreva SEMPRE main() como a primeira função, em especial se vai deixar seu programa para outros lerem. É assim que seu programa vai rodar, só que o sistema sempre sabe o endereço de main(). Você ou eu temos que procurar no texto... Vou ler seu código melhor. Se mudou algo poste aqui,
  6. Está mais ou menos correto. realloc() vai de fato realocar memória a partir de um bloco previamente alocado por malloc() mas isso implica em potencialmente copiar tudo para outra área de memória com o novo tamanho. Ao usar isso a cada execução você fica copiando tudo a cada vez de novo para aumentar só um. é uma coisa estranha e não se usa isso. Em geral nem se usa realloc() mas quando se usa o normal é usar uma unidade, um bloco de produtos. Por exemplo comece com 10 produtos e depois vá dobrando a cada necessidade: 10/20/40/80... Em geral se usa uma estrutura de dados chamada lista ou algo parecido, ou um vetor de ponteiros. Pergunte de novo se não sabe do que estou falando. De volta ao seu programa O que você queria de fato acho que era alocar um vetor de produtos, e endereçar de acordo, algo como struct produto Produtos[500]; Produtos[300].unidades = 125; Produtos[125].valorC = 123.23; strcpy(Produtos[80].nome, "um produto"); printf("unidades do %d: %d\n", 300, Produtos[300].unidades); printf("valorC do %d: %6.2f\n", 125, Produtos[125].valorC); printf("nome do %d: [%s]\n", 80, Produtos[80].nome); E ver unidades do 300: 125 valorC do 125: 123.23 nome do 80: [um produto] Mas não dá, porque você vai alocar isso em tempo de execução... Como declarar isso então para ter um resultado parecido? Você declarou assim struct n_produto *newp; newp = malloc(qtp*sizeof(struct n_produto)); Podia ter escrito um comando só struct n_produto *newp = (struct n_produto*) malloc( qtp * sizeof(struct n_produto) ); É mais comum: malloc(0 retorna um pointer para void, um genérico. E você deve usar algo tipo (int*) para indicar ao compilador que quer converter o ponteiro para um ponteiro para o tipo certo. Se chama cast Mas no seu caso está errado: assim vai alocar uma área para qtp desses produtos, mas não adianta nada: newp vai continuar sendo um ponteiro para um único produto... E assim não vai conseguir acessar os outros. Há muitas maneiras de fazer isso. Uma simples seria simplesmente criar um outro ponteiro e ir deslocando em unidades de sizeof(struct n_produto). No entanto isso é o que o compilador faria por si só então deve ter um jeito de declarar isso... Se struct produto Produtos[500]; permite acessar um a um, então um ponteiro para isso seria declarado e usado assim: struct produto (*produtos)[1]; // ponteiro para um vetor de 1 so. Tanto faz produtos = (struct produto*) realloc(produtos, (sizeof(struct produto) * BLOCO )); // aloca um BLOCO deles (*produtos)[55].unidades = 234; // acessa um produto. Seu problema se forem menos de 56 :) Use assim. E não deixe de usar free() ao final para liberar a área. O Exemplo a seguir mostra unidades do 300: 125 valorC do 125: 123.23 nome do 80: [um produto] unidades do ultimo produto de 10: 9 produto[ 0]: 0 produto[ 1]: 1 produto[ 2]: 2 produto[ 3]: 3 produto[ 4]: 4 produto[ 5]: 5 produto[ 6]: 6 produto[ 7]: 7 produto[ 8]: 8 produto[ 9]: 9 produto[10]: 10 produto[11]: 11 produto[12]: 12 produto[13]: 13 produto[14]: 14 produto[15]: 15 produto[16]: 16 produto[17]: 17 produto[18]: 18 produto[19]: 19 Eis o programa. Rode em sua máquina #define _CRT_SECURE_NO_WARNINGS #include "stdio.h" #include "stdlib.h" #include "string.h" struct produto { char nome[50]; float valorC; int unidades; }; int main(int argc, char** argv) { struct produto Produtos[500]; Produtos[300].unidades = 125; Produtos[125].valorC = 123.23f; strcpy(Produtos[80].nome, "um produto"); printf("unidades do %d: %d\n", 300, Produtos[300].unidades); printf("valorC do %d: %6.2f\n", 125, Produtos[125].valorC); printf("nome do %d: [%s]\n", 80, Produtos[80].nome); struct produto (*produtos)[1]; produtos = malloc( sizeof(struct produto)* 10); for (int i = 0; i < 10; i += 1) (*produtos)[i].unidades = i; printf("\nunidades do ultimo produto de 10: %d\n", (*produtos)[9].unidades); produtos = realloc(produtos, (sizeof(struct produto) * 500)); for (int i = 10; i < 20; i += 1) (*produtos)[i].unidades = i; for (int i = 0; i < 20; i += 1) printf("produto[%2d]: %d\n", i, (*produtos)[i].unidades); free(produtos); }; // end main() adicionado 3 minutos depois postei um exemplo dessa aritmética de índices um pouco mais completo aqui em
  7. Me lembrei de que eu postei um programa que faz exatamente isso, nesse tópico O que importa é essa função double testa_funcao(uint64_t(*funcao)(uint64_t), uint64_t limite) { uint64_t v; clock_t tempo = clock(); for (uint64_t target = 1; target <= limite; target += 1) v = (*funcao)(target); tempo = clock() - tempo; return (double)(tempo) / CLOCKS_PER_SEC; }; // testa_funcao() no caso usada assim printf("Usando a funcao original...\n"); secsB = testa_funcao(non_fib_original, limite); printf("Tempo usando a funcao original = %6.3fs\n", secsB); printf("Usando a funcao \"nova\"...\n"); secsA = testa_funcao(non_fib_nova, limite); printf("Tempo usando a funcao nova = %6.3fs\n", secsA); printf("\nTempo nova/original = %6.3g. Performance da nova = %6.2fX da original\n", secsA/secsB, (secsB/secsA)); basta adaptar para seu caso e seria assim a declaração double testa_funcao_v(void(*f)(int[], int), int[], int); E o uso por exemplo secsA = testa_funcao_v(bubbleSort, vet, tam); secsA = testa_funcao_v(MergeSort, vet, tam); secsA = testa_funcao_v(InsertionSort, vet, tam); Ou pode juntar todas em um vetor e usar como no primeiro exemplo, uma tabela de ponteiros para funções de sort... e aí fazer suas contas.
  8. Postei esse exemplo aqui semanas atrás e faz o que você quer. No caso apenas crie uma função que recebe o endereço do vetor e o endereço da função de classificação, nos moldes da função seletor() que está no programa abaixo. Era um exemplo simles de VFT em C, uma tabela de funções, que é o que você quer. #include "stdio.h" #include <Windows.h> typedef int (*pF_int_int)(int, int); int funcao_1(int, int); int funcao_2(int, int); int funcao_3(int, int); int seletor(int, pF_int_int*); int main(int argc, char** argv) { pF_int_int VFT[4]; // nao usei f[0] so porque nao int (*pF)(int, int) = NULL; printf("\nChama as 3 funcoes pela ordem\n"); funcao_1(1, 2); funcao_2(3, 4); funcao_3(5, 6); VFT[1] = funcao_1; VFT[2] = funcao_2; VFT[3] = funcao_3; printf("\nChama as 3 funcoes a partir do vetor de enderecos\n"); VFT[1](11, 22); VFT[2](33, 44); VFT[3](55, 66); printf("\nChama as 3 funcoes a partir de uma funcao seletora\n"); for (int i = 1; i <= 3; i += 1) seletor(i, VFT); return 0; } int funcao_1(int a, int b) { printf("Ola!Esta e a funcao_1(%d,%d)\n", a, b); return 0; }; int funcao_2(int a, int b) { printf("Ola!Esta e a funcao_2(%d,%d)\n", a, b); return 0; }; int funcao_3(int a, int b) { printf("Ola!Esta e a funcao_3(%d,%d)\n", a, b); return 0; }; int seletor(int qual, pF_int_int* VFT) { if ((qual < 1) || (qual > 3)) return -1; printf("\nseletor(%d) Chama funcao_%d()\n", qual, qual); (*VFT[qual])(qual * 100, qual * 100); // chama a funcao pelo numero return 0; }; Eis a saida do programa Chama as 3 funcoes pela ordem Ola!Esta e a funcao_1(1,2) Ola!Esta e a funcao_2(3,4) Ola!Esta e a funcao_3(5,6) Chama as 3 funcoes a partir do vetor de enderecos Ola!Esta e a funcao_1(11,22) Ola!Esta e a funcao_2(33,44) Ola!Esta e a funcao_3(55,66) Chama as 3 funcoes a partir de uma funcao seletora seletor(1) Chama funcao_1() Ola!Esta e a funcao_1(100,100) seletor(2) Chama funcao_2() Ola!Esta e a funcao_2(200,200) seletor(3) Chama funcao_3() Ola!Esta e a funcao_3(300,300) Se não entender volte a escrever Essa é a linha importante do programa printf("\nChama as 3 funcoes a partir de uma funcao seletora\n"); for (int i = 1; i <= 3; i += 1) seletor(i, VFT);
  9. Faça o simples: vá até uma pizzaria em sua cidade, veja como é um pedido e como ele se integra na rotina do sistema deles. E implemente algo parecido
  10. Pena. Eu tentei mas não consegui te explicar. Templates em C++ e generics em java são aplicações do mesmo conceito, generic programming. Talvez alguém consiga te explicar melhor, ou uma documentação que não seja da Oracle ou da Microsoft. Espero que tenha entendido o que são referências, indicadores de escopo e algo de templates em C++. Afinal para quem se sentia afugentado pela linguagem agora você está discutindo conceitos. Afinal era sua "dúvida". Não, sandro, não exige. Continue estudando e vai aprender em algum momento que vector e outras coleções genéricas iteráveis incluem iterators e é igualzinho em java. Veja em https://docs.microsoft.com/pt-br/cpp/standard-library/vector-class?view=vs-2019 E entenda que begin() end() cbegin() e outros métodos retornam um iterator. E no exemplo que eu te dei o iterator fica implícito, uma facilidade que a linguagem oferece ao escrever for (auto i : vetor_de_string) cout << i << " "; O equivalente usando a declaração explícita de iterator seria for ( vector<string>::iterator it = vetor_de_string.begin(); it != vetor_de_string.end(); it++ ) { cout << *it << " "; }; // for() No primeiro caso, ao processar o auto o compilador vê que vetor_de_string é std::vector e assume que i deve ser um iterator. Não vou mais repetir: o exemplo de 20 linhas que está aqui mostra que std::vector() é uma classe genérica e usa dois vetores de classes distintas: um vetor de int e um vetor de string. Template e generic class são a mesma coisa. meu exemplo usa uma classe genérica, vetor, de STL. Não cria uma classe genérica. Preste atenção. "gerar uma lista usando a palavra vetor" não consegui entender, mas se quiser criar um vetor em java pode ver a documentação em https://docs.oracle.com/javase/8/docs/api/java/util/Vector.html#Vector-- mas de todo modo se quiser criar o mesmo vetor de string do exemplo que te dei, mas em java, escreva por exemplo import java.util.Vector; public class Main { public static void main(String[] args) { Vector Lista = new Vector<String>(); Lista.add("muito"); Lista.add("complicado"); Lista.add("esse"); Lista.add("lance"); Lista.add("de"); Lista.add("template?"); System.out.println(Lista); } // main() } // Main() e vai ter mais ou menos o mesmo resultado, já que é a mesma coisa. Vou imaginar que nas 7 horas entre uma afirmação e outra você leu o que te expliquei e entendeu que é um nome que você criou e não existe. E em java Collection é uma classe genérica afinal. Não sei o que achou engraçado então não vou poder comentar. Talvez porque eu estivesse tentando mostrar para alguém que não sabia o que era <type> como usar uma classe genérica em C++ e não como criar uma.... Rode o exemplo em seu computador. Pode rodar o outro em java que está aí em cima. Dica: é igualzinho. Se chama generic programming esse tema. Pesquise. Comece por aqui https://en.wikipedia.org/wiki/Generic_programming A grafia correta seria trouxe. Eu estava tentando mostrar algo a paritr de um tópico que falava sobre símbolos estranhos em C++ O termo não é redundância. Seria herança múltipla. Vou mostrar só mais uma vez List é uma Interface e descende de DUAS outras, as que estão aí na lista. Não está subentendido que são as mesmas coisas e não são. iterator é uma interface descrita em https://docs.oracle.com/javase/8/docs/api/java/util/Iterator.html generics é o termo em java para generic programming. Aprenda algo aqui https://docs.oracle.com/javase/tutorial/java/generics/types.html Collection é uma interface e pode ser importada de java.util. Descrita em https://docs.oracle.com/javase/8/docs/api/java/util/Collection.html Procure em https://docs.oracle.com/javase/tutorial/java/generics/types.html pelo parágrafo com esse título: A Generic Version of the Box Class e deve ajudar. Eis um resumo: Dica: é igualzinho a template class em C++ !!!! Essa discussão não está mais ajudando ninguém e você parece mais interessado em criticar linguagens e mostrar conhecimento. Talvez devesse postar essas coisas em sites como o Quora https://pt.quora.com/ Espero que tenha resolvido suas 4 dúvidas. adicionado 25 minutos depois Bem fora do tópico, mas para mostrar como é igualzinho veja a maneira "antiga" e a "nova" de usar uma classe genérica Vetor em java e compare com C++ Em java import java.util.*; public class Main { public static void main(String[] args) { Vector Lista = new Vector<String>(); Lista.add("muito"); Lista.add("complicado"); Lista.add("esse"); Lista.add("lance"); Lista.add("de"); Lista.add("template?"); Iterator it = Lista.iterator(); while( it.hasNext()) System.out.print(it.next() + " "); System.out.println(); Lista.forEach(elemento -> System.out.print(elemento + " ")); System.out.println(); } // main() } // Main() E em C++ #include <iostream> #include <vector> using namespace std; int main() { std::vector<string> vetor_de_string { "muito", "complicado", "esse", "lance", "de", "template?" }; for ( vector<string>::iterator it = vetor_de_string.begin(); it != vetor_de_string.end(); it++ ) { cout << *it << " "; }; // for() cout << endl; for (auto i : vetor_de_string) cout << i << " "; cout << endl; return 0; } Os dois mostram a mesma coisa muito complicado esse lance de template? muito complicado esse lance de template? Notou como é parecido, imagino...
  11. Não sei dizer. Fui escrevendo apenas. Mas espero que você tenha agora entendido mais do que são referências - & indicadores de escopo - :: e "generics" em C++ --- <> --- e que você tenha lido os exemplos. Espero ter ajudado. Você até reproduziu a linha que você não leu. Lá está escrito Eu não consegui, mas minha expectativa era te explicar que generic programming é um tópico de programação orientada a objetos. e em C++ se consegue isso usando templates e em java usando generic classes. E te mostrei a documentação dos dois casos. Sim, "até onde você sabe". Mas não é o caso. Já te expliquei isso. Desculpe se pareço arrogante, mas não é minha opinião. O nome em java é generic class. Te mostrei a documentação. Não é minha opinião. List é uma interface que deriva de collection e iterable e te mostrei a declaração inclusive. E collections é uma classe genérica, um container. Veja de novo e entenda que Collection e Iterable são interfaces, bem como List. Não porque EU acho. Se você ler um pouco mais disso no manual de java vai ver um exemplo da classe Box que mostra uma classe generica que pode conter qualquer tipo de objeto, tipo uma caixa, com o perdão do trocadilho. Não, não é. Porque são a mesma coisa. Não fui eu que criei isso. Você está vendo os conceitos ainda de ponta-cabeça. Talvez deva escrever mais programas com classes genéricas e vai entender melhor. Veja o código de que falou, para não ter que voltar a ele: std::vector<int> vetor_de_int{ 0,1,2,3,4,5 }; std::vector<string> vetor_de_string { "muito", "complicado", "esse", "lance", "de", "template?" }; e entenda que "meu código" não pode MESMO ser chamado de "template". Entenda que std::vector sim é uma template class, declarada assim template < class T, class Alloc = allocator<T> > class vector; // generic template E eu não "precisei" usar isso duas vezes. Eu "pude" usar e foi ótimo. Isso quer dizer que eu posso declarar vector de qualquer coisa. Sabe porque? Porque vector é uma classe genérica, template class em C++, generic class em java, coisas assim. Eu posso usar todos os métodos da classe vector com minhas classes ou com tipos primitivos. Ou mesmo vector de vector. Se eu fosse escrever uma template class ela seria escrita como @vangodp te mostrou. Eu não queria escrever uma. Queria usar uma template class da STL para não ter que escrever eu duas novas classes cheias de métodos e propriedades iguais. Se a classe não fosse genérica seria preciso reescrever vector para cada classe que fosse usar: vector para MyClass, vector para int, vector para float. Isso é o que generic programming resolve. Não é "meu docs". É a documentação oficial. Collection List Generics é um termo que você criou. Já te expliquei várias vezes. A propósito, o .Net Framework tem um namespace System.Collections.Generic onde estão ... interfaces genéricas. Talvez deva postar isso no forum de java, mas de todo modo tem um exemplo aqui em https://docs.oracle.com/javase/tutorial/java/generics/types.html onde fala dessa classe Box --- caixa --- e a ideia é mostrar que por ser genérica a tal classe Box pode conter qualquer objeto, inclusive outras caixas... Você não pode usar tipos primitivos diretamente, mas isso não é relevante já que java tem um recurso chamado autoBoxing que permite encapsular os tipos primitivos e por na classe genérica. Não sei nada sobre a natureza ou futuro dessas empresas. Note que o Windows inclui há uns dois anos um kernel Linux, basta habilitar em "recursos avançados do Windows". E na loja do Windows tem distribuições como Kali, Ubuntu e SUSE que você pode instalar de graça com um click. E um IDE para o Linux que roda no Linux ou no Windows.
  12. Mais uma coisa: pode ser que seu compilador esteja compilando no padrão C++98 e não em C++11 ou posterior. E nesse caso esse formato de inicialização não é válido Você devia ter desconfiado quando colocou o comentário em reserved... Porque não fez o mesmo na inicialização de header? O outro erro Você não pode escrever header[0] = 'B'; header[1] = 'M'; em uma declaração de classe porque não há memória alocada para isso. Uma classe é uma classe e uma instância é uma instância. Você pode definir esses valores junto com o resto do header em write() por exemplo. Veja com atenção uma alteração que funcionaria em C++98: FileHeader fileHeader; InfoHeader infoHeader; fileHeader.header[0] = 'B'; // fileHeader e uma instancia da classe fileHeader.header[1] = 'M'; // entao pode atribuir valores fileHeader.reserved = 0; fileHeader.dataOffset = 0; fileHeader.fileSize = sizeof(FileHeader) + sizeof(InfoHeader) + data_size; fileHeader.dataOffset = sizeof(FileHeader) + sizeof(InfoHeader); infoHeader.width = width; infoHeader.height = height; fileHeader é uma instância da classe FileHeader, e aloca memória de acordo. infoHeader é uma instância da classe InfoHeader e aloca memória de acordo. E aí você pode definir os valores como manda o padrão para o formato bitmap. FileHeader DoisMilDessesHeaders[2000]; // 2.000 instâncias da classe FileHeader por exemplo aloca espaço para 2000 deles e você pode acessar qualquer um. Desculpe não ter visto antes ou ter anotado no programa. Lembrei por acaso. Um pouco off-topic Sugiro sempre usar o padrão mais recente. Tem muita coisa legal em C++11, 14, 17... Esses comandos {} são bem interessantes por exemplo Veja esse programa que eu postei ontem neste mesmo forum #include <iostream> #include <vector> using namespace std; int main() { std::vector<int> vetor_de_int{ 0,1,2,3,4,5 }; std::vector<string> vetor_de_string { "muito", "complicado", "esse", "lance", "de", "template?" }; cout << "Para um vetor de <int>" << endl; for (auto i : vetor_de_int) cout << i << " "; cout << endl; cout << "Para um vetor de <string>" << endl; for (auto i : vetor_de_string) cout << i << " "; cout << endl; cout << "Vale a pena aprender: economiza muito tempo" << endl; return 0; } O fato de poder inicializar vetores assim é bem prático. {} indica que é pra zerar o campo todo auto faz com que o compilador identifique o tipo da variável pelo contexto e tem um alcance enorme, em especial quando associado a um troço chamado trailing return type. Se se interessar veja uns exemplos em https://www.ibm.com/developerworks/community/blogs/5894415f-be62-4bc0-81c5-3956e82276f3/entry/introduction_to_the_c_11_feature_trailing_return_types?lang=en claro que há muitas outras coisas do padrão '98 para cá Não quero iniciar discussões religiosas, mas de um ponto de vista prático: Visual Studio tendo uma versão community VSCode compilando para Unix em Windows com várias distribuições Linux disponíveis de graça com um click na loja do Windows sem ter que sair do Windows Ficou difícil justificar o uso de outro ambiente.
  13. acho que sumiu o #include para <iostream> adicionado 4 minutos depois #pragma pack(push, 2) Se o bitmap estiver de algum modo corrompido veja como seu compilador implementa esse troço. É pra ser assim em todos mas... bitmap.fillBitmap(128, 128, 128); bitmap.write("test128.bmp"); para conferir 128 é metade de 256 então isso gera um bitmap com um cinza bem suave.
  14. Isso não acontece quando você compila o seu programa e sim quando você executa o programa. Se você o levar paa outra máquina e rodar lá vai dar na mesma. Em seu programa Em linhas consecutivas você escreveu coisas diferentes então deve ter um resultado para a primeira linha e outro para as seguintes. É mais importante saber o porque do 1: C usa aritmética de ponteiros então a diferença entre elementos consecutivos do array d é 1. O que você queria era a diferença em bytes entre cada elemento e essa é (1 * sizeof(int)) e vai depender de sua máquina. Em geral 4 bytes.
  15. Imagino que se leu os tópicos aqui e os programas que te mostrei tenha entendido que os símbolos não são assim tão estranhos e exóticos. São até bem úteis. Apenas você talvez não conhecesse direito não são recursos assim "avançados": são de uso comum não vão acabar com tudo que aprendeu. Apenas vão somar ao que você já sabia: & indica referência, :: tem o outro uso que te mostrei, e templates são o que expliquei E espero que não se sinta mais "afugentado" da linguagem. Há aspectos talvez mais sinistros nessa linguagem, como lambdas, functors, herança múltipla, contrutores diversos, ou operadores com novos significados definidos pelo usuário para suas classes. Ainda sobre isso... Veja na documentação em https://docs.microsoft.com/en-us/cpp/cpp/templates-cpp?view=vs-2019 e entenda que esse é o nome dado em C++. Não é o caso. Você misturou os conceitos. Esse é um campo em OOP chamado generic programming, como está até escrito aí em cima na documentação da MS sobre templates. Em java isso foi introduzido como "java generics" . Veja na documentação por exemplo em https://docs.oracle.com/javase/tutorial/java/generics/types.html e vai ler coisas como E note a definição de generic class Claro que você pode chamar isso com o nome que quiser, mas entenda que Collection na verdade é uma classe que faz obviamente largo uso de generics porque assim fica muito mais útil. E list é uma classe que "herda de" Collection<E> e Iterable<E> , como pode ver em https://docs.oracle.com/javase/8/docs/api/java/util/List.html Veja o simples, a documentação da Oracle em https://docs.oracle.com/javase/8/docs/api/?java/util/Collections.html Você parece achar que esse "contrato" é uma limitação quando escreve que E na verdade essa isso que você chama de "obrigação" é justamente o que o nome diz: uma óbvia generalização. Generics. O contrato normalmente seria declarar um objeto como sendo de UMA classe. Uma só. E você teria um vetor de int, um vetor de char, um vetor de MinhaClasse.... Mas acho que já entendeu: com generics você pode usar <> e a classe serve para vários tipos... Note que na documentação sobre listas em java ela também descende de Iterable. É assim em C++ também: faz total sentido ao ter uma coleção usar algum tipo de iteração, certo? Isso não é nada relevante: muitos dos acessórios do Windows tem décadas de idade e são muito simples. Não há razão para reescrever uma calculadora ou o bloco de notas or o Write para usar classes do .Net. Um anti'vírus? Não. São ferramentas simples, com interfaces simples, mas é bem provável que a interface em si tenha usado .Net e Visual Studio. E Visual Studio, o ambiente de desenvolvimento, usa .Net ... Você ainda não entendeu uma parte importante disso: java roda em uma máquina virtual, @sandrofabres e então seria realmente um paradoxo usar java para recuperar sistemas. É preciso ter um sistema rodando, para ter a JVM rodando para poder rodar seu programa em java... Não, não. Entenda que Microsoft criou uma linguagem, C#, para ter uma ferramenta de desenvolvimento similar ao java. É uma confusão comum. C# é a linguagem. .Net é um framework, uma biblioteca gigante de classes tornada recentemente open source, com versoões para Linux e Mac. java tem seus próprios frameworks, como Google GWT, java Server Faces, Apache Struts e muitos muitos outros. Parece sugerir que o mundo empresarial seja algo pequenino... "Só" no mundo empresarial é uma afirmação interessante. Se usa .Net onde é vantagem usar, porque essas classes aceleram muito o desenvolvimento de aplicações de diversos tipos e ninguém quer escrever tudo de novo. Mesmo no mundo acadêmico. E o mundo acadêmico não é um fim em si mesmo. De https://dotnet.microsoft.com/ java não é outra .Net. Acho que o que pretendia dizer é que C# da Microsoft é "outra java". .Net não nasceu de java..Net gera programas para rodar num ambiente chamado CLR e cria esse conceito de managed code segundo a MS, então é um código interpreptado e uma máquina virtual, de certo modo. Só que esses conceitos vem de muito antes. Veja por exemplo o UCSD P-System, dos '70/'80 que gerava um tal de p-code para uma máquina virtual, e vai achar bem familiar. E o VM/CMS dos '80 que usava máquinas virtuaís nos mainframes dos anos 80...
  16. Atente para o que está escrito na mensagem de erro Veja o código void Petismo(int *bEleitor) { int *lula = &bEleitor; *lula = 13; } Isso dá na mesma que escrever int* bEleitor; int* lula; mas ao escrever desse modo ajuda a ler que bEleitor é um ponteiro para int e lula é um ponteiro para int. Quando você escreveu &bEleitor está buscando o endereço de um ponteiro para int, e o resultado então seria int** E quando você escreve *lula = &bEleitor está atribuindo a um int* um valor int**, que é exatamente o que diz a mensagem de erro. E não há razão para declarar outra variável, já que poderia escrever simplesmente *bEleitor = 13; Em geral é melhor descobrir o que está errado do que ir mudando a olho até parecer certo.
  17. @sandrofabres Não, não desista. C++ é uma linguagem enorme e complexa. Não me leve a mal mas talvez apenas você pudesse ter uma aproximação mais humilde em relação a essas coisas. Vou mostrar uns exemplos sobre esses 4 pontos para você porque são pontos interessantes e um exemplo pode ser útil também para outros leitores eventualmente. Tenha paciência porque posso ser desses que escrevem exemplos enormes sem sentido Talvez você esteja classificando essas linguagens muito rápido para um iniciante ou saiba demais sobre elas. .Net é um framework gigante e escrever um programa usando isso nunca me fez achar que estava brincando de programar. java é também uma linguagem enorme e bem similar a C++ em muitos aspectos, como o tratamento de classes. Aí eu não sei julgar ou comentar. Depreciar um exemplo que recebeu de graça por um suposto especialista ou em site como o http://www.cplusplus.com por ser "grande" ou "corretinho" talvez esteja além da capacidade de julgamento de um auto-intitulado iniciante. E no geral não é uma atitude elegante ou respeitosa. Vou te mostrar exemplos relacionados a suas "dúvidas" se é que você tem dúvidas. Espero que ache "corretinho" porque estão certos. Não me leve a mal, mas você pode apenas não ter entendido. Pode ter lido na ordem errada. Pode não ter ainda experiência para ler esses exemplos... De volta aos tais exemplos em C++ Entenda que nesse caso o & está a direita do tipo também. Eu até recomendo declarar assim para quem está inciando porque a verdade é essa: 'e' é uma referência para XButtonEvent, constante. Pois é: você não aprendeu que, como em C, declarar int a; int& b = a; int &c = a; declara b e c como referências a a, algo como um ponteiro. Não vou explicar o que acontece em relação a classes passadas por referência e execução de construtores e coisas assim, porque aqui basta o exemplo com tipos primitivos, já que você ainda não conhecia isso. Veja esse trecho: using namespace std; class AltaClasse { public: void mostra(int& r); }; void mostra(int); tem duas funções mostra() que recebem um int e o alteram: void AltaClasse::mostra(int& r) { cout << "em mostra() na classe X valor = " << r << endl; r = 200220; cout << "em mostra() na classe X valor = " << r << endl; }; // mostra() E essa void mostra(int r) { cout << "em mostra() na area global = " << r << endl; r = 200219; cout << "em mostra() na area global = " << r << endl; }; // mostra() E esse trecho de programa AltaClasse a; auto valor = 2; cout << "valor em main() " << valor << endl; ::mostra(valor); cout << "valor em main() " << valor << endl; a.mostra(valor); cout << "valor em main() " << valor << endl; E ele mostra valor em main() 2 em mostra() na area global = 2 em mostra() na area global = 200219 valor em main() 2 em mostra() na classe X valor = 2 em mostra() na classe X valor = 200220 valor em main() 200220 E aí você entende que ao passar o valor por referência a alteração de valor na função permanece ao retornar para main: é a mesma variável. E na rotina que está fora da classe o valor é copiado então a alteracão se perde ao retornar para main() Note o tal operador :: esse vou discutir a seguir. Pois é: você não aprendeu sobre a existência de TEMPLATES. Isso é o que significam esses operadores <tipo> chamados por alguns de parenteses angulares. Isso é igualzinho em java então também não aprendeu em java, uma das linguagens que criticou inicialmente. Isso aí quer dizer que a classe Position é uma classe que opera possivelmente com vários tipos e nesse caso vai usar int. Atente para o exemplo abaixo Veja esse pequeno programa #include <iostream> #include <vector> using namespace std; int main() { std::vector<int> vetor_de_int{ 0,1,2,3,4,5 }; std::vector<string> vetor_de_string { "muito", "complicado", "esse", "lance", "de", "template?" }; cout << "Para um vetor de <int>" << endl; for (auto i : vetor_de_int) cout << i << " "; cout << endl; cout << "Para um vetor de <string>" << endl; for (auto i : vetor_de_string) cout << i << " "; cout << endl; cout << "Vale a pena aprender: economiza muito tempo" << endl; return 0; } Essas linhas std::vector<int> vetor_de_int{ 0,1,2,3,4,5 }; std::vector<string> vetor_de_string { "muito", "complicado", "esse", "lance", "de", "template?" }; declaram e iniciam dois vetores, um com int e outro com strings, USANDO AS MESMAS CLASSES. Isso é genial e economiza um tempo do c@r@&*o porque você usa as mesmas funções com qualquer tipo. Isso é por exemplo a STL, biblioteca padrão de templates, onde você tem filas, vetores, árvores, mapas, o diabo. Só declarar e usar. E funciona com suas classes e você não tem que programar tudo de novo. É assim também com o framework .Net. Pois é: você não aprendeu ainda que esse operador :: se chama operador de resolucão de escopo e pode ser a sua salvação para acessar algo no escopo global e que tenha desaparecido no escopo atual. Imagino que não tenha entendido então vou te mostrar um exemplo "certinho" Exemplo #include <iostream> using namespace std; string str = "valor na area global"; int main() { { auto str = "valor declarado em main"; cout << "'str' declarada em main [" << str << "]" << endl; cout << "'str' global que teria sumido [" << ::str << "]" << endl; cout << endl; } cout << "'str' em main fora do {} [" << str << "]" << endl; return 0; }; // main() mostra 'str' declarada em main [valor declarado em main] 'str' global que teria sumido [valor na area global] 'str' em main fora do {} [valor na area global] Se você não PREFIXAR str por :: para indicar o escopo global str sempre vai ser a variável declarada em main(), dentro dos {} em que a outra str está declarada. Fora deles --- mas claro ainda dentro de main --- a declaração auto str = "valor declarado em main"; fica fora de escopo e aí volta a ser visível a str global. Pois é: se leu até aqui já sabe que é outro TEMPLATE e que simplesmente indica que essa rotina vai retornar um unique_ptr para a classe Window_Manager Espero que tenha entendido algo. Se quiser os programas de teste inteiros avise e eu posto aqui. não tem mais que umas 20 linhas cada um. Se tiver dúvidas volte a escrever.
  18. Ler e imprimir as coordenadas de dois pontos não é assim importante. Podia ter começado a pensar com constantes mesmo. Se você tem v1(x,y) e v2(z,t) no mesmo plano, então ou eles são o mesmo ponto ou formam um retângulo, certo? Se você considerar um ponto como um retângulo o único ponto dentro do retângulo é o próprio, claro Agora sobre o vértice inferior esquerdo e superior direito: esquerdo e direito é o valor de x certo? E inferior e superior é o valor da coordenada y certo? pode ser que os dois pontos tenham o mesmo x e aí você tem uma linha vertical. Tipo um retângulo bem fininho e todos os pontos com a segunda coordenada entre y e t estariam dentro Pode ser que os dois pontos tenham o mesmo y e aí você tem uma linha horizontal. Tipo outro retângulo bem fininho e todos os pontos com a primeira coordenada entre x e z estariam dentro Se os pontos são distintos então tem mesmo um retângulo e os pontos que estão dentro do retângulo são... Os que estão dentro do retângulo. Basta olhar as coordenadas entre os limites x/z e y/t... Mais aritmética do que programação
  19. O programa que postei meses atrás tinha uma função unsigned int proximo_primo(unsigned int n); E como dá pra imaginar ela retorna o próximo primo a cada chamada. É praticamente a solução para o seu problema, já que pode usar isso para ir fatorando seu número e contando o número de fatores primos e pronto... Pode ler a discussão lá. Para resumir aqui abaixo tem o mínimo do código. Funciona direitinho. É só matemática afinal. Se não entendeu como isso se aplica ao seu problema, escreva de novo int retorna_um_se_primo(unsigned int n) { if (n < 2) return 0; if (n == 2) return(1); if (n % 2 == 0) return(0); unsigned int maior = (unsigned int)sqrt((double)n); unsigned int fator = 3; while (fator <= maior) { if (n % fator == 0) return 0; fator += 2; } // end while return 1; } // end retorna_zero_se_primo() unsigned int proximo_primo(unsigned int n) { static int iniciado = 0; static int proximo = 0; if (n == 0) // inicia a serie { iniciado = 1; proximo = 2; return 1; } // end if if(iniciado == 0) return 0; // erro: tem que chamar com 0 antes if (proximo == 2) { proximo = 1; return 2; } // end if // normal: a a partir daqui retorna o proximo primo for (int i = proximo+2;;i += 2) if (retorna_um_se_primo(i)) { proximo = i; return proximo; } // end if } // end proximo_primo()
  20. Estive procurando um exemplo de como endereçar uma área para acessar com 1 índice ou 2 ou talvez mais e não encontrei quase nada, exceto por umas notas no conhecido C FAQ em http://c-faq.com/about.html Então escrevi um exemplo e vou postar aqui. Talvez ajude alguém em algo que eu acho um inferno: como acessar algo assim. Não há razão para uma classe aqui: basta uma struct e assim pode ser usado em C também o mesmo código, ou quase. A estrutura é uma bobagem, só para exemplo, e é algo como uma variante, ou tagged union como se lê às vezes: struct multiD { int len; union { int(*x1D)[60]; int(*x2D)[4][15]; int(*x3D)[3][4][5]; int(*x4D)[2][3][2][5]; int(*x5D)[1][2][2][3][5]; }; }; É só para mostrar como declarar ponteiros para vetores como usar uma union anônima --- sem nome --- para acessar a mesma área na memória com variáveis alternativas, o tal registro variante O programa é bem linear: aloca o vetor com 60 posições, int, e numera todas de 00 a 59 acessa o vetor como uma matriz de 1 a 5 dimensões e mostra como acessar os valores usando os operadores tradicionais []. Usando ponteiros é mais simples e tem um programa aqui no forum que mostra isso, de umas semanas atrás. Pesquise por Tanenbaun + índices + arfneto e deve aparecer. O objetivo aqui era usar os colchetes. mostra todos os valores nas possíveis dimensões mostra o último valor em cada matriz para ver que é o mesmo 59 Veja o final da saída do programa O ultimo elemento, visto com 1 a 5 indices, deve ser o mesmo: 1D v[59] = 59 2D v[3][14] = 59 3D v[2][3][4] = 59 4D v[1][2][1][4] = 59 5D v[0][1][1][2][4] = 59 ARFNETO 2020 O programa é simples, e gira em torno da struct e dessa função void mostra(multiD* matriz, int planos){}; que recebe uma struct e acessa com os índices certos para o número de planos passado... Veja o caso para uma dimensão, usando ponteiros porque eu esqueci que ia usar só índices e agora não vou mudar mais case 1: // int(*x1D)[60]; for (int i = 0; i < matriz->len; i += 1) { std::cout << setw(2) << i << ": " << setw(2) << *(*(matriz->x1D) + i) << " "; if (i % 10 == 9) cout << endl; }; // for break; E para 3 case 3: // int (*x3D)[3][4][5]; for (int i = 0; i < 3; i += 1) for (int j = 0; j < 4; j += 1) for (int k = 0; k < 5; k += 1) std::cout << "(" << setw(2) << i << "," << setw(2) << j << "," << setw(2) << k << ") = " << (*matriz->x3D)[i][j][k] << endl; break; E um trecho do programa principal // exemplos de vetores xD int v1D[60]; int v2D[4][15]; int v3D[3][4][5]; int v4D[2][3][2][5]; int v5D[1][2][2][3][5]; multiD teste; // estrutura de teste teste.len = 60; teste.x1D = &v1D;// so testes, para mostrar o acesso teste.x2D = &v2D;// so testes, para mostrar o acesso teste.x3D = &v3D;// so testes, para mostrar o acesso teste.x4D = &v4D;// so testes, para mostrar o acesso teste.x5D = &v5D;// so testes, para mostrar o acesso // preenche usando o vetor v1D teste.x1D = &v1D; // for (int i = 0; i < teste.len; i += 1) *(*(teste.x1D) + i) = i; // igual for (int i = 0; i < teste.len; i += 1) (*teste.x1D)[i] = i; // mostra a mesma area de 1 a 5 dimensoes for (int i = 1; i <= 5; i += 1) mostra(&teste, i); // nada a liberar: so usamos valores estaticos // agora mostra o ultimo elemento de cada vetor cout << "\nO ultimo elemento, visto com 1 a 5 indices, deve ser o mesmo:\n" << endl; cout << "1D v[59] = " << (*teste.x1D)[59] << endl; cout << "2D v[3][14] = " << (*teste.x2D)[3][14] << endl; cout << "3D v[2][3][4] = " << (*teste.x3D)[2][3][4] << endl; cout << "4D v[1][2][1][4] = " << (*teste.x4D)[1][2][1][4] << endl; cout << "5D v[0][1][1][2][4] = " << (*teste.x5D)[0][1][1][2][4] << endl; Se alguém precisar, o programa pode ser baixado aqui, ou lido lido aqui O que importa é só como declarar e como acessar as diferentes matrizes, e o lance da variante, que é um conceito muito útil para quando você vai receber um registro que tem um certo número de formatos, dependendo muitas vezes de algum prefixo identificador
  21. Não sei se entendi, mas você pode gerar o código em HTML no arquivo de saída do seu programa em C e assim não ter que mexer em nada para colar do outro lado, se é disso que precisa
  22. Não. Windows 10 é mais esperto apenas. Algo que não é estranho já que Windows 7 foi lançado em 2009 Talvez pudesse explicar o que não está conseguindo. Seu IDE vai usar o compilador externo para gerar um arquivo executável. Só isso. Ele fez isso? Achou o executavel? Achou onde abrir a janela do prompt de comando? Viu a imagem que te mostrei com as 3 janelas abertas?
  23. Dev C++ é um ambiente de desenvolvimento. Ele usa um compilador externo, tipo gcc ou mingw ou algo assim. Eu não uso esse ambiente. Mas o fato é que ele acaba gerando um executável, um arquivo que deve ter o mesmo nome que seu programa em c. pgm.c gera pgm.exe por exemplo. Esse pgm.exe você pode levar para qualquer computador e rodar. Só digitando o nome. Afinal é para isso que a gente um programa: para rodar em outras máquinas. Dev C++ já cumpriu seu papel quando seu programa ficou pronto. Você pode rodar o programa direto no executar do Windows, e no seu caso serviria até. Mas em geral você abre uma janela de comando, rodando Windows+R e CMD e ENTER. Isso porque a janela de execução de seu programa fecha ao final do programa e isso pode deixar o usuário inseguro. Um outro caminho, mais comprido, aperta iniciar e escreve "prompt de comando" claro que não precisa escrever tudo. Já vai apareer na tela: Na janela que vai abrir, a tal "Prompt de comando" você digita o nome do seu programa. O nome completo. É essa sua dúvida? Viu a janela que eu postei com a imagem do terminal rodando isso?
  24. Viu o exemplo que te mostrei? É só isso. Você põe seu código no programa que eu mostrei, no lugar daquele for que imprime as linhas de teste. E seu programa gera o arquivo com o nome que voce quiser e o notepad abre em seguida o arquivo novo... ch-testec arquivo.txt && notepad arquivo.txt Assim. Viu a imagem da tela?
  25. Entendo. A documentação diz que esses mecanismos de acesso à área de transferência são reservados para projetos do tipo desktop e não para programas de console, mas acho que ao menos em C++ deve ser possível replicar o funcionamento. Testei algumas das funções e parece que todas funcionam no ambiente da console. Mas é um processo complicado para de fato criar um teste completo. Se eu tiver tempo de criar um programa eu posto aqui. Em essência o problema é que a área de transferência é uma área global de transferência, e pode conter um número enorme de coisas diferentes, algumas até criadas pelo usuário. E pode ter apenas um "dono" por vez na hora de gravar. E tem que alocar um recurso global e pode conter por exemplo um texto, ou uma foto, ou uma lista de arquivos, como quando você arrasta um ícone de um programa para a janela do compilador e ele abre o arquivo --- não sei se o compilador que usa faz isso., mas acho que entendeu o exemplo: drag & drop se chama. Programas de console vivem em um ambiente mais ou menos separado no Windows, e fica difícil e muitas vezes impossível usar coisas dos projetos desktop. Em C# você tem uma classe clipboard que tem essas funções facinho. Em C++ usando aplicações de console precisaria testar mais com a documentação que te passei antes. Para desktop seria tranquilo. De todo modo, para o seu problema talvez não precise passar por isso. Sugiro não rodar programas do prompt do compilador. Não faz sentido. Arrume seu programa e gere um executável. Não há razão para compilar e gerar o mesmo código toda vez que faz um orçamento. Mude seu programa para gerar, além da saída na tela que já te atende, uma saída em um arquivo de texto, via fprintf() que é igualzinho ao printf(). E nesse arquivo gere exatamente no formato que quer importar pro mercado livre. Gere um atalho para rodar o seu programa e um atalho para abrir por exemplo o Bloco de Notas com o seu texto. Clica no atalho de seu programa e gera o orçamento Clica no atalho do notepad e abre o novo arquivo gerado No bloco de notas, control A seleciona o texto todo, Control C copia. E vai tudo certo já que foi você que escreveu o programa No mercado livre, control V copia o orçamento E a vida segue Um exemplo mais integrado: Claro, não use telas maximizadas no Windows. São muito pouco produtivas e não vai conseguir fazer o que estou explicando. E quando são produtivas o próprio programa terá um atalho para isso. Meu compilador usa Alt-Shift-Enter, o Windows em geral usa F11, como o navegador Edge, o navegador Chrome... Na tela do prompt de comando: para rodar o programa de novo para um próximo orçamento basta usar a seta para cima --- veja na imagem abaixo No notepad control-O abre um novo arquivo, mas pode só fechar o programa e abrir com o atalho que ele abre na mesma posição na janela... E no fundo nem precisa do atalho porque pode abrir o bloco de notas com o arquivo gerado pelo programa usando o próprio prompt de comando Se você tiver um programa de orçamento C chamado ch-testec.c vai gerar um executável ch-testec.exe. Se seu programa exigir um argumento com o nome do arquivo de teste pode abrir o orçamento direto no NotePad assim por exemplo ch-testec arquivo.txt && notepad arquivo.txt O efeito do "&&" é chamar o comando seguinte --- notepad arquivo.txt --- se o comando anterior --- ch-testec arquivo.txt --- retornou ok. Ou seja, o seu programa retornou 0 em main(). E aí o orçamento gerado já abre no bloco de notas... Se for importante você pode até usar um arquivo .BAT e ir numerando os orçamentos, como arquivo1.txt, arquivo2.txt ... de modo a não perder nenhum se for importante. Aberto no bloco de notas você usa Control-A, Control-C e vai no mercado livre com alt-TAB se já está com o site aberto, e já cola o orçamento com control-C claro Veja uma tela assim, depois de rodar o programa: E um protótipo do programa #define _CRT_SECURE_NO_WARNINGS #include "stdio.h" #include "stdlib.h" int main(int argc, char** argv) { if (argc < 2) { fprintf(stderr, "\nCancelando: Faltou o nome do arquivo de saida\n\n"); return -1; } FILE* saida = fopen(argv[1], "w"); if (saida == NULL) { fprintf(stderr, "Nao conseguiu abrir [%s]\n", argv[1] ); return -1; } fprintf(stderr, "Criado [%s]\n", argv[1]); fprintf(saida, "gerado pelo programa\n"); for (int i = 1; i <= 10; i += 1) fprintf(saida, "Orcamento linha %02d\n", i); fclose(saida); }; // main() E para rodar o programa de novo basta voltar no prompt e usar a seta para cima... Acha que serve?

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

LANÇAMENTO!

eletronica2025-popup.jpg


CLIQUE AQUI E BAIXE AGORA MESMO!