Ir ao conteúdo
  • Cadastre-se

isrnick

Membro Pleno
  • Posts

    1.550
  • Cadastrado em

  • Última visita

posts postados por isrnick

  1. Estou configurando um computador para usar como NAS para casa, cuja principal função é para armazenar e assistir videos via PLEX/Emby/Jellyfin, mas também para as funções típicas de um NAS como armazenamento de backups, substituir Dropbox/One Drive/etc...

     

    Até agora a configuração é:

     

    Processador Intel Pentium Gold G7400 3.7GHz, 2-Cores, 4-Threads, LGA 1700

    placa-mãe ASUS PRIME H610M-E D4, CHIPSET H610, INTEL LGA 1700, MATX, DDR4

    MEMÓRIA DDR4 GEIL ORION, 16GB (2X8GB) 3200MHZ

    M.2 ngff b-chave sata para sata 5 porta placa de expansão 6gbps placa de expansão jmb585 chipset suporte SSD e hdd

     

    O processador foi escolhido por ter UHD Graphics 710 para fazer transcode, pois minha coleção de vídeos está principalmente no formato H265/HEVC, e por ter baixo consumo de energia (já que é um servidor pra ficar sempre ligado).

     

    placa-mãe escolhida por ter dois M.2 permitindo usar uma para um SSD NVMe, e a outra para colocar a placa de expansão de portas SATA. (O PCI-e pode ficar livre para ser usado para colocar uma placa Ethernet 2.5Gbits no futuro.)

     

    Ainda não defini a fonte, nem o gabinete, mas por enquanto pretendo usar um gabinete velho que tenho disponível e que caberia várias HDs de 3.5" (umas 8 ou 9 HDs), até achar uma opção melhor.

     

    A ideia é colocar entre 6 a 8 HDs de 4TB. E usar TrueNAS como sistema operacional no SSD NVMe, para montar RAIDZ2 (ZFS com 2 discos de paridade).

     

    Peço que deem suas sugestões e opiniões.

  2. 26 minutos atrás, Lucca Rodrigues disse:

    @isrnick

    Funciona só se o buffer não estiver vazio.

    Mas aí você pode tentar garantir que sempre sobre pelo menos o caractere nova linha na entrada antes de chamar a função para limpar a entrada.

     

    Do contrário vai ter que usar algo que nunca deixe nada sobrando na entrada, como a função getline do padrão PÒSIX, ou minha função nscanf:

     

    OBS: getline não é uma função padrão ISO da linguagem C, então se não estiver disponível no seu compilador pode ter que achar uma implementação pronta na internet, ou implementar você mesmo.

    • Curtir 1
  3. @thefill Não use o primeiro método de "limpar" entrada desse link, está usando fflush para algo que ele não foi feito (ele é apenas para fluxos de saída) logo terá comportamento indefinido, ou seja não dá pra garantir que funcione. Use apenas o segundo pois funciona em todas as situações.

  4. Não reduz muito, poderia checar as 3 verticais assim:

    for(int i=0; i<3; ++i){
        if(m[0][i]==m[1][i] && m[1][i]==m[2][i]){
            //....
        }
    }

    Aí tem que fazer outro loop para as horizontais, e para as diagonais vão ser só 2 ifs mesmo.

  5. Uma maneira de reduzir pela metade os ifs seria simplesmente verificar se os casas adjacentes são iguais entre si, ao invés de checar se são iguais a 'X' ou 'O'. Por exemplo:

     

    if(m[0][0]==m[1][0] && m[1][0]==m[2][0])

    Assim não importa se a casa é 'X' ou 'O', só que tem 3 valores iguais (mas note que também precisa eliminar o caso em que as posições da matriz são iguais mas não foram preenchidas com 'X' nem 'O').

     

    Fora isso seria necessário fazer usar ciclos while ou for para percorrer a matriz e checar as posições se quiser tentar reduzir mais.

  6. @thefill Essa mensagem de warning está dizendo que a função gets é perigosa e não deve ser usada. E ela é perigosa pois não limita o número de caracteres lidos e armazenados no vetor de char, o que significa que se a entrada for mais longa do que o tamanho vetor ele vai estourar o tamanho do espaço alocado, tentando guardar valores além deste espaço.

     

    Mas o modo como você usou a função scanf tem exatamente o mesmo problema da função gets pois não limita o tamanho da string que pode ser lida, resultando no mesmo perigo de estourar o tamanho do vetor de char.

     

    O modo correto seria assim:

    scanf(" %49s", dados[i][h][j].curso);
    
    //Ou se também quiser armazenar frases, não apenas palavras:
    
    scanf(" %49[^\n]", dados[i][h][j].curso);

    Limitando para ler no máximo 49 caracteres não nulos (e nesse caso extremo usaria a 50ª posição do vetor para armazenar o caractere nulo '\0' indicando o fim da string).

     

    Ou então também pode usar a função fgets:

    fgets(dados[i][h][j].curso, 50, stdin)

    Pois ela exige que forneça o tamanho do vetor, e limita a leitura baseado nisto.

    • Obrigado 1
  7. @arfneto No Windows você redirecionou a saída de type (e depois de echo) para os executáveis dos seus programas, e é o type quem adiciona o caractere nova linha '\n' no fim do texto do arquivo um.txt ...

     

    O modo correto de redirecionar um arquivo texto como entrada de um executável no Windows é assim:

     

    t-gcc.exe < um.txt

     

    Veja o resultado do seu programa compilado em ambos no MSVC (cl) e no Mingw/GCC, fazendo o redirecionamento corretamente:

     

    C:\C-Cpp>type um.txt
    agora no Windows...
    C:\C-Cpp>cl t.c
    Microsoft (R) C/C++ Optimizing Compiler Versão 19.16.27045 para x86
    Copyright (C) Microsoft Corporation. Todos os direitos reservados.
    
    t.c
    Microsoft (R) Incremental Linker Version 14.16.27045.0
    Copyright (C) Microsoft Corporation.  All rights reserved.
    
    /out:t.exe
    t.obj
    
    C:\C-Cpp>gcc -o t-gcc.exe t.c
    
    C:\C-Cpp>t.exe < um.txt
                                        ....*....1....*....2....*....3
                                        1...*....0....*....0....*....0
    Digite uma frase com ate 30 letras:     Leu 19 letras. A frase:
    97 103 111 114 97 32 110 111 32 87 105 110 100 111 119 115 46 46 46
    A frase: agora no Windows...
    
    C:\C-Cpp>t-gcc.exe < um.txt
                                        ....*....1....*....2....*....3
                                        1...*....0....*....0....*....0
    Digite uma frase com ate 30 letras:     Leu 19 letras. A frase:
    97 103 111 114 97 32 110 111 32 87 105 110 100 111 119 115 46 46 46
    A frase: agora no Windows...

     

    Não há exceções, a função fgets() não adiciona caractere '\n' no fim do texto em nenhum deles.

     

     

    • Curtir 2
  8. 41 minutos atrás, arfneto disse:

    A implementação INSERE um newline se tiver espaço para ele e um não tiver sido digitado na entrada.

    A função fgets não insere caractere nova linha '\n'.

     

    Como exemplo veja esse simples código:

    #include <stdio.h>
    
    int main()
    {
        char s[32];
        fgets(s, sizeof s, stdin);
        printf("\n%sAAA", s);
        return 0;
    }

     

    Quando executado no site https://www.onlinegdb.com/online_c_compiler e digitado abc e a aperta Enter, resultando em "abc\n" na entrada padrão stdin, a execução do programa fica assim:

     

    abc
    
    abc
    AAA

     

    Mas quando digita abc e aperta Ctrl+D para sinalizar o fim da entrada sem inserir o caractere '\n' (equivalente de Ctrl+Z no Windows), resultando em "abc" no stdin, a execução do programa fica assim:

     

    abc
    abcAAA

     

     

    Observe que não é inserido o caractere '\n' no fim da string lida pelo fgets, pois não foi criada uma linha entre abc e AAA neste segundo caso.

     

    fgets apenas lê caracteres da stream/arquivo que foi passada para ele, e nunca insere nada a mais do que está lá além do caractere nulo no fim da string (como todas as funções entrada da biblioteca padrão).

    • Curtir 1
  9. 10 horas atrás, arfneto disse:

    O tal '\n' newline não é digitado propriamente: é a tecla que sinaliza a fgets() o fim do processamento.

     

    É digitado sim, quando você aperta Enter o caractere '\n' é inserido na entrada e sinaliza o fim da entrada a ser lida pelo fgets().

     

    10 horas atrás, arfneto disse:

    Se quer ler até 30 letras (inclusive) deve usar 31 e não 32 como escreveu.

     

    Usar 31 é o suficiente para ler 30 caracteres, mas 32 é melhor por garantir que o '\n' também seja lido quando for digitado 30 caracteres (se houver um '\n'), e não fique sobrando o '\n' na entrada padrão podendo causar problemas para leituras de entradas seguintes.

     

     

    • Curtir 1
  10. Você precisa linkar a biblioteca curses colocando -lcurses ou -lncurses (se um não der tenta o outro) no comando de compilação.

     

    Fora isso também tem isto:

    - usa printf mas não incluiu stdio.h

    - a função main não retorna 0 quando é finalizada

    • Curtir 2
  11. Faça um loop para percorrer o vetor de char até chegar no fim da string (= quando encontrar o caractere '\0'), e nele cheque se o caractere na posição atual do vetor é um espaço em branco, e incremente um contador se for. (Não esqueça de iniciar para 0 o contador antes de começar percorrer o vetor.

     

    Para o programa quando esse contador for igual a 0 depois de percorrer o vetor (o que implica que não encontrou nenhum espaço em branco).

    • Curtir 1
  12. Mas se estamos falando de funções de entrada da linguagem C em termos das funções que oficialmente fazem parte do padrão da linguagem, o melhor seria consultar um site de documentação da linguagem como https://en.cppreference.com/w/c/io , ou então ler a norma ISO mais recente da linguagem diretamente.

     

    Estas são as funções que oficialmente devem estar disponíveis em qualquer compilador que seja conformante com as normas que definem a linguagem C.

     

    Outras funções que não sejam definidas na norma dependem do sistema operacional e/ou da disponibilidade de bibliotecas de terceiros. (Exemplos destas que foram mencionados aqui: read, funções da biblioteca Curses como getch, etc)

     

    • Curtir 2
    • Amei 1
  13. 1 hora atrás, arfneto disse:

    Não testei isso, rodei só agora. Mas parece não valer a pena ir tão longe. Não entendi o propósito dessa série, exceto como programa em C

     

    A série é uma maneira de calcular cosseno numericamente, se você fosse implementar a função cos() da biblioteca math.h usaria isto ou outro um método como esse. Claro ninguém precisa 'reinventar a roda' de fato, mas isso é um típico exercício para que está começando a estudar Cálculo/Analise Numérica, serve apenas justamente para aprender sobre esses tipos de considerações como sobre limite de máximo e mínimo de valores armazenáveis, velocidade de crescimento de valores, erros decorrentes dos cálculos efetuados, etc... Em fim, é para exercitar o raciocínio numérico.

     

    Na prática uma implementação não calcularia 19 iterações, a condição de parada da série provavelmente seria justamente verificar quando dois cossenos calculados consecutivamente são iguais ou tem uma diferença pequena o suficiente (margem de erro).

     

     

    E aqui implementação usando as equações que postei:

    #include <stdio.h>
    #include <math.h>
    
    int main()
    {
        double g, x, f, cosseno;
        
        printf("Digite o angulo em graus: ");
        scanf("%lf", &g);
        while (g > 360.0) g = g - 360.0;
        while (g < -360.0) g = g + 360.0;
        
        x = g*M_PI/180.0;
        
        f = 1.0;
        cosseno = 0.0;
        for (int n=1; n <= 20; n++){
            cosseno = cosseno + f;
            printf("\n=====%02d======\n"
                   "%2do. elemento = %.17E\n"
                   "cosseno(%.2lf) = %.17lf\n"
                   "diferenca = %.17E\n",
                   n, n, f, g, cosseno, fabs(cos(x)-cosseno));
            f = f * (-x*x)/((2.0*n)*(2.0*n - 1.0));
        }
        
        return 0;
    }

     

    Resultado:

    Digite o angulo em graus: 45
    
    =====01======
     1o. elemento = 1.00000000000000000E+00
    cosseno(45.00) = 1.00000000000000000
    diferenca = 2.92893218813452427E-01
    
    =====02======
     2o. elemento = -3.08425137534042437E-01
    cosseno(45.00) = 0.69157486246595756
    diferenca = 1.55319187205900100E-02
    
    =====03======
     3o. elemento = 1.58543442438154984E-02
    cosseno(45.00) = 0.70742920670977305
    diferenca = 3.22425523225478017E-04
    
    =====04======
     4o. elemento = -3.25991886927389960E-04
    cosseno(45.00) = 0.70710321482284566
    diferenca = 3.56636370191232288E-06
    
    =====05======
     5o. elemento = 3.59086044859150925E-06
    cosseno(45.00) = 0.70710680568329420
    diferenca = 2.44967466311862836E-08
    
    =====06======
     6o. elemento = -2.46113695049419920E-08
    cosseno(45.00) = 0.70710678107192471
    diferenca = 1.14622866753677499E-10
    
    =====07======
     7o. elemento = 1.15011591279740482E-10
    cosseno(45.00) = 0.70710678118693626
    diferenca = 3.88689080921267305E-13
    
    =====08======
     8o. elemento = -3.89807317125967434E-13
    cosseno(45.00) = 0.70710678118654646
    diferenca = 1.11022302462515654E-15
    
    =====09======
     9o. elemento = 1.00188646163627170E-15
    cosseno(45.00) = 0.70710678118654746
    diferenca = 1.11022302462515654E-16
    
    =====10======
    10o. elemento = -2.01965339688668116E-18
    cosseno(45.00) = 0.70710678118654746
    diferenca = 1.11022302462515654E-16
    
    =====11======
    11o. elemento = 3.27848356160984535E-21
    cosseno(45.00) = 0.70710678118654746
    diferenca = 1.11022302462515654E-16
    
    =====12======
    12o. elemento = -4.37734520949183473E-24
    cosseno(45.00) = 0.70710678118654746
    diferenca = 1.11022302462515654E-16
    
    =====13======
    13o. elemento = 4.89160615315761183E-27
    cosseno(45.00) = 0.70710678118654746
    diferenca = 1.11022302462515654E-16
    
    =====14======
    14o. elemento = -4.64213630938462923E-30
    cosseno(45.00) = 0.70710678118654746
    diferenca = 1.11022302462515654E-16
    
    =====15======
    15o. elemento = 3.78770245945430248E-33
    cosseno(45.00) = 0.70710678118654746
    diferenca = 1.11022302462515654E-16
    
    =====16======
    16o. elemento = -2.68556931493154947E-36
    cosseno(45.00) = 0.70710678118654746
    diferenca = 1.11022302462515654E-16
    
    =====17======
    17o. elemento = 1.66995380103824061E-39
    cosseno(45.00) = 0.70710678118654746
    diferenca = 1.11022302462515654E-16
    
    =====18======
    18o. elemento = -9.18102906881847163E-43
    cosseno(45.00) = 0.70710678118654746
    diferenca = 1.11022302462515654E-16
    
    =====19======
    19o. elemento = 4.49469865595933128E-46
    cosseno(45.00) = 0.70710678118654746
    diferenca = 1.11022302462515654E-16
    
    =====20======
    20o. elemento = -1.97194601868895092E-49
    cosseno(45.00) = 0.70710678118654746
    diferenca = 1.11022302462515654E-16

     

    • Curtir 1
  14. Como o @arfneto  mencionou há um limite máximo para valores de n! que podem ser calculados usando os tipos inteiros da linguagem C, pois n! cresce muito rapidamente estourando o valor máximo que pode ser armazenado numa variável inteira, mesmo para valores baixos de n.

     

    O que deve notar nesse tipo de exercício é que está dividindo por n! , logo não precisa calcular n!, pois pode calcular 1/(n!) que é algo que diminui ao invés de crescer...

     

    E observe que: image.png.94b72f09b27631169e8b8d9e2ecd498c.png

     

    Logo, podemos calcular o próximo valor sabendo o valor anterior da sequência de valores de 1/n! (do mesmo modo que funciona quando calcula n!), podendo usar um loop para calcular os valores.

     

     

     

    Seguindo essa lógica para o caso da fórmula: 

    image.png

    image.png

    O que deseja-se fazer é achar a forma dessa fórmula que possa calcular o valor atual utilizando o valor calculado anteriormente.

     

    Então, se chamarmos cada elemento da somatória acima de função f(x)n teremos:

     

    image.png.9a118b523f9fcc708c73498986e22ce1.png

     

     

    Usando isto podemos calcular cada elemento da somatória sabendo o elemento anterior, e não precisamos calcular image.png.57560ca0071738964d4758edfea489ff.png nem (2n)! pois podemos calcular cada elemento image.png.8f10b70b3ce8597496aa60ae12bb896e.png diretamente, evitando estouros de valores máximos de variáveis.

    • Curtir 1
  15. Eu resolvi assim:

     

    #include <stdio.h>
    
    int main()
    {
        int n, s;
        
        printf("Informe ate qual posicao deseja gerar a lista: ");
        scanf("%d", &n);    
        
        for (int i = 0; i < n; i++){
            s = i/3 + (i%3 == 0 ? 1 : 4);
            printf("%d ", s);
        }
        printf("\n");
    
        return 0;
    }

     

    Que é o mesmo que isso:

     

    #include <stdio.h>
    
    int main()
    {
        int n, s;
        
        printf("Informe ate qual posicao deseja gerar a lista: ");
        scanf("%d", &n);    
        
        for (int i = 0; i < n; i++){
            if (i % 3 == 0){
                s = i/3 + 1;
            }
            else {
                s = i/3 + 4;
            }
            printf("%d ", s);
        }
        printf("\n");
    
        return 0;
    }

     

    • Curtir 2
    • Amei 1
  16. Em 10/01/2021 às 18:56, Lucca Rodrigues disse:

    Depois de 7 meses, ainda ta valendo o feedback? 🤪

     

    Claro 👍

     

    Em 10/01/2021 às 18:56, Lucca Rodrigues disse:

    Aquele lbuffer é o que? Ou era pra ser linebuffer?

     

    Sim, estava errado, o correto é linebuffer.

    Eu estava certo de que eu já tinha editado e corrigido isso quando criei o tópico, talvez tenha perdido a edição quando o fórum foi atualizado?

    De qualquer maneira pedi para os moderadores editarem e corrigirem isso (já que o fórumnão permite mais que eu mesmo edite), e agora o código está correto.

     

    Em 10/01/2021 às 18:56, Lucca Rodrigues disse:

    Se uso o scanset negado sem incluir o '\n' num possível conjunto de caracteres, ao dar um Enter ele já encerra a leitura (e garante um '\n' na string como último caractere inserido), isso é proposital? Com scanset, se incluo o '\n' no conjunto e dou um Enter, ele encerra a leitura também.

     

    Não entendi muito bem a pergunta... Pode clarificar?

    Com %[^\n] ele tudo que não for o '\n', logo o '\n' é o único caractere que não é lido, logo fica sobrando o '\n' na entrada padrão stdin. Mas com %[\n] ele só vai identificar e ler o caractere nova linha '\n', e não vai ler nada mais.

    • Obrigado 1
  17. Em 17/12/2020 às 18:35, alkwelt disse:

    @isrnick como faço isso em uma recursão?

     

    #include <stdio.h>
    
    double ouro(double num){
        double num2 = 1 + 1/num;
        double erro = num2 - num;
        erro = erro < 0.0 ? -erro : erro;
        if (erro > 0.00000000001) {
            num2 = ouro(num2);
        }
        return num2;
    }
    
    int main()
    {
        printf("%.12lf\n", ouro(1.0));
    
        return 0;
    }

     

    • Curtir 2
    • Amei 2
  18. strcpy(inversa, palavra); //Desnecessário: Não há necessidade de fazer cópia exata da palavra

     

    Mude:

    tam = strlen(inversa);

    Para:

    tam = strlen(palavra);

     

     

    No ciclo for mude:

    printf("%c",inversa[x]);

    Para:

    inversa[x] = palavra[tam-x-1];

     

     

    E não esqueça de colocar o caractere nulo no fim da string (fora do ciclo for):

    inversa[tam] = '\0';

     

    • Amei 1

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

Ebook grátis: Aprenda a ler resistores e capacitores!

EBOOK GRÁTIS!

CLIQUE AQUI E BAIXE AGORA MESMO!