Ir ao conteúdo

arfneto

Membro Pleno
  • Posts

    6.517
  • Cadastrado em

  • Última visita

Tópicos solucionados

  1. O post de arfneto em Acessar uma rede através de outra! foi marcado como solução   
    Endereços de rede terminam em 0. Esse é um host, talvez o gateway da rede certo? DHCP não faz pare disso. A rede é 192.168.3.0
     
    Esse é outro host. A rede é 192.168.0.0/24
     
     
    Da rede 2 pode acessar a rede 1, é a rede acima dela. Pode precisar de rotas. O contrário não, ou ao menos não de um modo produtivo.
     
    Não deve ligar redes internas via WAN. Esse é seu problema,
  2. O post de arfneto em Adpatador Wireless USB ou Placa PCI Wireless foi marcado como solução   
    Compre algo com wifi6 ou wifi6E, AX não AC. 
     
    Dependendo do barramento USB em sua máquina pode não fazer diferença. Mas os limites de banda de PCIx ou USB3X são muito mais altos que o necessário para o potencial dessas placas de todo modo.
     
    USB tem o lance de ser portável para outras máquinas e pode ser um argumento.
  3. O post de arfneto em Qual é o melhor Cabo Cat para internet 600Mb foi marcado como solução   
    Não deve fazer a menor diferença. Mas se for mudar enenda que esses cabos são mais duros e mais grossos e como parte do padrão 6 tem uma canaleta plástica dura dentro. Se vai passar por um duto considere que pode dar mais trabaalho, e caber menos cabos. Noe que deve usar conectres CAT6 também ou não faria muito sentido. De todo modo não precisa disso, porque cabos Cat5E são garantidos para até 1000mbps, bem mais que 600, e provavelmente seus equipamentos não funcionam a mais de 1000 também. Isso para situações de não ter muita interferência e até 95+5 metros de cabo.
     
     
    Antes de gastar temp e dinheiro verifique o que o sistema reporta para essa conexão entre o roteador e o pc. E se puder TESTE com algum outro dispositivo na rede. Antes de se preocupar com a internet deve estar absolutamente certo de que a rede local está ok. Você pode precisar e ter uma ree local a 10.000mbps e estar ok com um link de de 200 mbps para a internet. Nada tem a ver uma coisa com a outra.
     
  4. O post de arfneto em Não sei que roteador devo comprar para conseguir usar 800+ mbps no meu pc. foi marcado como solução   
    800mbps é bem menos que 1000 mbps então qualquer roteador que tenha portas gigabit serve. Se vai usar wifi use qualquer um que tenha wifi6 ao menos. Nos últimos tempos comprei vários da marca tp-link modelo AX12, 1500 mbps em wifi e AX53, 3000 mbps em wifi, e nenhum deu qualquer tipo de problema até agora.
  5. O post de arfneto em Troca do modem CLARO foi marcado como solução   
    Em que cidade está isso? Parece tão estranho. Explico: tenho 3 contas na CLARO em cidades diferentes. Nessas quando há troca de firmware ou por alguma razão precisa trocar o modem, já no primeiro acesso vem uma tela dizendo que é preciso colocar uma nova senha e não consigo passar adiante sem isso. E o usuario original é CLARO_XXXXXX onde esse XXXXXX vem dos últimos 6 dígitos do endereço MAC do modem.
     
     
    Se colocar em modo bridge --- ponte --- o modem vira isso, uma ponte, apenas um conversor de mídia. E não consegue acessar nada porque ele não faz mais parte da rede.
     
     
  6. O post de arfneto em Modem Claro e roteador tplink com redes diferentes e funcionando como servidor d foi marcado como solução   
    Não há nada de especial nesse caso, mas é curioso no mínimo:
    qual a razão de usar tal máscara /27? .224 limita a rede a 32 endereços. são redes distintas para sala e quartos. Isso quer dizer que coisas simples como transferir mídia --- como um filme --- de um celular ligado no wifi numa rede para a outra pode ser complicado ou impossível vai ter uma perda grande de banda na segund rede por causa do múltiplo NAT. Pode chegar a uns 40% claro que vai precisar de DHCP na segunda rede. comparilhamento de impressoras ou arquivos é um inferno automação outro pesadelo  
    com as limitações de que falei, mas funciona.
     
     
    bridge é isso: ponte. Só vai perder. Perder portas ethernet, antenas, cobertura wifi, banda wifi.
     
     
    Rede IP é uma coisa, rede ethernet é outra. Wifi é outra. wifi também é ethernet mas é um subconjunto da rede ethernet
     
    No geral você quer uma única rede IP, com um único gateway padrão, o modem da operadora. E pode ter tantas redes wifi quanto precise.
     
     
    Isso não mexe no wifi da claro de modo algum.  
     
    Não deve usar roteadores ligados via WAN no roteador principal. Algumas das razões eu já expliquei acima. É comum fazer isso, a ponto de ser visto como normal, mas não é adequado.
     
     
     
    Não precisa desligar DHCP no segundo e é melhor mesmo não fazer isso, no mínimo por redundância e menor latência no DHCP. Deve excluir esse endereço .2 da faixa de DHCP de todo modo. 
     
    Não é preciso configurar como AP. E dependendo do roteador em uso não deve mesmo, porque alguns desabilitam as portas ethernet quando assim configurados, e esperam uma simples conexão pela WAN com o sinal para o wifi.
     
     
  7. O post de arfneto em Preciso fazer um download automático de uma tabela excel a cada hora foi marcado como solução   
    @Nosila19 Sim. pode usar automação e escrever um script para fazer isso. Então coloca na agenda do sistema para rodar nos horários determinados e pronto.
     
    Pode tentar AutoIt ou um script em Python usando pyautogui. Uso algo assim para reprogramar e reiniciar roteadores.
  8. O post de arfneto em Placa de rede internet 10 ou 100 mb/s foi marcado como solução   
    Não entendi. Esse cabo da foto é o que comprou?
     
     
    Não existe placa de rede internet. Só placa de rede. Não precisa de inerne para ter rede. Mas precisa de rede para ter internet. Mesmo que sejam 2 pontos só.
     
     
    Isso quer dizer que já fez o simples e testou o mesmo computador com os outros dois cabos e os outros dois computadores com esse cabo certo? E qual foi o resultado?
     
     
    Um cabo CAT6 não vai fazer a menor diferença. Só gastou dinheiro. Sua placa de rede vai até 1Gigabit, o padrão de 1999. E para esse padrão a categoria 5 foi revista e desde enão tem o cbos Cat5E, que são perfeitamente adequados para essa velociade, em 95+5 metros. Ou uma velocidade até bem maior se forem cabos curtos e não estiver em um ambiente de muita interefrência.
     
    O cabo da foto parece folgado e está claramene fora do padrão, E dá pra imaginar que os cabos tem duas pontas e mostrar uma só de nada adianta. Que pino está ligado em que pino seria a pergunta normal a fazer. A primeira, E os testes de que falei. 
     
    Esses são os padrões. 
     
    Para curtas distâncias qualquer um deve servir, mas não é esperto divergir desses dois esquemas.
  9. O post de arfneto em Velocidade de conexão menor do que o plano oferece foi marcado como solução   
    não é bem assim.
     
    Placas não "suportam internet". Sua placa nem deve estar conectada a internet mas sim a um roteador. Se desligar o roteador da internet a placa e a rede continuam funcionando.
     
    A velocidade da placa é dada pelo chipset instalado, nada tem a ver com internet ou plano de dados.
     
    Sua placa tem um chipset de rede embutido, e esse suporta conexões gigabit. ou FE a 100 mbps, ou mesmo a 10 mbps. 
     
    Mas nada tem a ver com o que sua placa suporta. Essa placa tem 2 slots x1 e um slot x16. Isso quer dizer que pode instalar placas de rede nos 3. Pelo formato pode instalar 2 placas 2500G nos slots x1 e uma placa 10.000G no X16. Nada tem a ver com internet.
     
    Essas propriedades são um limite e não uma definição. Você usa isso para LIMITAR uma conexão abaixo da velocidade que seria normal.
     
    E precisa ver o que tem do outro lado do cabo, os cabos, os conectores e tal.
  10. O post de arfneto em Ler um texto e transformá-lo em um Array Bidimencional foi marcado como solução   
    F7: bidimensional é a grafia correta, como em dimensão.
     
    Seu programa lê lexto e mostra texto, então mostre texto aqui e não essas imagens gigantes copiadas de sua tela. Ajude outros a ajudarem você: poste um mínimo arquivo de teste que mostra o que quer fazer, e um exemplo do seu problema acontencendo, em texto.
     
    Isso seria algo melhor que as duas telas gigantes:
     
    entrada.txt
     
    Pokemon Megaman Megamente Kyrbi Kaku
    Porque assim alguém pode copiar isso e colar em um arquivo e tentar reproduzir seu problema em minutos.
     
    E poste a saída do seu programa. Mas nem posso postar aqui a saída do programa que mostrou, porque ele sequer compila direito ainda.
     
    Sobre o programa:
     
    Quase todo o código está comentado. Qual o propósito?
     
    Esse comando, por exemplo:
     
                strncpy(                 &Text_Read[i][p],                 (char*)fgets(                     ((char*)getchar()), 1 * sizeof(char),                     ((FILE*)printf("%c", *(&One_Letra2)))),                 1 * sizeof(char));
    é algo que deve muito evitar, em especial se está começando a programar nessa linguagem. No caso de seu programa está errado mesmo, mas é algo que deve evitar mesmo que saiba o quie está fazendo.
     
    São muitas coisas que podem dar errado, isso se a ideia em si estiver certa.    
     
    `fgets` pode dar errado. Não está sequer testando e já passa o valor como argumento para `strncpy`. Não é boa ideia. leia o manual: `printf` retorna um `int`. Qual seria o sentido de converter para `FILE~`, algo que nem é suposto para ser tratado pelo programador? o operador `sizeof` retorna 1 para `char`. Então tudo isso seria para de algum modo copiar uma letrinha e um `NULL`?  pra que `strncpy`? Isso é algo que poderia ter comentado... Não seria melhor ver agora o tamanho da string e alocar do tamanho certo e copiar usando simplesmente strcpy? Está certo de entende o que é `FILE*`? Tem um livro? Mais sobre o código
     
      Seu programa tem muitos dos erros comuns que vemos aqui, e então vou copiar de uma lista que tenho e listar umas coisas que provavelmente deve evitar
     
    Não use acentos em nomes de variáveis ou comentários. Evite mesmo em strings  a menos que o enunciado exija. Não vai aprender nada e só vai ter problemas. Mais ainda evite usar Unicode e coisas como emojis. Nada acrescenta ao código e não sair em muitas telas, ou vai sair outra coisa. E se imprimir o programa pode não sair nada ou algum lixo. Evite comentários como "main é a função principal" ou "declaração de variáveis" ou coisas óbvias desse tipo. Comente o porque está fazendo algo, escreva para você mesmo no futuro, tipo daqui a 2 dias quando pode não lembrar para que era aquele ponteiro, por exemplo. evite retornar void de funções: em geral é um desperdício. E muitas vezes um erro. Use argumentos nas funções, e retorne algo delas. É mais esperto e expressivo. Use alguma ordem em suas funções, como a ordem alfabética por exemplo. Vai gostar disso quando seu programa tiver 50 funções ao invés de umas poucas. Muitos IDE mostram uma lista das funções, em geral na ordem em que foram declaradas, de modo que você pode clicar no nome e o editor vai direto para o código, mas se estiverem em ordem é claro que você só ganha. Nunca use variáveis globais. Isso é um pesadelo e sempre vai cair na sua cabeça. Em geral é proibido em empresas e escolas. Não declare NADA que use memória  fora de main(). Não declare mais que uma variável por linha. Não acrescenta nada e só dificulta a leitura. Inicialize todas as variáveis. Nunca leia valores do teclado para alimentar seu programa antes dele estar rodando. Só vai te atrasar e não acrescenta absolutamente nada. Use constantes, use funções que retornam a estrutura preenchida. Leia de arquivos: é trivial em C. Ao terminar os  testes aí sim incorpore a leitura. Um programa interativo é chato para testar. Durante o desenvolvimento ninguém quer interagir com o programa. Nunca escreva um programa interativo, mesmo que seja o objetivo final. Alinhe seu código com algum critério. Evite longas linhas com mais de 60 colunas. Use nomes significativos para as variáveis e fuja de coisas como aux, aux1 e aux2. E não use nomes de variáveis enormes porque em uma expressão fica muito difícil de ler. não use fflush(): isso só está definido para fluxos de saída. Em alguns compiladores pode até funcionar, mas é um sinal de fez algo errado e não sabe como consumir os dados. não use setbuf a menos que saiba a razão de fazer isso. streams usam buffers porque é esperto e não o contrário. Não existe "lixo de teclado": necessidades como de flush() na entrada indicam apenas que não entendeu bem o que está lendo e o que é a entrada via teclado, free form: o usuário pode digitar qualquer coisa e é o seu programa que tem que se virar O teclado tem ao menos 105 teclas de liberdade e o usuário pode digitar qualquer coisa em qualquer ordem. evite ler do teclado a menos que seja o objetivo do problema. Ler de arquivos é muito mais simples, seguro e fácil de reproduzir. Não há razão para ficar parado em frente a tela minutos inventando nomes de campos e coisas assim: o efeito é que vai acabar não testando direito porque é difícil controlar e repetir testes. Não misture entrada de dados ou formatação com a apresentação dos dados ou a lógica do programa, Isso é um desastre para manutenção e desenvolvimento. Um printf() de 6 linhas é **muito**, mas muito melhor que 6 printf() de 1 linha. E se só vai mostrar o texto puts() é ainda melhor e dezenas de vezes mais rápido que uma série de printf(). Escreva seu programa em torno dos dados.
     
    O que quer criar é o que todo programa `C` recebe: uma lista de strings. Esse é o protótipo normal de `main`:
     
            int main( int argc, char** argv);  
    E são os argumentos que seu programa --- e todo programa `C` recebe: uma lista de strings com o que o usuário digitou na linha de comando. O primeiro argumento é sempre o nome do programa. Isso deveria ser ensinado no PRIMEIRO programa do aluno, aquele tal `Hello World`. Mas não sou eu quem ensina ou decide isso 😄  
     
    Os dados:
     
    o que o programa recebe? O que o programa cria?
     
    O programa recebe o nome de um arquivo e cria uma lista de strings. Igualzinho ao que o sistema faz para todo programa `C`, como eu disse.
     
    Então faça igual, já que dá certo para todo programa vai dar certo para o seu:
     
        char nome_arquivo[250];     const char[] arquivo_padrao = "entrada.txt";     typedef struct     {         unsigned n_linhas; // quantas linhas no arquivo?         char**   L; // o vetor de linhas     } Array;
     
    Já seria um bom começo:
     
    tem onde ler o nome do arquivo. tem um nome padrão para o caso do cara não digitar nada. E assim para testar não tem que ficar digitando nomes de arquivo duzentas vezes. E pode ter arquivos de teste já separados. na saída vai ter o tal `Array` onde diz que o texto carregado tem n_linhas e as linhas vão estar todas arrumamindas no vetor L.    Parece simples assim.

      E 
     
      #include <stdio.h> typedef struct {     size_t N;  // quantas linhas no arquivo?     char**   L;  // o vetor de linhas } Array; int main(int argc, char** argv) {     char nome_arquivo[250];     const char arquivo_padrao[] = "entrada.txt";     return 0; }
     
    já compila e roda. Claro, só para apoio moral porque não faz nada.
     
     
     
    São mesmo duas dimensões. De todo modo entenda que C sequer tem arrays multidimensionais, como FORTRAN. Só existe array. Mas tem array de array, array de array de array e assim por diante...
     
    Então se declarar o simples
     
    char** Linha;  
    e gravar seu arquivo lá, vai ter a linha 0 em Linha[0], a linha 3 em Linha[3] e tal.
     
    Linha[0] é o que? char*, assim foi declarado. Então
    Linha é char** *Linha é char*, Linha[0] é char* **Linha é uma letrinha, char, assim foi declarado. assim sendo, Linha[12][0] é a primeira letra da linha 13 a ultima letra da terceira linha seria o que?   
    Seguindo com o exemplo que mostrei:
     
    #include <stdio.h> #include <stdlib.h> typedef struct { size_t N; // quantas linhas no arquivo? char** L; // o vetor de linhas } Array; int main(int argc, char** argv) { char nome_arquivo[250]; const char arquivo_padrao[] = "entrada.txt"; char* uma = "uma linha"; char* outra = "outra linha"; Array exemplo = {.L = NULL, .N = 0}; printf("exemplo tem %llu linhas\n", exemplo.N); exemplo.L = (char**)malloc(2 * sizeof(char*)); exemplo.L[1] = uma; exemplo.L[0] = outra; exemplo.N = 2; printf("exemplo tem %llu linhas\n", exemplo.N); return 0; }  
    Isso mostra
     
    exemplo tem 0 linhas exemplo tem 2 linhas  
    Mas é claro que vai querer mostrar o que tem dentro do vetor, as linhas, então uma função assim
     
    int ch_mostra(Array*,const char*); // mostra as linhas na tela  
    Seria a popular "mão na roda" e ainda aceita um título pra você não ter que ficar colocando os ultra chatos printf aqui e ali... Seria difícil escrever?
     
    int ch_mostra(Array* arr,const char* msg) { if (arr == NULL) return - 1; // sem linhas if (msg != NULL) printf("%s", msg); printf(" Vetor tem %llu linhas\n", arr->N); for (size_t i = 0; i < arr->N; i += 1) printf("#%llu\t\"%s\"\n", i, arr->L[i]); printf("\n******\n\n"); return 0; }  
    10 linhas está ok. 
     
    E mudando o programa aí de cima
     
    #include <stdio.h> #include <stdlib.h> typedef struct { size_t N; // quantas linhas no arquivo? char** L; // o vetor de linhas } Array; int ch_mostra(Array*,const char*); // mostra as linhas na tela int main(int argc, char** argv) { char nome_arquivo[250]; const char arquivo_padrao[] = "entrada.txt"; char* uma = "uma linha"; char* outra = "outra linha"; Array exemplo = {.L = NULL, .N = 0}; ch_mostra(&exemplo, "[array vazio]\n\n"); exemplo.L = (char**)malloc(2 * sizeof(char*)); exemplo.L[1] = uma; exemplo.L[0] = outra; exemplo.N = 2; ch_mostra(&exemplo, "[array deve ter duas linhas]\n\n"); return 0; } int ch_mostra(Array* arr,const char* msg) { if (arr == NULL) return - 1; // sem linhas if (msg != NULL) printf("%s", msg); printf(" Vetor tem %llu linhas\n", arr->N); for (size_t i = 0; i < arr->N; i += 1) printf("#%llu\t\"%s\"\n", i, arr->L[i]); printf("\n******\n\n"); return 0; }  
    E na tela mostra
     
    [array vazio] Vetor tem 0 linhas ****** [array deve ter duas linhas] Vetor tem 2 linhas #0 "outra linha" #1 "uma linha" ******  
    É melhor escrever em torno dos dados e começar assim.
     
    E sobre a última letra da última linha?
     
    // 'len' = tamanho da ultima linha size_t len = strlen(exemplo.L[exemplo.N - 1]); char ultima = exemplo.L[exemplo.N - 1][len - 1]; printf( "\n\n\tUltima letra da ultima linha: '%c'\n", ultima);  
    E colocando isso no programa
     
    #include <stdio.h> #include <stdlib.h> typedef struct { size_t N; // quantas linhas no arquivo? char** L; // o vetor de linhas } Array; int ch_mostra( Array*, const char*); // mostra as linhas na tela int main(int argc, char** argv) { char nome_arquivo[250]; const char arquivo_padrao[] = "entrada.txt"; char* uma = "uma linha"; char* outra = "outra linha"; Array exemplo = {.L = NULL, .N = 0}; ch_mostra(&exemplo, "[array vazio]\n\n"); exemplo.L = (char**)malloc(2 * sizeof(char*)); exemplo.L[1] = uma; exemplo.L[0] = outra; exemplo.N = 2; ch_mostra(&exemplo, "[array deve ter duas linhas]\n\n"); // 'len' = tamanho da ultima linha size_t len = strlen(exemplo.L[exemplo.N - 1]); char ultima = exemplo.L[exemplo.N - 1][len - 1]; printf( "\n\n\tUltima letra da ultima linha: '%c'\n", ultima); free(exemplo.L); return 0; } int ch_mostra(Array* arr, const char* msg) { if (arr == NULL) return -1; // sem linhas if (msg != NULL) printf("%s", msg); printf(" Vetor tem %llu linhas\n", arr->N); for (size_t i = 0; i < arr->N; i += 1) printf("#%llu\t\"%s\"\n", i, arr->L[i]); printf("\n******\n\n"); return 0; }  
    Que mostra
     
    [array vazio] Vetor tem 0 linhas ****** [array deve ter duas linhas] Vetor tem 2 linhas #0 "outra linha" #1 "uma linha" ****** Ultima letra da ultima linha: 'a'  
    Para que isso? 
     
    Só para mostrar como acessar as letras dentro da estrutura.
  11. O post de arfneto em Acess point intelbras oscilando foi marcado como solução   
    @Veronica Sales Sim, podem ser apenas um dos conectores. Troque os dois. Troque antes a porta no switch onde está conectado. 
     
    O que eu disse sobre um cabo curto e testar na mesa é em resumo colocar o aparelho ligado em uma mesa onde tenha um computador com a pagina de configuração dele aberta, e onde ele possa atrair alguns clientes 🙂  e ver o que acontece. E consultar os logs. Para tentar interceptar uma falha em tempo real.
    Pode usar um script de monitoramento também, que alerte quando ele se desconecta. E pode ver se não coincide por exemplo com o fim do lease do DHCP se usa isso para ele
  12. O post de arfneto em somaxconn não existe? não consigo criar foi marcado como solução   
    siga o exemplo que tem lá na documentação. 
  13. O post de arfneto em Roteador ou Repetidor - Qual a melhor opção foi marcado como solução   
    Cabos Ca5 não são vistos há anos e se sua casa é nova dificilmente alguém usaria esses cabos nos últimos 10 ou 15 anos. Pode ser que simplesmente não usaram as 8 vias para atingir todos os pontos, e com 4 vias apenas não vai conseguir uma conexão a 1000 gbps.
     
    Por outro lado, em distâncias curtas mesmo um cabo cat5 conectaria a 1gigabit se tivesse as 8 vias do cabo conectadas corretamente.
     
     
    Pois é. Não é preciso um cabo CAT6 para essa modesta velocidade de meio gbps. E entenda que a velocidade da conexão na LAN NADA tem a ver com a velocidade contratada para acesso a internet. Você pode ter e precisar de uma rede a 10 ou 40 giga e não ter sequer acesso a internet na rede por questões de segurança, por exemplo.
     
    Para distâncias curtas e não tendo uma grande  fonte de  interferência no caminho dos cabos, um cabo CAT5e vai até 2.5 ou mesmo 5 gbps. 
     
     
    5GHz é uma frequência de wifi. Nada tem a ver com a internet. Como o alcance das antenas nessa frequência é bem modesto um sinal de 5GHZ não é bom candidato a um repetidor. Seria o caso de uma rede mesh mas para isso rodar bem o ideal é usar vários POD que possam ser conectados via cabo e você volta ao mesmo problema.
     
    Sugiro rever os conectores de sua rede e verificar se tem todos os sinais conectados nos terminais.
  14. O post de arfneto em como compilar um C com libmbp.h e imghelpers.h foi marcado como solução   
    salvaImagem("saida.bmp", R, G, B, c, l);  
     
    Com seis ou tres parâmetros, não parece bom. O que eu tentava dizer nos outros posts é que é muito mais conveniente usar encapsulamento e escrever em torno dos dados. O simples.
     
    O header não existe sem o bitmap. Os RBG lá são os pixels. nenhum deles existe sózinho. E os dados são só o bitmap. Então só se usa o bitmap.
     
     
    Foi o que eu tentei dizer 🙂 
     
    Uma outra solução
     
    Vou deixar uma quarta opção, algo que já postei aqui.  
     
    Porque outra solução? Para ter exemplo do que estou tentando explicar.
     
    Isso é um bitmap:
     
    typedef struct { BitmapFileHeader h_bmp; BitmapInfoHeader h_info; uint8_t* pixel; } Bitmap;  
    É isso que seu programa deve ver. E o usuário de sua biblioteca deve ver. E pode ser você mesmo. Não é esperto expor os aspectos internos, coisas que já estão embutidas, coisas que você pode querer mudar depois e vai ter então que mudar as chamadas em 2 mil lugares.
     
    Se o bitmap é isso, e ele é isso, então pode escrever
     
    typedef struct { char header[2]; int32_t fileSize; int32_t reserved; int32_t dataOffset; } BitmapFileHeader; typedef struct { int32_t headerSize; int32_t width; int32_t height; int16_t planes; int16_t bitsPerPixel; int32_t compression; int32_t dataSize; int32_t horizontalResolution; int32_t verticalResolution; int32_t colors; int32_t importantColors; } BitmapInfoHeader; typedef struct { BitmapFileHeader h_bmp; BitmapInfoHeader h_info; uint8_t* pixel; } Bitmap; Bitmap* bmp_copy(Bitmap*); Bitmap* bmp_create(unsigned w, unsigned h); Bitmap* bmp_destroy(Bitmap* bmp); int bmp_fill(Bitmap*, uint8_t, uint8_t, uint8_t); int bmp_grad(Bitmap* bmp); Bitmap* bmp_read(const char* filename); int bmp_setPixel( Bitmap* bmp, int x, int y, uint8_t red, uint8_t green, uint8_t blue); int bmp_to_bw(Bitmap*); int bmp_write(Bitmap* bmp, const char* filename);  
    Para ter um mínimo para testar.
     
    Bitmaps estão na memória e assim o simples é considerar:
    quer criar um bitmap? de que tamanho? Só isso. quer apagar um bitmap? Qual o endereço? Só isso. quer copiar um bitmap? De qual? Só isso. Bitmap* bmp_copy(Bitmap* origem); Bitmap* bmp_create(unsigned w, unsigned h); Bitmap* bmp_destroy(Bitmap* bmp); quer colocar uma cor em um pixel?  int bmp_setPixel( Bitmap* bmp, int x, int y, uint8_t red, uint8_t green, uint8_t blue);  
    Não é só isso? Então a gente não escreve mais que isso.
     
    int bmp_fill(Bitmap*, uint8_t, uint8_t, uint8_t); int bmp_grad(Bitmap* bmp); int bmp_to_bw(Bitmap*); bmp_fill é o simples para testar e preenche todo o bmp com a cor
    bmp_grad era pra exemplo. Cria esse bitmap:

    Escrevi isso só porque é simples e é legal de testar a transição das cores.
     
    O código está logo abaixo e é trivial.
     
     
     
     
     
     
    bmp_to_bw() é a função aqui do tópico. Então o simples seria o que? Pega o endereço do bitmap vai lá e transforma. inline. O gradiente fica assim
     
    E assim dá para ver os 256 tons de cinza em cada cor e comparar com o de cima...
     
     
     
     
     
     
     
     
    Ler / gravar
     
    Bitmap* bmp_read(const char* filename); int bmp_write(Bitmap* bmp, const char* filename);  
    Isso é mais simples. Quer ler? De onde? Quer gravar? Para onde?
     
    Assim é mais fácil de consumir a API. Veja:
     
    Bitmap* a_test = bmp_create(1024, 768); bmp_fill(a_test, 255, 0, 0); //vermelho bmp_write(a_test, "red.bmp"); bmp_destroy(a_test);  
    Esse trecho cria um bmp 1024x768, pinta de vermelho e grava no disco e apaga o bitmap da memória
     
    EXEMPLO
     
    Esse programa usa todas as funções e gera vários arquivos
     
    #include "bitmap.h" int main(void) { const int W = 1024; const int H = 768; // arquivos de teste const char* red = "red.bmp"; const char* green = "green.bmp"; const char* blue = "blue.bmp"; const char* blue_copy = "blueCopy.bmp"; const char* gradiente = "gradiente.bmp"; const char* gradiente_pb = "gradiente-pb.bmp"; Bitmap* a_test = bmp_create(1024, 768); if (a_test == NULL) { fprintf(stderr, "\tErro ao tentar criar bitmap\n"); return -1; } fprintf(stderr, "\tCriado BMP %dx%d\n", W, H); int res = 0; res = bmp_fill(a_test, 255, 0, 0); // red fprintf(stderr, "\tbmp_fill retornou %d\n", res); res = bmp_write(a_test, red); fprintf( stderr, "\tbmp_write() retornou %d ao criar %s\n", res, red); res = bmp_fill(a_test, 0, 255, 0); // green fprintf(stderr, "\tbmp_fill() retornou %d\n", res); res = bmp_write(a_test, green); fprintf( stderr, "\tbmp_write() retornou %d ao criar %s\n", res, green); res = bmp_fill(a_test, 0, 0, 255); // blue fprintf(stderr, "\tbmp_fill() retornou %d\n", res); res = bmp_write(a_test, blue); fprintf( stderr, "\tbmp_write() retornou %d ao criar %s\n", res,blue); Bitmap* a_copy = bmp_copy(a_test); fprintf( stderr, "\tbmp_copy() %s [%dx%d], size is %d, para %s\n", blue, a_copy->h_info.width, a_copy->h_info.height, a_copy->h_bmp.fileSize, blue_copy); res = bmp_write(a_copy, blue_copy); fprintf( stderr, "\tbmp_write() retornou %d ao gravar %s\n", res, blue_copy); res = bmp_grad(a_copy); fprintf(stderr, "\tbmp_grad() retornou %d\n", res); res = bmp_write(a_copy, gradiente); fprintf( stderr, "\tbmp_write() retornou %d ao criar %s\n", res, gradiente); res = bmp_to_bw(a_copy); fprintf(stderr, "\tbmp_to_bw() retornou %d\n", res); res = bmp_write(a_copy, gradiente_pb); fprintf( stderr, "\tbmp_write() retornou %d ao criar %s\n", res, gradiente_pb); a_test = bmp_destroy(a_test); a_copy = bmp_destroy(a_copy); fprintf(stderr, "\t[ F I M ]\n"); return 0; }  
    Saída
     
    Criado BMP 1024x768 bmp_fill retornou 0 bmp_write() retornou 0 ao criar red.bmp bmp_fill() retornou 0 bmp_write() retornou 0 ao criar green.bmp bmp_fill() retornou 0 bmp_write() retornou 0 ao criar blue.bmp bmp_copy() blue.bmp [1024x768], size is 3145782, para blueCopy.bmp bmp_write() retornou 0 ao gravar blueCopy.bmp bmp_grad() retornou 0 bmp_write() retornou 0 ao criar gradiente.bmp bmp_to_bw() retornou 0 bmp_write() retornou 0 ao criar gradiente-pb.bmp bitmap APAGADO bitmap APAGADO [ F I M ]  
    Uma implementação mínima
     
    #pragma pack(push, 2) #pragma pack(show) #include "bitmap.h" Bitmap* bmp_copy(Bitmap* orig ) { if (orig == NULL) return NULL; // sem origem // cria a copia Bitmap* cp = bmp_create(orig->h_info.width, orig->h_info.height); if ( cp == NULL ) return NULL; // deu pau // copia os headers, claro cp->h_bmp = orig->h_bmp; cp->h_info = orig->h_info; //copia os pixels uint8_t* de = orig->pixel; uint8_t* para = cp->pixel; // nesse exemplo sao 4 bytes por pixel, 32bpp, certo? for (int32_t i = 0; i < orig->h_info.width * orig->h_info.height * 4; i += 1) *para++ = *de++; return cp; // so isso: retorna a copia } Bitmap* bmp_create(unsigned w, unsigned h) { Bitmap* one = (Bitmap*)calloc(1, sizeof(Bitmap)); one->h_bmp.dataOffset = sizeof(BitmapFileHeader) + sizeof(BitmapInfoHeader); one->h_bmp.fileSize = one->h_bmp.dataOffset + (w * h * 4); one->h_bmp.header[0] = 'B'; one->h_bmp.header[1] = 'M'; one->h_info.bitsPerPixel = 32; one->h_info.headerSize = 40; one->h_info.height = h; one->h_info.horizontalResolution = 2400; one->h_info.planes = 1; one->h_info.verticalResolution = 2400; one->h_info.width = w; one->pixel = (uint8_t*)calloc( 1, (size_t)(w * h * 4 * sizeof(uint8_t))); if (one->pixel == NULL) { free(one); return NULL; } return one; }; Bitmap* bmp_destroy(Bitmap* bmp) { if (bmp == NULL) return NULL; if (bmp->pixel != NULL) free(bmp->pixel); free(bmp); fprintf(stderr, "\tbitmap APAGADO\n"); return NULL; } int bmp_fill( Bitmap* bmp, uint8_t red, uint8_t green, uint8_t blue) { if (bmp == NULL) return -1; uint8_t* p = bmp->pixel; for (int32_t i = 0; i < bmp->h_info.width * bmp->h_info.height; i += 1) { // 32bpp *p++ = blue; *p++ = green; *p++ = red; *p++ = 0xFF; // alpha } return 0; } int bmp_grad(Bitmap* bmp) { // preenche a imagem com 3 faixas verticais // em vermelho verde e azul, mas mudando a intensidade // da cor de 0 a 255 a cada linha if (bmp == NULL) return -1; uint8_t red = 0; uint8_t green = 0; uint8_t blue = 0; uint8_t* p = bmp->pixel; for (int y = 0; y < bmp->h_info.height; y++) { uint8_t color_value = (uint8_t)(255 * (double)y / bmp->h_info.height); for (int x = 0; x < bmp->h_info.width; x++) { switch (x / (bmp->h_info.width / 3)) { case 0: red = color_value; green = 0; blue = 0; break; case 1: red = 0; green = color_value; blue = 0; break; default: red = 0; green = 0; blue = color_value; break; } *p++ = blue; *p++ = green; *p++ = red; *p++ = 0XFF; } }; return 0; } Bitmap* bmp_read(const char* filename) { FILE* in = fopen(filename, "rb"); if (in == NULL) return NULL; Bitmap* one = bmp_create(800, 600); if (one == NULL) { fclose(in); return NULL; } size_t size = sizeof(BitmapFileHeader) + sizeof(BitmapInfoHeader); size_t res = fread((void*)one, (size_t)(1), size, in); if (res != size) return NULL; // agora calcula o que falta ler size = one->h_info.height * one->h_info.width * 4; // 32bpp uint8_t* area = (uint8_t*)realloc(one->pixel, size); if (area == NULL) { fclose(in); bmp_destroy(one); return (NULL); }; one->pixel = area; res = fread((void*)one->pixel, (size_t)(1), size, in); return one; } int bmp_setPixel( Bitmap* bmp, int x, int y, uint8_t red, uint8_t green, uint8_t blue) { if (bmp == NULL) return -1; uint8_t* pPixel = bmp->pixel; // get address of coordinates of x,y pPixel += (y * 4) * bmp->h_info.width + (x * 4); pPixel[0] = blue; pPixel[1] = green; pPixel[2] = red; pPixel[3] = 0xFF; return 0; } int bmp_to_bw(Bitmap* bmp) { if (bmp == NULL) return -1; uint8_t* p = bmp->pixel; for (int32_t i = 0; i < bmp->h_info.width * bmp->h_info.height; i += 1) { // 32bpp double value = (*p * 0.114) + *(p + 1) * 0.587 + *(p + 2) * 0.299; // isso e antigo // não e ideia minha, mas e uma mistura das cores // e fica ok como branco e preto *p++ = (int)(value); // r *p++ = (int)(value); // g *p++ = (int)(value); // b p++; // alfa não vai mexer, ja que e transparencia } return 0; } int bmp_write(Bitmap* bmp, const char* filename) { FILE* out = fopen(filename, "wb"); if (out == NULL) return -1; size_t res = 0; res = fwrite( &bmp->h_bmp, (size_t)1, sizeof(BitmapFileHeader), out); res = fwrite( &bmp->h_info, (size_t)1, sizeof(BitmapInfoHeader), out); size_t size = (bmp->h_info.width * bmp->h_info.height * 4); res = fwrite( (const void*)bmp->pixel, (size_t)(1), size, out); if (size != res) { fclose(out); fprintf( stderr, "\tbmp_write() write %zd. %zd expected\n", res, size); fclose(out); return -2; } res = fclose(out); return 0; } #pragma pack(pop)  
    Sugiro comparar e entender a razão de escrever em torno dos dados, usar encapsulamento e manter apenas ponteiros como argumentos e retorno. É muito mais simples de ler e de usar. E não expõe coisas internas. Não é vantagem usar 3 ponteiros para cada cor. Mas se usar e colocar como argumento e depois mudar de ideia vai ter que mexer em todas as chamadas em todos os programas que usam isso. 
     
     
     
    Entenda que ao ler precisa de DOIS fread só. E para gravar UM. E não de 2,4 milhões para um bmp de 1024x768....
     
    Um bitmap é um mapa. Vem um pixel atrás do outro.
     
    Veja o exemplo que deixei acima
    O header "bitmap.h" no exemplo seria 
     
    #pragma once #pragma pack(push, 2) #pragma pack(show) #include <stdint.h> #include <stdio.h> #include <stdlib.h> typedef struct { char header[2]; int32_t fileSize; int32_t reserved; int32_t dataOffset; } BitmapFileHeader; typedef struct { int32_t headerSize; int32_t width; int32_t height; int16_t planes; int16_t bitsPerPixel; int32_t compression; int32_t dataSize; int32_t horizontalResolution; int32_t verticalResolution; int32_t colors; int32_t importantColors; } BitmapInfoHeader; typedef struct { BitmapFileHeader h_bmp; BitmapInfoHeader h_info; uint8_t* pixel; } Bitmap; Bitmap* bmp_copy(Bitmap* origem); Bitmap* bmp_create(unsigned w, unsigned h); Bitmap* bmp_destroy(Bitmap* bmp); int bmp_fill(Bitmap*, uint8_t, uint8_t, uint8_t); int bmp_grad(Bitmap* bmp); Bitmap* bmp_read(const char* filename); int bmp_setPixel( Bitmap* bmp, int x, int y, uint8_t red, uint8_t green, uint8_t blue); int bmp_to_bw(Bitmap*); int bmp_write(Bitmap* bmp, const char* filename); #pragma pack(pop)  
  15. O post de arfneto em Estou conectado na Internet, mas não consigo acessar nada foi marcado como solução   
    @Maurício Rockembach Nesses problemas de conectividade tem que ser metódico, quase paranóico, para isolar o problema. E não seriam esses comandos --- flush de cache de DNS ou ProcessIdleTasks ---
    que iriam ajudar.
     
    Reinstalar o sistema pode também não resolver nada. A causa mais comum disso está em roteadores ligados errado, coisas como servidores DHCP perdidos na rede. Há casos em que na ânsia de resolver usuários copiam e rodam listas de uma dúzia de comandos e alguns interferem mesmo na rede. Outro caso é digitar valores errados no formulário de configuração de DNS. Rotas inválidas, gateways inoperantes, uma longa lista.
     
     
    Bom que funcionou. Em muitos casos é só perda de tempo. 
     
     Tem que procurar em sua própria máquina. São comandos simples. Mas tem que ser metódico e saber o que procurar. É um porre isso --- minha opinião.
     
    EXEMPLO
     
    O último que eu vi, numa casa com 4 roteadores, 2 servidores DHCP e uns 30 pontos de rede: uma marcenaria chegou para instalar 2 painéis desses que se usa para colocar TV na parede. Uma das TV tinha um roteador colado nela, um desses AX73 ou similar da TP-Link. Desligaram e desmontaram tudo. Ao final da instalação o dono da casa não viu que o roteador estava desligado. Uma parte dos dispositivos não se conectava com a internet. Às vezes. Redes wifi sumiram e tal. 
    Para resolver ele pesquisou na internet e tal. Aí ligou o aparelho na mesa e usou o aplicativo da fábrica e reiniciou o infeliz para a configuração de fábrica e conectou tudo de volta. E tudo ficou maluco na rede toda.
    Passou a ter um servidor DHCP novo, com gateway inválido e endereços válidos acho que por um dia. Claro que tudo que se conectasse através dele não ia para lugar algum. 
    Só que nem sempre. Pela natureza dos protocolos e pela natureza do rádio a cada vez que reconectava um aparelho ele podia receber endereço de outro servidor e funcionar ok até vencer o intervalo de validade, que é de 5 minutos naquela rede. E aí nova loteria.
  16. O post de arfneto em Soma de valores usando Lista Duplamente Encadeada em C. foi marcado como solução   
    Uma vez resolvida a parte da lista, a soma usa o algoritmo do ensino fundamental (primário): alinha os valores pela direita e soma. Passou de 10 "vai um" e tal. Nada mais.
     
    Como o simples é somar a partir das unidades use os ponteiros a partir do fim da lista. E seja esperto e GUARDE na lista esses ponteiros....
     
    Veja esse exemplo
     
    typedef struct no_ { void* item; struct no_* proxima; struct no_* anterior; } Node; // um no typedef struct { char* nome; unsigned quantos; unsigned maximo; Node* inicio; Node* fim; } Lista;  
    A lista é uma lista de Node, mas tem um total de nós e um ponteiro para o início e para o fim. É disso que você precisa. A menos que queira ficar guardando ponteiros pra todo lado na hora de somar. Em item estariam os dígitos dos números, claro. E pode trocar o void* item por char digito
     
    Há muitos exemplos de lista aqui no forum. Eu por exemplo já postei muitos e pode pesquisar no conteúdo
  17. O post de arfneto em Conexão local sem acesso a rede. foi marcado como solução   
    É muito raro precisar de um cabo crossover hoje em dia. Há décadas os aparelhos detectam isso automaticamente. De todo modo um cabo crossover apenas inverte os pares 1-2 3-6.
     
    O que precisa fazer para usar isso, uma ligação ponto a ponto entre duas máquinas, é configurar manualmente as duas na mesma rede ou ativar um serviço DHCP em uma das pontas.
    Note que ativar o compartiilhamento de conexão a internet de um lado vai implicitamente fazer isso...
  18. O post de arfneto em Telefonia na Nuvem VIVO caindo foi marcado como solução   
    Uma ligação VOIP consome perto de 60/100 kbps. Não é algo assim muito exigente. Telefones VOIP tem interface de 100mbps e sempre dá conta. Muitos tem até uma saída LAN para ligar o computador usando um ponto só. E funcionam.
     
    Esses Grandstream GXP1615 são compatíveis com Poe então basta o cabo de rede.
     
     
    Imagino que tenha um switch PoE ou dois. 
     
    E --- se não fez isso ainda --- separe sua rede local da rede dos telefones. 
     
    O tráfego na LAN pode muito bem congestionar tudo, mesmo sem qualquer relação com a internet ou VOIP. 
     
     
  19. O post de arfneto em Programa de Cadastro de Empresas em C foi marcado como solução   
    Ainda no tópico #3 te disse que não pode escrever assim. Esse valor tam deve ser conhecido em tempo de compilação. Não pode ser um valor lido na hora em que o programa está rodando porque o compilador precisa reservar essa área ao gerar o código.
     
    Se precisa criar na hora deve alocar a memória necessária usando malloc() de stdlib.h. Existe uma extensão para C que admite isso, um troço chamado VLA, mas nunca foi adiante e não irá agora, depois de 50 anos.
      
    // 200, fixo Empresa cadastro[200]; // variavel, tam Empresa* cad = malloc(tam* sizeof(Empresa));  
    Assim é.
     
    Da minha lista de problemas comuns:
    não use comentários com acentos. Podem não sair na tela em algumas maquinas ou pode sair tudo errado na tela ou na eventual impressão. evite comentários óbvios como // FUNCAO P/ LIMPAR A TELA void limpar() { printf("\n\n\n"); system("clear"); printf("\n\n\n"); }  
    Ainda sobre essa função, qual o propósito de escrever 3 linhas em branco, que ninguém vai ver, e depois limpar a tela?
     
    Veja esse comentário em seu programa:
     
    // INICIO DA MAIN int main(void)  
    Acha que acrescentou algo dizer que ali é o ínicio da função?
     
    Sobre system: é apenas uma função que pega uma string, um texto, e tenta rodar usando o interpretador de comandos do sistema. É proibida em toda parte, escolas e empresas. Como te disse, não vai aprender nada com isso. E system foi escrita em C. O sistema foi escrito em C. E deve imaginar que tem uma função para limpar a tela, em C, para o seu sistema operacional.
     
    Sobre pause: é uma coisa simples: você roda um programa para fazer algo e terminar. Não para fazer algo e ficar esperando um infeliz ficar em frente a tela para teclar ENTER depois que o programa fizer o que se espera que ele faça.
     
    EXEMPLO: 
     
    Você escreveu o programa soma.exe para rodar no windows. Você usa assim: 
     
    C:\Clube do Hardware>soma 42 17 42 + 17 = 59 C:\Clube do Hardware>soma 1700 4200 1700 + 4200 = 5900  
    E está ok. Mas se você fizer como "recomendado" e usar um pause imagine o que vai acontecer:
     
    C:]Clube do Hardware>soma 3 4 3 + 4 = 7 Press any key to continue . . . C:\Clube do Hardware>soma 5 6 5 + 6 = 11 Press any key to continue . . .  
    E você tem que digitar um ENTER. Ou chamar alguém pra ficar lá esperando. Mas imagine que você tenha uma lista de programas
     
    soma 2 3 soma 17 42 soma 2300 1 soma 0 0  
    Então você poderia por num arquivo e rodar todos de uma vez e esperar pelo resultado... basta digitar por exemplo .
     
    soma 2 3 & soma 17 42 & soma 2300 1 & soma 0 0  
    SEM o infeliz PAUSE:
     
    O sistema sabe que é pra rodar os programas um depois do outro e pronto
     
    C:\Clube do Hardware>soma 2 3 & soma 17 42 & soma 2300 1 & soma 0 0 2 + 3 = 5 17 + 42 = 59 2300 + 1 = 2301 0 + 0 = 0  
    Mas se fizer o recomendado....
     
    C:\Clube do Hardware>soma 2 3 & soma 3 4 2 + 3 = 5 Press any key to continue . . .  
    Genial., Tem que  teclar ENTER para rodar a próxima soma. Tem que ter alguém lá em frente ao teclado. Tosco. Não se escrevem programas para isso.
     
    Sobre void: Retornar void é ingênuo. Veja sua função
     
    void cadastrarEmpresa(int tam, Empresa cadastro[])...  
     
    O que se quer aqui? Simples: inserir uma empresa em um cadastro. Só que não é o que está escrito.
     
    Considere a alternativa
     
    int cadastrar(Empresa emp, Cadastro cad) { return 0; };  
    Você quer cadastrar uma empresa em um cadastro de empresas. Então você passa pra função uma empresa e um cadastro. E a função faz o serviço dela. Retorna 0 se deu certo, retorna -1, -2 ou qualquer coisa negativa para o caso de erro. Não acha mais esperto? Novidade não é. Sempre é feito assim.
     
    Sobre ler dados do teclado
     
    Entenda que seu programa tem um monte de funções e tem um monte de coisas pra testar. Não é nada esperto ficar digitando coisas a cada teste. 
     
    Sua empresa tem 6 campos. Um deles é o endereço e pode ter mais de um por empresa. Se for testar o programa com 3 empresas vai ter que digitar 18 campos. Só que endereco tem 6 campos também. Se usar 2 enderecos por empresa para 5 empresas imagina quanto tempo vai demorar cada simples teste que for fazer? 
     
    E você está aprendendo então é boa a chance do programa cancelar na sua cara logo depois de ficar 5 minutos inventando dados.
     
    sobre "NULL"
     
    NULL é um texto, um valor objetivo. NULL é o que se usa quando não tem nada no campo.
     
    Se você escrever 
     
    Empresa cadastro[20] = {0};  
    por exemplo, o sistema vai colocar esse valor em cada lugar do vetor inteiro.
     
    Sobre constantes e inicialização
     
    typedef struct { char pais[80]; char estado[80]; char municipio[80]; char logradouro[80]; int numero; int cep; } Endereco;  
    Pois é. Então pode usar
     
    Endereco teste = { .cep = 222, .estado = "SP", .logradouro = "Av. Antiga", .municipio = "Vila Nova", .numero = 42, .pais = "Terra Nova"};  
    E colocar valores na estrutura toda.
     
    Sobre um menu
     
    Imagine essa função:
     
    int menu1();  
    Ela mostra um menu e retorna o valor da opção que o cara escolheu. Não é conveniente????
     
    Sobre fflush
     
    fflush só está definido para saída. Não está no padrão fflush da entrada como está fazendo. Isso não existe exceto em um ou outro compilador e não é certo que vá funcionar. 
     
    Sobre o uso de arquivos
     
    Em C é trivial criar arquivos. Essa linguagem foi criada para ajudar a escrever um sistema, o Unix, que virou Linux, MacOS, Android e outros nessas décadas todas. No Unix tudo é arquivo então dá pra imaginar que é fácil usar arquivos em C.
     
    EXEMPLO
     
    int cria_arquivo(const char* nome, const char* texto) { FILE* arq = fopen(nome, "w"); if (arq == NULL) return -1; fprintf(arq, "arquivo: \"%s\"\n", nome); for (int i = 0; i < 5; i += 1) fprintf(arq,"%06d \"%20s\"\n", 1 + i, texto); fclose(arq); return 0; }  
    Essa função trivial chamada assim
     
    cria_arquivo("teste.txt", "valor");  
    cria o arquivo teste.txt com isso dentro
     
    arquivo: "teste.txt" 000001 " valor" 000002 " valor" 000003 " valor" 000004 " valor" 000005 " valor"  
    Nada mais
     
    Sobre o código postado
     
    Pouco corrigiu dos problemas que apontei. Uso incorreto de scanf, printf, fflush e tal. Sugiro ir refinando o programa conforme aprende.
     
    typedef struct { char pais[80]; char estado[80]; char municipio[80]; char logradouro[80]; int numero; int cep; } Endereco; typedef struct { int id; char nome[80]; char cnpj[80]; char proprietario[80]; int funcionarios; int qtd_endereco; Endereco endereco; } Empresa;  
    Criou um campo qtd_endereco mas só tem lugar pra 1. Que diferença faz? E os outros?
     
    Pra que 80 bytes num cnpj? Porque cep é int? vai somar? Porque estado tem 80? Seu compilador não reclamou pelo tamanho da pilha porque declarou errado o vetor.
     
    A noção de container
     
    Todos esses programas de iniciantes giram em torno da noção de container, coleção, algum tipo de cadastro. Se usar isso desde o início sua vida vai ficar muito mais simples
     
    Escreva em torno dos dados
     
    Cade o cadastro? Porque não tem essa estrutura em seu programa? Acha que basta um vetor??
     
    Não basta. Só dá muito mais trabalho se ficar só com o vetorzinho. Considere uma alternativa bobinha:
     
    typedef struct { unsigned tam; // tamanho unsigned lim; // limite Empresa emp[20]; } Cadastro;  
    Não fica claro que o limite é 20 e que  se colocar tam = 0 a estrutura fica marcada como vazia? Não é mais simples?
     
    E a mesma coisa não serviria para os endereços, já que seria um outro container, a mesma coisa? Algo assim não ajudaria:
     
    typedef struct { unsigned tam; // tamanho unsigned lim; // limite Endereco end[5]; } Enderecos;  
    Sim,  a mesma coisa.
     
    Como usar? Trivial: basta colocar isso em cada empresa
     
    typedef struct { int id; char nome[80]; char cnpj[15]; char proprietario[80]; int funcionarios; Enderecos end; } Empresa;  
    E claro que não precisa mais da quantidade de endereços em Empresa porque a estrutura já tem seu contador DENTRO.
     
    Veja como pode ser simples:
     
    int limpar_cadastro(Cadastro* cad,unsigned tam) { if ( cad == NULL ) return -1; cad->lim = tam; cad->tam = 0; // vazio return 0; }  
    O que importa é começar logo a testar o programa. Precisa de uma empresa? Um cadastro? Um endereco? Use C, use o computador.
     
    int cadastra(Empresa emp, Cadastro* cad) { if (cad == NULL) return -1; if (cad->tam >= cad->lim) return -2; // não cabe cad->emp[cad->tam] = emp; // copia a empresa cad->tam += 1; // conta essa return 0; }  
    cadastrar uma empresa pode ser só isso. Se voltou zero está ok.
     
    Veja a saida de um exemplo
     
    Cadastro tem 4 [de 20] empresas Amazonia (CNPJ:123.456.78-45) Amazon (CNPJ:123.456.78-03) Google (CNPJ:123.456.78-02) Microsoft (CNPJ:123.456.78-04)  
    Só digitando os dados. Sem entrada, sem pausa, sem esperar. Em 5 minutos estamos testando e já rodou da primeira vez
     
    #include <stdio.h> #include <stdlib.h> typedef struct { char pais[80]; char estado[3]; char municipio[80]; char logradouro[80]; int numero; char cep[10]; // 01234-012 } Endereco; typedef struct { unsigned tam; // tamanho unsigned lim; // limite Endereco end[5]; } Enderecos; typedef struct { int id; char nome[80]; char cnpj[15]; char proprietario[80]; int funcionarios; Enderecos end; } Empresa; typedef struct { unsigned tam; // tamanho unsigned lim; // limite Empresa emp[20]; // max 20 } Cadastro; int limpar_cadastro(Cadastro*); int cadastra(Empresa, Cadastro*); int lista(Cadastro*); int cria_arquivo(const char*, const char*); int main(void) { Endereco teste = { .cep = "123450678", .estado = "TN", .logradouro = "Rua Antiga", .municipio = "Vila Nova", .numero = 42, .pais = "Terra Nova"}; Empresa emp_1 = { .cnpj = "123.456.78-45", .nome = "Amazonia"}; int res = 0; Cadastro um; limpar_cadastro(&um, 20); // cadastra umas empresas res = cadastra(emp_1, &um); res = cadastra( (Empresa){ .cnpj = "123.456.78-03", .nome = "Amazon"}, &um); res = cadastra( (Empresa){ .cnpj = "123.456.78-02", .nome = "Google"}, &um); res = cadastra( (Empresa){ .cnpj = "123.456.78-04", .nome = "Microsoft"}, &um); // lista lista(&um); return 0; } // https://www.clubedohardware.com.br/forums/topic/1654426-programa-de-cadastro-de-empresas-em-c/#comment-8620688 int cadastra(Empresa emp, Cadastro* cad) { if (cad == NULL) return -1; if (cad->tam >= cad->lim) return -2; // não cabe cad->emp[cad->tam] = emp; // copia a empresa cad->tam += 1; // conta essa return 0; } int lista(Cadastro* cad) { printf( "Cadastro tem %u [de %u] empresas\n\n", cad->tam, cad->lim); for (int i = 0; i < cad->tam; i += 1) { printf( " %s (CNPJ:%s)\n", cad->emp[i].nome, cad->emp[i].cnpj); } printf("\n"); return 0; } int limpar_cadastro(Cadastro* cad, unsigned tam) { if (cad == NULL) return -1; cad->lim = tam; cad->tam = 0; // vazio return 0; } int cria_arquivo(const char* nome, const char* texto) { FILE* arq = fopen(nome, "w"); if (arq == NULL) return -1; fprintf(arq, "arquivo: \"%s\"\n", nome); for (int i = 0; i < 5; i += 1) fprintf(arq, "%06d \"%20s\"\n", 1 + i, texto); fclose(arq); return 0; }  
    Agora pode inserir os enderecos e continuar testando, mas o que importa é entender como deve escrever em torno dos dados. E NUNCA escrever um programa interativo.
  20. O post de arfneto em Questionamentos sobre a ONU EG8145v5. foi marcado como solução   
    O que importa não é só a quantidade de equipamentos mas a cobertura. Como eu disse, não dá pra colocar um rádio em dois lugares, E assim, em especial a 5GHz não é esperto desligar o wifi que você já tem na ONU. Raramente wifi a 5ghz passa com qualidade mais de uma parede...
     
    Sobre o duplo NAT se tem é porque ligou errado. Não deve nunca usar a porta WAN em roteadores que não o que está ligado de fato à WAN. A menos que possa desabilitar NAT no primeiro roteador e ligar apenas roteadores nesse nível, mas aí provavelmente saberia porque precisa disso e como fazer.
     
    Nos últimos meses postei muitos roteiros, desenhos, roteiros e argumentos de como ligar muitos roteadores ao mesmo tempo em redes domésticas ou de pequenas empresas. E parei de repetir.
     
    Tenho uma lista de alguns tópicos e pode ver lá e perguntar aqui sobre qualquer dúvida...
     
    Veja 
    Alguns números
    https://www.clubedohardware.com.br/forums/topic/1605208-como-criar-uma-rede-pública-isolado-com-um-segundo-roteador/#comment-8429612
     
    Outro caso
    https://www.clubedohardware.com.br/forums/topic/1606750-configurando-roteadores-d-link-dir-842-e-apple/#comment-8434558
     
    detalhes aqui
     
    https://www.clubedohardware.com.br/forums/topic/1613345-abrir-porta-com-modem-que-distribui-faixa-de-ip-diferente-para-o-roteador/#comment-8460463
     
    exemplo
     
    https://www.clubedohardware.com.br/forums/topic/1625440-velocidade-duplex-pode-causar-quedas-de-internet/#comment-8506640
     
    resumo 
     
    Nunca conecte roteadores secundários via porta WAN. Isso cria outras redes IP e segmenta o tráfego. A primeira rede não vê as outras. As outras veêm a primeira apenas porque nela é que está o gateway padrão dos roteadores. Fora isso quase nada funciona mais direito. Incorre em múltiplo NAT e pode perder metade da banda nas redes que não a primeira só por causa disso. Nada vai funcionar direito com dispositivos que não estejam na mesma rede IP. Isso inclui espelhamento de tela de celulares, compartilhamento de arquivos, impressoras wifi, lâmpadas acessórios smart  e outras coisas. Encaminhamento de portas tem que ser repetido em TODAS as redes secundárias. Broadcast de rede não passa pelos roteadores e assim coisas como Wake-on-LAN não vão funcionar. Desconexão temporárias por alguns segundos  acontecem quase sempre devido aos intervalos de lease de DHCP. Acesso remoto é um pesadelo.  


  21. O post de arfneto em Ligar computador de qualquer canto fora da minha rede. Wake on Wan/Wake on Lan. foi marcado como solução   
    Não, @snake odeia HD não é por isso que existe essa opção 
     
    E ela não é a mesma coisa que WOR ou WOL.
     
    No BIOS --- sim, em português BIOS é masculino, o S de sistema, masculino --- essa opção existe em geral com 3 opções: "Último Estado", "Ligado" e  Desligado" para permitir essencialmente que 
    ao cair a força: quando voltar a energia o micro possa reiniciar sozinho. Isso existe porque em caso de micros que existem apenas para rodar algum aplicativo, talvez sem teclado ou monitor, no caso de cair a força ele reinicie sozinho e tudo volte ao normal (usando scripts de login e de configuração) sem ter que ir alguém até lá só pra apertar o botão. Os tais "servidores" por exemplo. Imagine ter um servidor de mídia em sua casa, com mídia. Filmes e vídeos e música. Ele pode ficar dentro do armário ou no teto ou em outro piso. Ao ligar o micro o aplicativo de mídia entra no ar. Plex é o exemplo mais comum. E logo em seguida você pode passar a assistir mídia pela rede toda ou mesmo de fora dela. para esse caso se usa a configuração "Last State" de modo que se o micro estava ligado e desliga ao voltar a força ele liga de novo mas nesse caso se você o desligar e cair a força nada acontece ao voltar: o micro continua desligado como desligado estava. E é isso o que se quer e é isso que essa opção resolve com a configuração em OFF ao cair a força --- mesmo com o servidor ligado --- quando voltar ele não vai ligar. Essa é a configuração para um computador comum. mas com a seleção em "Always on"  --- ou seja lá como estiver em sua versão de BIOS --- ao ligar na tomada ele sempre vai ligar. Não há como saber se é o que você quer. Se você tirar a placa e levar para outro lugar ou para outro uso continua assim. Se rodar outro sistema continua assim. Se você mudar o micro de lugar e ligar na tomada ele vai ligar. De bobeira. TODA VEZ. E pode ter gente que não sabe disso, ao seu lado no escritório ou em casa. essa é a mesma coisa que acontece com WOR: você deixa seu micro ligado permanentemente a um ramal no escritório, ou a uma linha telefônica. Se alguém ligar, de propósito ou não ele vai ligar. Se alguém ligar da Polonia a cobrar ele vai ligar. Pela tensão do Ring apenas. Não é o que se quer em geral, mas décadas atrás isso já era um avanço porque permitia o óbvio: ligar um servidor ou um computador importante por telefone, sem ter que ir até ele. existiam até tomadas controladas por telefone, exatamente o que faz essa que mostrou aí, só que essas de hoje usam ethernet (wifi é ethernet). E qual a diferença afinal?
     
    Simples: WOL usa pacotes de broadcast que tem o endereço de rede do micro a ser ligado embutido na mensagem. Tem o endereço da placa de rede, não o endereço IP, claro, já que a máquina provavelmente está desligada. Todos os micros da rede recebem isso, mas apenas a placa de rede com esse endereço vai atender e ligar o micro, se as outras condições estiverem ok.
     
    Ainda pode ser enviado por engano, mas entenda o quanto é mais confiável...
     
    Não é como essa tomada que pode ligar um lustre no fim do corredor. 
     
    Pode atender a necessidade de muitos, mas espero que tenha entendido que não é a mesma coisa que Wake on Lan e que essa opção de configuração não existe para isso.
     
    As opções de Wake-up são as que em geral estão no mesmo menu no BIOS:
    atividade via PCI atividade via PCIx RTC - relógio: liga em certo horário teclado - para teclados que tem a tecla POWER ou uma convenção como Control-ESC mouse - algum movimento no mouse liga a máquina  
     
     
     
  22. O post de arfneto em Rede caseira entre um PC desktop (sem wifi) e um Macbook (não conecta cabo) foi marcado como solução   
    "Rede caseira entre um PC desktop (sem wifi) e um Macbook (sem ethernet)"
     
    @ThiagoVideo wifi também é ethernet...
     
    Se os dois acessam a impressora então já tem uma parte do caminho. Se acessa a internet a partir dos dois estão na mesma rede ou ao menos compartilham o mesmo gateway de algum modo...
     
    O simples é criar uma conta no MAC e no Windows com o mesmo nome e senha. E colocar os dois no mesmo grupo de trabalho. Acho que isso pode ser feito direto na interface gráfica dos dois sistemas, sem instalar nada mais.
     
    Se for preciso instalar algo instale SMB no MAC --- o pacote SAMBA --- e edite smb.conf para criar as contas e compartilhamentos do MAC para o Windows. Do lado do MAC o cliente SMB já deve localizar os compartilhamentos do windows e não precisa fazer nada.
     
    MacOS é Linux há tempos. Então pode abrir um terminal e ver se existe a pasta /etc/samba por exemplo
  23. O post de arfneto em PC conectado via cabo não encontra Notebook conectado via Wi-Fi foi marcado como solução   
    Pode ter algo do tipo wifi isolation que pode estar ativo na configuração do wifi. Se não tem acesso ao aparelho deve consultar o provedor e pedir para desabilitar. Muita gente achava que isso era bom e que aumentava a segurança... 
  24. O post de arfneto em Reestruturar WiFi de uma casa grande foi marcado como solução   
    Bem, se leu o que eu escrevi já deve imaginar o que vou escrever a seguir: ligue toda a infraestrutura via cabo. Descarte o repetidor e compre outro roteador. Repetidores são algo pra usar em algum tipo de emergência. Vão repetir um sinal quando começar a degradar? E o máximo que vão repetir é o que chega até ele. E o tráfego do que vier a ser ligado nele vai todo passar por ele.
     
    Coloque um roteador perto de cada TV e um outro lá pro fim da casa. Esse terceiro pode ser um AP wifi mesmo, mas um roteador é melhor porque o preço é parecido e o roteador vai te dar mais 3 portas LAN, já que cada roteador tem um switch embutido.
     
    Se for comprar algo wifi não compre NADA que não seja wifi6 ou wifi6E. Sobre onde colocar apenas use um celular e um aplicativo como o wifi analyzer que tem pro telefone do robo e o da frutinha. Coloque seu Archer onde quer medir o sinal e simplesmente veja na tela do celular os valores em dbm. Nem precisa saber o que é bom. Pode só conectar e ver as barrinhas. E claro que não precisa de internet. A rede wifi é um subconjunto da rede local. Nada tem a ver com a internet.
     
     
    Deve estar enganado quanto ao DHCP. Fixou mesmo endereços para os celulares e as TV?
     
    Como sabe se tem uma única rede IP?
     
    Não teria ligado o C60 ou o tal repetidor via porta WAN teria? Usou aquela porta azul????
     
    Como te expliquei cada roteador inclui um switch. O da VIVO tem 3 portas LAN o C60 tem 4. Como tem que ligar um ao outro vai usar uma de cada.
     
     
  25. O post de arfneto em Computador não consegue achar rede wifi sem fio foi marcado como solução   
    Isso explica tudo

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