Ir ao conteúdo

arfneto

Membro Pleno
  • Posts

    6.526
  • Cadastrado em

  • Última visita

Tudo que arfneto postou

  1. Li o enunciado. A única variação do usual --- ok, não jogo isso há eras --- acho que é a possibilidade de marcas as células suspeitas, ou desmarcar. Ou já tinha e eu nem sabia e marcava num papel . Mas isso não é nada complexo, basta acrescentar um estado a mais para as células e controlar o total de células marcadas para não estourar o limite. Programe a entrada em separado, a parte do programa que pega os valores e faz a validação. E teste. E guarde. Você já fez bolo de festa? É algo assim tem o recheio, a cobertura a massa, a decoração... Espero que não fique brava com as analogia bestas... Mas abstração é importante na programação... Vai ter trabalho para terminar isso em dois dias, em especial se não puder dispor de muito tempo só pra esse programa. Para não perder tempo, já que o jogo aparentemente é familiar para você, escreva um programa que lê os valores do usuário, linhas, colunas, semente e tal. E valida e mostra na tela. Guarde. Pense numa estrutura de dados para gravar isso, pode ser mesmo o simples m*n células, z minas e cada célula tem um estado, como no enunciado: marcado, desmarcado, aberto. Talvez marcado com mina e marcado sem mina, que tal? assim não precisa marcar as minas em outro lugar... Se a sua estrutura se chamar Grade pode escrever algo assim struct Grade * define_grade(short m, short n, short z); que cria uma grade e devolve pro seu programa. Entende isso? Já devolve a grade populada com as minas e com os estados das células ok. Pense em uma definição para Grade que descreva bem o problema. Nem mais nem menos. Um dia isso foi um jogo de tabuleiro, onde você recebia continhas coloridas pra marcar as minas e pinos coloridos para marcas os resultaos, e jogava um contra o outro. Tinha a versão da batalha naval e mais mil variantes... Saberia escrever esses dois?
  2. Entendo. Acho sacanagem esperar que um aluno se vire pra fazer um terceiro programa assim. Espero que tenha um bom prazo, mas não quero que desanime. O primeiro programa deve ter te dado essa noção de "receita de bolo", imagino Perfeito. Mas conhece campo minado? tem em seu computador? Jogou mesmo? Ganhou, perdeu e tal? É muito importante isso. E aquela parada de que falei de preparar o jogo para alguém é importante. Se ficar sem graça de fazer com alguém pode fazer com você mesma, no papel. Podia mandar pra mim mas ia levar dias pra jogar. Sério, preparar o mapa, mesmo que 3x3, acompanhar os resultados de cada palpite, atualizar o mapa, preparar o tabuleiro. Fazendo isso umas vezes vai ajudar muito a entender a dinâmica disso. Acho que a parte mais delicada é quando o sujeito seleciona uma célula vazia e aí você, como a controladora do jogo ou o seu programa, tem que ir abrindo as células em volta da célula vazia que o cara escolheu, e a área vazia vai se espalhando. Sabe mesmo como é isso? Não? Jogue! É de graça. Até entender claramente. Tem na loja do Windows 10 por exemplo. Vi agora. Nunca pensei em programar isso, mas pode ser um exercício interessante. Mas repito: não tente fazer tudo ao mesmo tempo, ver o programa como uma coisa só. Não é e você vai perder um tempo enorme se fizer isso. Pense no seu segundo programa, o das funções. Vai ser essencial. Pense na parte do "sorteio" das minas, veja se está claro como faz pra selecionar os campos, faça um pequeno programa de teste. Pense na entrada, como seria a chamada do programa. Codifique uma função main() pra pegar os valores e mostrar na tela, só isso. E irá progredindo rápido. C é uma linguagem bem legal, eu acho. Quando se sentir criativa, escolhendo maneiras de fazer ao invés de lutar pra achar uma, talvez goste mais de programar, ou odeie menos.... E pode nem demorar Bom trabalho
  3. Olá! Meu palpite, com umas perguntas. Acho que esse não deve ser seu primeiro ou segundo programa em C, ou em qualquer outra linguagem. Em geral os caras guardam esses problemas para entregar em período, depois de fazer outros programas menores. É esse o caso? Já escreveu um certo número de pequenos programas para se acostumar com o fluxo dessas coisas? Não o do programa em si, mas compilar, separar as coisas, testar, ler valores do teclado ou de arquivos, escrever na tela ou em arquivos? Ajudaria saber o que você já sabe, para não ficar escrevendo coisas chatas ou redundantes e nem ficar, por outro lado, escrevendo o que você não entende ainda. Li seu "requerimento", o arquivo. Está bem escrito. A minha primeira sugestão: se você não conhece o jogo, jogue um pouco até ter a mecânica dele clara. Não se preocupe em programar p$%%@ nenhuma, apenas no jogo. Ganhar, perder, a rotina. Depois: pense só no jogo também, mas nesse sentido: você e mais um jogador. Você tem umas folhas com um tabuleiro, tipo 3x3 só pra pensar. e você vai ter um pra você com as minas, tipo 2 minas só em 9 posições. E na mesa na sua frente seu amigo vai jogar: então você marca as minas num tabuleiro que você guarda. E dá um formulário tabuleiro pra ele. Ele vai jogando começa marcando as posições falando pra você que diz pra ele se acertou em algo e vai atualizando o tabuleiro. Aí você está mais em condições de programar o serviço, depois de ter jogados umas vezes e de ter pensado nessa simulação com um amigo que pode ser você mesma... Receitas de bolo podem ser bem complexas... E a partir daí você pensa em escrever pequenas partes do serviço, partes que possa testar em separado e ir se acostumando com o problema e com os métodos de solução. Ex: - uma função de desenha um tabuleiro de um certo tamanho - uma função que faz o sorteio da posição das minas - uma função que atualiza o tabuleiro Coisas assim que possa testar em separado e possa por exemplo postar aqui e perguntar algo. Assim vai se aproximando da solução. Esse é um programa relativamente grande para você começar pensando nele todo sem experiência.. Bom trabalho
  4. Isso era de uma época anterior aos micros E anterior ao Windows. Não existia computador "pessoal". Os computadores eram chamados de mainframes, ocupavam andares inteiros e eram acessados a partir de terminais, monitores com teclados como esse da foto.Isso os mais modernos da época. Não eram terminais gráficos nem tinham cor. Apenas fósforo verde ou ambar as vezes. Em geral tinham 24 linhas por 80 colunas apenas. Muitos não tinham letras minusculas, alguns tinham uma tecla para ativar se você precisasse mesmo de minúsculas. IBM 3278 era o clássico terminal. Os computadores em geral rodando OS/VS ou DOS/VS ou depois VM/CMS --- que era virtualização nos anos 80. As linguagens eram basicamente COBOL e FORTRAN e ASSEMBLER. Mas havia opções como APL, Algol e até Pascal dependendo do ano. Mas isso é assunto para um outro tópico
  5. Muito bom ficou bem complexo
  6. @misterjohn Estudei COBOL nos anos 70. Nem tenho ideia de quantos programas escrevi nessa linguagem Sim, é uma linguagem. Bem interessante até. Hoje não é muito divulgada mas parece haver ainda uma enorme quantia de programas escritos em COBOL rodando no mundo. Vi umas matérias nos últimos dias falando sobre gente sendo treinada atualmente para programar em COBOL Isso que listou não sei o que é não. Era isso mesmo? A única coisa assim cheia de símbolos que já usei foi uma linguagem chamada APL e era bem legal. Veja esse teclado com os símbolos em laranja de https://geekhack.org/index.php?topic=93923.0 Escrevi alguns programas em APL. Eu estudava matemática afinal e tinha a ver, mas nem me lembro o que faziam
  7. @misterjohn programar computadores pode ser um hobby bacana. Mas gasta muito tempo eu acho
  8. @misterjohn Imagino que seja um trabalho de faculdade: o autor precisa rodar um programa para todos os arquivos de uma pasta no micro, tipo pegar uma pasta de mídia do seu servidor e fazer algum tipo de análise em TODOS os arquivos da pasta. Abraço Errei. Esse era outro tópico. Esse aqui deve ser algo sobre um curso de estruturas de dados imagino, e precisa testar essa estrutura chamada pilha. Em resumo esse tipo de pilha é como a pilha de pratos no restaurante: você coloca os elementos em cima e vai tirando primeiro os que colocou por ultimo...
  9. @isrnick Ainda não entendo onde quer chegar: Essa discussão começou como sabe em outro tópico, onde você também escreveu. De lá vem a consideração de "moderna" para essa opção, não porque ela tenha de fato pouca idade, mas por um detalhe bem óbvio e que foi listado lá: Em https://docs.microsoft.com/pt-br/windows/desktop/FileIO/listing-the-files-in-a-directory na documentação oficial da empresa que escreveu o Windows e onde é colaborador o próprio criador da linguagem, Dr. Bjarne Stroustrup, está um tópico com esse título: Listando os arquivos em um Diretório e tem uma exemplo pronto de como fazer isso. Simples assim. Isso atenderia o que o autor do tópico precisa e vem de uma fonte, digamos, importante. E esse artigo é de maio de 2018, não de '95. Talvez entenda porque eu disse "moderna" Resumindo o que já disse lá no outro tópico: considerando que aqui é um forum para discussão de C C# e C++ e frequentado por estudantes que podem estar usando qualquer versão de compilador e não necessariamente Cygwin ou MinGW muitos usam Linux ou Mac dirent roda igualzinho nos dois ambientes E eu até postei até um código completo que automatiza a chamada de uma função para todos os arquivos comuns de uma pasta, e que rodaria apenas mudando o delimitador de / para \ em Linux. Faltaria só escrever a função que faz o trabalho que o autor do tópico precisa. Eu implementei 2 exemplos Eu acho mais simples usar essa solução. Talvez possa colaborar e acrescentar um trecho de código usando <filesystem> . A Microsoft já postou um usando os iteradores. Assim um eventual leitor do tópico poderia fazer as contas com 3 exemplos concretos. Não escrevi porque tenho pouco tempo e não me pareceu útil. Abraço
  10. Olá! Entendi. Mas seu código sequer compila ainda push() e pop() por exemplo tem um parâmetro, status, um ponteiro para int, e você nem está passando os valores. Você declarou as funções assim: void push(struct pilha**,int, int*); int pop(struct pilha **,int*); void mostra_pilha(struct pilha**); void retira_multiplos_de_3(struct pilha *p1,struct pilha **p2); o que fez você declarar p1 e p2 de modo diferente? e depois lá na rotina você usa p3 que nem está declarado... Acho que push e pop estão ok. Acho que mostra_pilha() também. Mas o programa principal podia ser mais simples. E a rotina alvo do seu programa, a que retira os itens, está muito muito confusa. Talvez você pudesse comentar melhor o seu código e alinhar melhor as coisas, para você ter mais facilidade em ir escrevendo depois. vou te mostrar um exemplo: imagine que você tenha uma rotina assim int insere_na_pilha(struct Pilha** pilha, int quantos, int inicio, int incremento) E essa rotina faz o simples: usa push() e insere quantos valores na pilha, com valores começando em inicio e incrementados por incremento Para que isso? simples: olhe essas chamadas: insere_na_pilha(&p1, 5, 1, 1); insere_na_pilha(&p1, 2, 1, 1); insere_na_pilha(&p1, 7, 3, 1); insere_na_pilha(&p1, 5, 3, 3); 5,1,1 vai gerar 1 2 3 4 5 bem besta e voce deve ter 5 4 2 1 na saida. O comum 2,1,1 vai gerar 1 2 e voce deve ter 2 1 na saída e testou para quando não tem nenhum múltiplo de 3 na lista 7,3,1 vai gerar 3 4 5 6 7 8 9, sete valores a partir de 3. Só que essa sequencia começa e termina por multiplos de 3. Muito bom para testar seu programa porque vai apagar o começo e o fim da lista ou vai dar um p#$% erro 5,3,3 vai gerar 3 6 9 12 15, 5 valores multiplos de 3 e você deve terminar com uma lista vazia, certo? Ou um erro de segmentação. Sugiro ler esse pedaço até entender: com esse trecho de código você testa as condições mais importantes da sua rotina, sem ter que ficar no terminal digitando... Só escreve isso em main() para uma pilha p1: zera_pilha(&p1); insere_na_pilha(&p1, 5,1,1); // 1 2 3 4 5 mostra_pilha(&p1); zera_pilha(&p1); insere_na_pilha(&p1, 2,1,1); // 1 2 mostra_pilha(&p1); zera_pilha(&p1); insere_na_pilha(&p1,7,3,1); // 3 4 5 6 7 8 9 mostra_pilha(&p1); zera_pilha(&p1); insere_na_pilha(&p1,5,3,3); // 3 6 9 12 15 mostra_pilha(&p1); zera_pilha(&p1); Entendeu? Essa zera_pilha() serviria apenas para liberar a memoria alocada pelas pilhas entre cada teste. Pode esquecer por enquanto. E sobre a retira_multiplos_de_3(struct pilha *p1,struct pilha **p2) ? Você deve usar struct** para endereçar as pilhas porque precisa de acesso ao conteúdo do valor apontado pelo ponteiro, então tem mais um nível e precisa do segundo * Mas não precisa de outras pilhas. A menos que seja o objetivo real de seu problema ou se precisasse preservar a pilha original. Em resumo, um valor da pilha aponta para o próximo e assim vai. Você só tem um ponteiro, que aponta para o primeiro item, ou vale null para a lista vazia. Para excluir o primeiro item: trivial: salve o endereço do segundo. exclua o primeiro e altere o ponteiro de inicio para o valor salvo. Excluir no final: quase trivial, porque a pilha é de mão única. Quando chega no fim já era. Não dá pra salvar o endereço do penúltimo, excluir o último e fazer o penúltimo apontar para NULL. Mas continue lendo Excluir no meio: mesmo problema: se voce tem lá na lista 5 6 7 por exemplo e precisa tirar o 6. O 5 vai ter que apontar para o 7 e ai você apaga o 6. Escrever assim fica fácil. Mas quando descobre que vai apagar o 6 o 5 já era... Seria como marcar algo para ontem A solução para os dois casos? A mesma. Breacrumbs.Migalhas. Deixe marcas por onde o programa passa... Percorra a lista mas salve o início da lista e o elemento anterior para não perder o rumo, e aí não terá problema, e pode usar uma única pilha. Eis um exemplo: // // a logica aqui: // - se um elemento aponta para um multiplo de tres: // - se tem um elemento anterior entao ele passa a apontar para // o seguinte, pulando esse // - se nao tem um anterior, é o primeiro e simplesmente extrai esse // int retira_multiplos_de_3(struct Pilha **pilha) { int s1; int c = 0; int v; struct Pilha* pItem = *pilha; struct Pilha* pSalvaInicio = *pilha; // salva struct Pilha* pAnterior = NULL; printf("\n***** retira_multiplos_de_3\n"); // pItem comeca no topo while (pItem != NULL) { v = pItem->dados; if (v % 3 == 0) { // esse deve ser excluido if (pAnterior != NULL) { // entao tinha um antes apontando para esse // e agora deve apontar para o que vem depois desse pAnterior->proximo = pItem->proximo; // pula esse que vai excluir pop(&pItem, &s1); // remove o item printf("\tMultiplo %4d: removido\n", v); } else { // vai remover o item inicial pSalvaInicio = pItem->proximo; pop(&pItem, &s1); // remove o item printf("\tMultiplo %4d: removido. [Item inicial]\n", v); } // end if } else { // esse vai ficar: nao multiplo de 3 pAnterior = pItem; pItem = pItem->proximo; } // end if } // end while (*pilha) = pSalvaInicio; return c; // retorna o total de itens removidos } Leia esse com atenção e veja se faz sentido para você. Esse funciona. Agora pense no programa principal: não seria bom se pudesse digitar os parâmetros direto na linha de comando, pra não perder tempo? Já que escreveu a rotina de insere os valores, podia usar na linha de comando teste 5 3 3 para testar seu programa com uma sequencia de 5 valores, começando em 3 com incremento de 3. bem melhor que ficar esperando ou alterando o código e compilando de novo. Como podia ser essa coisa? Exemplo: int argItens = 10; // padrão 10 itens int argItem1 = 1; // primeiro = 1 int argIncremento = 1; // e depois 2,3,4,5... // // os argumentos podem ser 3: // - o numero de itens a inserir no teste. padrão 10 // - o valor do primeiro item. padrão 1 // - o valor do incremento. padrão 1 // ex: x 6,3,3 vai grar 6 itens: 3,6,9,12,15 e 18 // // so para facilitar os testes da rotina que remove os multiplos de 3 // assim pode testar com multiplos no inicio, no fim ou na lista toda // so mudando a linha de comando // printf("\nIniciando %s\n", argv[0]); if (argc > 1) argItens = atoi(argv[1]); if (argc > 2) argItem1 = atoi(argv[2]); if (argc > 3) argIncremento = atoi(argv[3]); printf( "***** testando com %d itens a partir de %d com incremento %d\n", argItens, argItem1, argIncremento ); Esse tem até valores default: se digitar só teste vai rodar com a sequencia de 1 a 10. E pode digitar 1 2 ou 3 parametros. E se quiser embutir os testes mais significativos? pode escrever algo assim para um teste interessante: mostra_pilha(&p1); insere_na_pilha(&p1,argItens,argItem1,argIncremento); mostra_pilha(& p1); // agora exclui ate esvaziar, para testar do { printf("\t[-] %4d\n", pop(&p1, &ok)); } while (p1 != NULL); // outros testes simples mostra_pilha(&p1); // deve estar vazia retira_multiplos_de_3(&p1); // nao deve fazer nada ja que esta vazia E os testes de que falamos? Simples: // 2 zera_pilha(&p1); insere_na_pilha(&p1,5,1,1); // insere de novo mostra_pilha(&p1); // lista de novo. deve ter 1 2 3 4 5 retira_multiplos_de_3(&p1); // deve remover 3 mostra_pilha(&p1); // mostra o resto // 3 zera_pilha(&p1); insere_na_pilha(&p1,2,1,1); // insere de novo mostra_pilha(&p1); // lista de novo. 1 2 retira_multiplos_de_3(&p1); // nao deve remover nada mostra_pilha(&p1); // mostra o resto // 4 zera_pilha(&p1); insere_na_pilha(&p1,7,3,1); // insere de novo mostra_pilha(&p1); // lista de novo. 3 4 5 6 7 8 9 retira_multiplos_de_3(&p1); // deve remover 3 6 e 9 mostra_pilha(&p1); // mostra o resto // 5 zera_pilha(&p1); insere_na_pilha(&p1,5,3,3); // insere de novo mostra_pilha(&p1); // lista de novo. 3 6 9 12 15 retira_multiplos_de_3(&p1); // deve remover tudo mostra_pilha(&p1); // mostra o resto Pense nessas coisas. Tente corrigir seu código. Depois posto o programa inteiro, mas acho que você não vai precisar. E se eu colocar aqui o programa agora pode ficar tentado a não tentar... Boa sorte
  11. @Leonardo Naressi Vou dar uma olhada no código hoje com mais detalhe. Se sabe que está usando os parâmetros errados, o que está "trancando" você? adicionado 25 minutos depois Olá! Esta difícil de entender o que você pretende com o procedimento void retira_multiplos_de_3(struct pilha *p1,struct pilha **p2) Está certo de que postou o código direito? Qual seu ambiente de desenvolvimento --- o que usa para editar, programar e tal, como compiladores e sistema e editor? Pode comentar melhor o que quer fazer, o porque de 3 pilhas, e em especial porque p1 é pilha* e p2 é pilha** ? //Remover numeros multiplos de 3 void retira_multiplos_de_3(struct pilha *p1,struct pilha **p2) { //não estou conseguindo passar os parametros de forma correta acredito ser este o erro while(p1 != NULL) { if(p1->dados % 3 == 0) { push(p2,pop(p1));//pega o topo de pilha 1 para a pilha 2 } else { push(p3,pop(p1));//pega o topo de pilha 1 para a pilha 3 } // end if } // end while }while(p1 != NULL){ push(p1,pop(p3));//coloca de volta os numeros não mutiplos de 3 para a pilha 1 }
  12. @isrnick Só posso imaginar que não leu o que escrevi sobre isso ser uma referência histórica do porque T. Ronkko portou dirent para Windows em '98. E não leu o que escrevi sobre as razões pelas quais, a menos que você já use um desses compiladores citados, é melhor usar as soluções modernas: Ou usar <filesystem> Ou usar dirent.h como provida no github pelas razões que expliquei acima... De todo modo, o autor do tópico parece não estar se valendo dessa discussão...
  13. Olá! Veja como declarou push(): void push( struct pilha **topo, int valor, int *status) e como delcarou p2: struct pilha *p2 = NULL; e pop(): int pop(struct pilha **topo, int *status) E aí você escreve push(p2, pop(p1));//pega o topo de pilha 1 para a pilha 2 Só que p2 é um ponteiro para pilha e o primeiro argumento de push é um ponteiro para um ponteiro para pilha. Veja as declarações. E aí o compilador reclama... struct pilha **topo é diferente de struct pilha *, certo?
  14. @isrnick Não entendi o que você está tentando dizer. Isso que o autor escreveu é uma referência histórica, apenas a razão do autor ter portado a API para Windows ainda em '98. E ele acrescentou que existem hoje boas alternativas para compilar programas UNIX no windows. E citou esses compiladores. E acrescentou que ambos esses oferecem a API dirent. Só isso. Isso não muda em nada a realidade de quem quer, como o autor do tópico aqui no forum, criar uma função que envolve varrer diretórios e executar procedimentos. Não é o caso de recompilar no Windows programas do UNIX. E usar as API do Cygwin ou MinGW não faz sentido se você não usa já esses compiladores. Outro caso é precisamente o que temos aqui: se você vai postar esse código aqui, onde você não sabe que compilador o leitor vai estar usando, deve concordar que é mais seguro testar com a implementação original da dirent para Windows, ou não? E se o leitor usa Eclipse? Borland? Visual Studio? Por isso eu usei Visual Studio atualizado e testei numa máquina usando uma versão recente de Windows. Essa implementação se tornou a recomendada pela Microsoft até outro dia. Mesmo em C++. Depois passou a se recomendar a <filesystem> ainda nos tempos da biblioteca boost. E agora a recomendação é iterar usando FindFirstFile, FindNextFile e FindClose.
  15. Passei perto de ter um problema desses então . Usei SDL mas os arquivos vinham como parâmetro então não tinha razão para usar dirent. Mas acho que era SDL 2.0.9 porque é a única que vejo nos backups. SDL 1.2 parou em 2012 acho. E foi bem depois que eu usei. Obrigado por mostrar ao menos duas. Faltou um diff Saudações!
  16. Olá. Vou dar uma olhada! Palpite: não crie um procedimento para" retirar os múltiplos de 3". Crie um procedimento para colocar na pilha, push() é o nome clássico. Crie um procedimento para tirar da pilha, pop() é o nome clássico, Teste os caras, empilhe umas coisas e retire até ficar vazia... Aí você cria uma função que extrai os que são múltiplos de 3... Assim não mistura os testes
  17. Conflitos não vão se espalhando como um vírus. Se você tem um único serviço de DNS rodando a partir de seu único gateway. Se você desativou DHCP no roteador secundário. Se você ligou o roteador secundário via porta LAN. Então os endereços de servidores DNS virão junto com o endereço IP, a máscara e o endereço de gateway, tudo cortesia de seu próprio servidor DHCP. Essa é a vantagem de ter tudo concentrado e automático. Pois é: ao colocar tudo estático grande chance de você criar mais problemas ao invés de resolver algum. Isso que escreveu sobre os dispositivos wifi não faz sentido: o que seria "um tipo de firewall"? Firewall não serve como gateway, só fica no caminho do tráfego de dados. Firewall não fornece IP muito menos sequência de IP. Verifique se de fato desativou o serviço DHCP no roteador secundário. Na prática os únicos dispositivos que devem ter endereço fixo na sua rede são os dois roteadores. Se a rede servida pelo DHCP é 192.168.1.0 como sugeriu, pegue um endereço fora da faixa de endereços em uso pelo DHCP no modem e fixe para o roteador secundário, assim ele estará na rede e você poderá sempre acessá-lo sem ter que mexer em nada. É comum usar os endereços fixos em sequência, por exemplo use 192.168.1.2 para o roteador secundário, 192.168.1.1 para o modem roteador, e a faixa de DHCP a partir de 10 ou 20 e assim você sabe que pode usar os endereços até 10 ou 20 para fixar em algum dispositivo para teste, por exemplo... Teste e continue escrevendo
  18. Não tenho tanto tempo e nem tanto interesse para comparar essas hipotéticas "duas versões"... Mas eventualmente vou fazer isso porque sou curioso O próprio autor, T. Ronkko diz na página de download que Mingw e Cygwin disponibilizam a API dirent completa. Mas nada diz sobre uma possível diferença. Mas não faz sentido ter duas versões de uma biblioteca tão simples e estabelecida, e o autor afinal é o próprio T. Ronkko. Um eventual conflito com sockets.h parece um pouco distante do nível de acesso de dirent. Usar uma dessas opções incluída no compilador economizaria um download mas não tenho acesso fácil a esses compiladores. Por outro lado, alguém podem se sentir inseguro ao usar uma biblioteca de mesmo nome que não é, digamos, a original. Ainda mais sabendo que o autor continua atualizando a API na página no github ainda hoje. A última atualização foi há 3 meses. Para uma API de 27 anos... O raciocínio é simples: seja qual for o seu ambiente, se todos usarem a mesma API --- de 23k --- não tem como dar errado a menos que tenha um erro na API, certo? E ela vem sendo mantida regularmente. Agora se eu usar a de um compilador e tiver algo lá diferente, que eu não sei o que é... Posso dizer apenas do ambiente com Visual Studio 15.9.12 e sob Windows 10. Que usei para testar o programa que postei. E funciona sem problemas. Nem sei quais versões de sistema usei no passado, mas nunca me ocorreu usar uma API que não a do autor, porque aí eu teria que me preocupar com o que aconteceria se eu passasse a usar um outro ambiente de desenvolvimento que usasse outra "versão". E sempre funcionou...
  19. Nem perto disso. O fato de você pode em geral portar código C para C++ em mutos casos com facilidade termina aí. C++ é uma linguagem "enorme" com um mundo de construções sem paralelo em C. A bem da verdade você pode olhar trechos de programa em java ou até javascript e achar que é C++ também, ou C#, mas dura alguns minutos só Essa é uma coisa que você vai ler ainda em muitos lugares, como eu vou, mas não é verdade. De volta ao tópico, seu programa roda em C exceto pelas funções de biblioteca como cin e cout que na verdade não são assim parte da linguagem, seja C ou C++. Por exemplo, cin e cout estão na biblioteca iostream do C++ por exemplo, e scanf na biblioteca stdio.h do C. sqrt() está em math.h nos dois casos
  20. Olá! Está apenas compartilhando o código ou tem alguma pergunta?
  21. Olá! Acho que as pessoas que acompanham esse forum vão acabar vendo as mesmas questões, então talvez abrir um novo tópico com o mesmo problema pode não ser assim efetivo... Como te disse antes, talvez ajudasse você explicar qual seu ambiente de desenvolvimento... O código que postei funciona perfeitamente, bastaria criar uma nova rotina e passar o nome dela pra a função executa_na_pasta() long executa_na_pasta(const char * pasta, long(*a_funcao)(const char *)) { // roda a funcao a_funcao() para todos os arquivos na // pasta 'pasta' e retorna o total em bytes da soma do // tamanho dos arquivos struct dirent *diretorio; // descreve o diretorio DIR *pDir = opendir(pasta); // o ponteiro para o diretorio char * nome_completo; // nome do arquivo na pasta long total = 0; // para somar os tamanhos printf("\n[%s]\n\n", pasta); if (pDir == NULL) { printf("Erro ao abrir %s\n", pasta); return(-1); } // end if while ((diretorio = readdir(pDir)) != NULL) { // em d->name esta o nome do arquivo // entao precisamos da string 'pasta\nome' // para ver se e um arquivo comum e listar afinal int n = 2 + strlen(pasta) + strlen(diretorio->d_name); nome_completo = (char *)malloc((size_t)n); // monta o nome do arquivo: pasta \ nome no windows sprintf_s(nome_completo, n, "%s\\%s", pasta, diretorio->d_name); // se for um arquivo comum, chama a funcao // faz o servico para cada arquivo na pasta *********************** if (eh_um_arquivo(nome_completo)) total = total + a_funcao(nome_completo); // *********************** free(nome_completo); // libera o nome } // end while printf("\nTotal de %d bytes nos arquivos da pasta\n", total); closedir(pDir); // ao sair fecha a pasta return(0); } // end executa_na_pasta() se a sua função for teste() bastaria chamar com executa_na_pasta("nome da pasta", teste) Acho que tem algo errado na configuração de seu ambiente. Não é pra ter diferença a versão de mingw e o código original. Não faria sentido, porque iria contra a própria razão de sucesso dessa biblioteca, que tem mais de vinte anos e roda até no videogame. De qualquer forma, a versão de Toni Ronkko vem sendo mantida há mais de vinte anos e é, claro, definitiva. Foi essa que usei para testar a rotina acima, essa long executa_na_pasta(const char * pasta, long(*a_funcao)(const char *)) apenas escrevi duas rotinas de teste. Postei até a saída da execução em e compila sem problemas em Windows 10 e Visual Studio 2017. Seu problema não é este.
  22. Olá! Nesses casos não é uma sub-rede, mas uma rede distinta. Mas como a rede do modem é a rede seguinte do roteador wifi você continua tendo acesso a ela pelos endereços IP, a partir do roteador wifi. Já postei aqui uns exemplos com algumas telas de como isso funciona, telas do Windows 10 apenas, mas funciona em outras versões e sistemas, mas não sei o tópico. TCP/IP só tem um afinal. Assim, dispositivos conectados ao seu roteador wifi tem acesso normal aos dispositivos conectados às outras portas do modem O inverso é mais complicado porque o roteador wifi faz NAT na porta WAN e isso pode exigir encaminhar as portas de compartilhamento de arquivos para o endereço IP da impressora wifi. E o acesso a eventuais micros ligados por esse roteador wifi a partir de micros na rede do modem ficaria prejudicado. Se for só a impressora iria funcionar. O caso da impressora ligada direto ao roteador vai depender de como for o software fornecido para o roteador, porque normalmente você instala uma espécie de driver nas estações para que elas acessem a impressora conectada ao roteador via USB. E esse software supõe a impressora na mesma rede em que está o roteador. Nesse caso, talvez seja possível compartilhar novamente a impressora a partir de um micro na rede do roteador. E assim poderia usa-la através dessa máquina na rede do modem a partir de máquinas ligadas no roteador "secundário". Outra possibilidade é configurar o acesso às impressoras via IPP --- internet printing protocol --- que roda na porta 9100 por padrão e criar os encaminhamentos correspondentes. Se usar alguma máquina para "compartilhar de novo" uma impressora claro que esse compartilhamento implica na máquina estar ligada...
  23. Olá! Isso parece ser um programa de trabalho de faculdade, então é bom lembrar que: Em C++ não existe o tipo string. string é uma classe, baseada no mesmo exato tipo char do C Poder usar == para comparar strings em C++ não é assim de verdade. Essa é apenas uma cortesia da implementação da classe string, que redefine o operador == para na verdade usar string::compare(), não muito diferente do strcmp() do C. Na verdade todos os operadores são redefinidos, como > e <. Veja mais direto no manual em http://www.cplusplus.com/reference/string/string/operators/ Poder usar = em C++ para copiar string também não é assim uma atribuição simplesmente: uso provoca a execução do construtor de cópia da classe string Essas são situações para mostrar as diferenças entre essas linguagens, já que algumas coisas ficam meio escondidas... Acertou o programa afinal? ah, o link para a bíblia da classe string
  24. Olá. Acabei de escrever algo sobre esse lance de portas em um outro tópico aqui, neste artigo. De uma olhada se tiver tempo. Talvez ajude O que você descreve está na contramão: se o backdoor está no computador dele você tem que registrar o endereço público do roteador dele no no-ip. e encaminhar no roteador dele o tráfego da porta 4444 para o endereço ip do micro em que instalou a backdoor. E eventualmente fixar o enderço IP local do micro dele no DHCP para ter certeza de que o tráfego vai ser transferido para o micro certo todo dia, porque o D de DHCP é de ... dinâmico. Você não vai "abrir portas". Muito menos pelo DNS, que é só um sistema gigante de registro de IP pelo nome. Você "abre" a porta 4444 no momento em que ativa a backdoor no micro. Mas precisa de uma maneira de bater na porta certa, e isso envolve o registro do endereço público por nome em algum servidor DNS e se o micro está atrás de um ou mais roteadores você tem que encaminhar o tráfego até ele. Isso pode implicar também em reservar um endereço fixo no DHCP no roteador ou usar um endereço fixo no micro. Se acaso não fez isso ainda e se pode fazer, teste isso primeiro no próprio micro em que instalou isso, usando localhost:4444. Quando funcionar, teste a partir de outro micro na rede local. Quando funcionar, aí sim teste via internet. Isso depois de testar o registro dinâmico, certo?
  25. Olá! Portas não ficam em redes ou envolvem redes por definição. Uma rede TCP/IP tem um endereço, uma máscara, um endereço de ao menos um gateway e uma lista de ao menos um servidor DNS. E em geral tem ao menos um servidor DHCP. Tudo isso envolve endereços IP como o clássico 192.168.0.1. Não portas diretamente. Mas o tráfego via TCP/IP é feito via uma abstração chamada socket, que é um conjunto formado por um endereço IP e uma porta, que é um número entre 1 e 65536. e nesse socket ocorre um tráfego através de um protocolo. Isso não envolve a internet ou sequer a rede local. Envolve dois programas: um que está aceitando conexões em um socket e outro que tenta se conectar a este socket. Quando um programa está aceitando conexões em um socket isso implica em ter uma porta aberta no endereço IP da máquina que roda o programa e na porta em que o programa está aguardando conexão. Talvez daí venha a noção de "abrir portas" que se lê tanto aqui no forum por exemplo, mas que não existe na verdade. Mas um programa pode se conectar a outro na mesma máquina, por exemplo. Para a conexão não existe essa noção de local ou remoto. Todo micro tem por exemplo o endereço 127.0.0.1 para uso, conhecido não por acaso como localhost. Exemplo: você tem um servidor FTP rodando na porta 21 na sua máquina. Na sua máquina você abre um cliente FTP e tenta se conectar ao socket 127.0.0.1:21 e vai receber o prompt do servidor FTP imediatamente. Funciona assim. Agora se você vai acessar isso pela internet e seu micro está atrás de um roteador, que está ligado a internet através de um provedor e tem um endereço IP público qualquer, e que pode mudar a qualquer momento, eis a mecânica do outro lado: Você usa um serviço de registro dinâmico de IP como o no-ip e sempre que seu roteador se conecta a internet seu roteador vai ao site do no-ip e, usando seu código de usuário e senha, atualiza lá o seu endereço IP atual para o nome que você contratou lá, tipo ddm-ftp.ddns.net. Essa é a primeira parte. Assim qualquer computador conectado a internet pode se conectar com seu roteador, em ddm-ftp.ddns.net. Em qualquer porta. Só que seu roteador não tem nenhum serviço rodando, então essas conexões não vão dar em nada e dizem que a porta está fechada, mas não é o caso. Apenas não tem um programa rodando para aceitar conexões. A bem da verdade seu roteador tem algum serviço rodando. Muitos tem um servidor web rodando na porta correspondente, 80 e se você acessa isso vem... a tela de configuração do roteador. E muitos roteadores podem ser configurados para habilitar "administração remota" e isso significa apenas que se alguém a partir de algum lugar da internet tentar se conectar a http://ddm-ftp.dns.net vai receber a tela de login do seu roteador, se ele estiver assim configurado. Seu roteador também tem um servidor DHCP rodando, mas ele não aceita conexões pela porta WAN, de entrada, mas apenas pelas portas LAN. Isso quer dizer que se você escrever um programa na sua rede local que cria um socket e tenta se conectar ao seu roteador, por exemplo em 192.168.0.1, na porta 67 que é a porta do DHCP, vai conseguir algo. Se seguir todo o protocolo pode até receber um endereço de rede e criar uma grande confusão. Mas ao ligar seu micro sua placa de rede faz exatamente isso. Estou escrevendo isso tudo porque nunca vejo essa mecânica descrita em lugar nenhum e pode ser interessante para quem ler isso. Claro, não está exatamente em resposta à sua dúvida e talvez tenha já parado de ler lá em cima mesmo. Continuando: seu roteador tem um nome registrado em no-ip para o endereço público dele e está acessível a partir da internet pela porta WAN sob tal nome. E o servidor DHCP dele deu um endereço IP ao seu micro que tem o servidor FTP rodando. No entanto o D de DHCP quer dizer dinâmico, e isso quer dizer que ele pode mudar, exatamente como o endereço público de seu roteador na internet. Então você precisa de um equivalente ao no-ip na rede local, e isso em geral se faz usando uma tabela que tem no roteador que reserva endereços para os micros na rede local. Fica nas opções de DHCP, claro, e pode ter vários nomes, como "client address reservation". É bem simples: cada dispositivo de rede tem uma espécie de número de série chamado MAC --- media access control --- e nessa tabela você marca lá o endereço MAC do servidor FTP e fixa um endereço para ele, tipo 192.168.0.10. Segunda parte: agora seu micro na rede vai estar sempre em 192.168.0.10. E os micros na rede local podem acessar o servidor ftp sempre em 192.168.0.10:21. Mas e pela internet? Terceira parte: você precisa ir ao roteador e configurar algo para que ele transfira todo o tráfego que entra direcionado a porta 21 para o micro que está em 192.168.0.10 rodando o servidor FTP. Isso é feito numa tabela, de encaminhamento de portas ou port forwarding ou algum nome similar. Isso fecha o círculo e a coisa anda. Pode ficar mais complicado se você tiver por exemplo vários servidores FTP na rede e quiser acessar de fora, ou se você tiver mais de um servidor DHCP na rede, ou muitos outros casos, mas o geral é isso que descrevi. E como saber as portas? Em geral toda implementação de TCP/IP deve ter um conjunto de arquivos que lista isso. No Windows por exemplo você pode ver esses arquvos na pasta C:\Windows\System32\drivers\etc Eis as primeiras linhas do arquivo services, que lista as portas comuns: # # Format: # # <service name> <port number>/<protocol> [aliases...] [#<comment>] # echo 7/tcp echo 7/udp discard 9/tcp sink null discard 9/udp sink null systat 11/tcp users #Active users systat 11/udp users #Active users daytime 13/tcp daytime 13/udp qotd 17/tcp quote #Quote of the day qotd 17/udp quote #Quote of the day chargen 19/tcp ttytst source #Character generator chargen 19/udp ttytst source #Character generator ftp-data 20/tcp #FTP, data ftp 21/tcp #FTP. control ssh 22/tcp #SSH Remote Login Protocol telnet 23/tcp smtp 25/tcp mail #Simple Mail Transfer Protocol time 37/tcp timserver time 37/udp timserver rlp 39/udp resource #Resource Location Protocol nameserver 42/tcp name #Host Name Server nameserver 42/udp name #Host Name Server OK OK Parei. Boa sorte Espero que ajude alguém, ou você ao menos. Escreva com mais detalhes de seu problema

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!