Ir ao conteúdo
  • Cadastre-se

arfneto

Membro Pleno
  • Total de itens

    3.775
  • Cadastrado em

  • Última visita

  • Qualificações

    0%

Tópicos solucionados

  1. O post de arfneto em Reproduzir imagem através de código foi marcado como solução   
    Isso eu te disse no primeiro momento...
     
    Quando tem pressa deve ser ainda mais metódico
     
    Esse era o plano 1, escrevendo em torno dos dados
     

     
     
     
     
     
     
     
     
     
     
    Como te mostrei pela manhã...
     
     
     
     
     
     
     
    Esse arquivo aí, com os 11 pontinhos. Primeiro lê e mostra, não adianta pensar em gravar se não ler p. nenhuma antes. E precisa ter um mínimo de segurança antes de gravar.
     
     
    É tudo simples. Mas se atropelar vai levar dias....
     
    image read_pts(char *name, int *nl, int *nc) { // -------------------------------------------- // Para Fazer // 1. abrir o arquivo texto 'nome' para leitura // 2. ler o número de linhas e colunas // 3. ler o número 'n' de pontos // 4. alocar o vetor 'img' com nl x nc // elementos // 5. preencher o vetor imagem com zeros // 6. ler as 'n' coordenadas (i, j) e preencher // a posição correspondente de img com 1. // --------------------------------------------  
    Você postou isso. Então faça isso. Com controle. Para dar certo da primeira vez
     
    // 1. FILE *f = fopen(name, "r"); if (f == NULL) return NULL;  
    não existe modo "rt".
     
    // 2. ler o número de linhas e colunas // 3. ler o número 'n' de pontos  
    Pois é: 
     
    // 2,3. int pt = 0; // total de pixels '1' int res = fscanf(f, "%d %d %d", nl, nc, &pt); if (res != 3) return NULL; // não leu direito, cancela  
    Não se preocupe com mensagens de erro e sim com o mais comum: ler e pronto. E use um printf() depois para ficar mais seguro de que está lendo o que acha que está lendo.
     
    E TESTE a p. do resultado de fscanf().
     

    E entenda que se não ler um dos 3 o programa já era de qualquer maneira. Você quer ler o que, no caso do J? 6, 10 e 11. Está lá no arquivo. Então coloca um printf() logo de cara. Vai ver os números certinhos e você apaga. Ou vai uns números enormes ou um crash e você corrige, MAS não segue em frente ou nunca vai terminar.
     
     
    // 4. alocar o vetor 'img' com nl x nc // elementos  
    Não precisa declarar antes e ficar esperando. É uma chance a mais de errar algo. Escreva o simples
     
    // 4. image img = alloc_memo(*nl, *nc);  
      // 5. preencher o vetor imagem com zeros  
    // 5. memset((void *)img, 0, sizeof(int) * (*nl) * (*nc)); // zera tudo  
    Basta ver o que alocou na tal rotina da linha de cima, certo? 
     
    image alloc_memo(int nl, int nc) { return (image)malloc(nl * nc * sizeof(int)); }
    Está lá no código que recebeu...
     
    // 6. ler as 'n' coordenadas (i, j) e preencher // a posição correspondente de img com 1. // --------------------------------------------  
    Pois é. O que vai ler aqui, no caso do J? Os 11 pontos. Acabou de ler esse valor. É só um loop
     
    0 4 1 4 2 4 3 4 4 4 5 4 6 0 6 4 7 1 7 2 7 3  
    Vão colocar 1 em 11 pontos e depois mostrar os asteriscos no loop que te mostrei antes... E tanto faz digitar dois por linha ou 4 ou tudo numa linha só: fscanf() só entende uma coisa: espaço em branco. Pula tudo igualzinho, espaços, tabs, newlines, tanto faz. Só não pode ter letrinhas. Por isso é melhor aqui que fgets().
     
    // 6. for (int n = 0, i = 0, j = 0; n < pt; n += 1) { // para os 'pt' pontos if (2 != fscanf(f, "%d %d", &i, &j)) { // deu erro: free(img); return NULL; } *(img + (i * *nc) + j) = 1; // marca o pixel }  
    Como te disse, ler todos de 2 em dois é mais fácil. E não é esperto deixar variáveis vivas pelo programa todo se só vai usar aqui, então pode declarar i e j no próprio loop. Se der erro deixa pra lá, retorna NULL. O programa não testa nada mesmo, como pode ver em main().
     
    E copiar os caras é a conta simples que está no enunciado: seus "pixels" estão  obviamente um depois do outro em img, como sabe. Foi o que alocou. 
     
    Então o pixel (i, j) está em 
     
    *(img + (i * *nc) + j) = 1; // marca o pixel  
    E deve estar tudo certo.
     
    Mas para ficar mais seguro... Como te falei da primeira vez:
     
    ////////////////////////////////////////////////////////////////// // mostra o que leu int col = 6; pt = *nc * *nl; for (int i = 0; i < pt; i += 1) { if ( *(img + i) == 1 ) printf("* "); else printf(" "); if (++col % 6 == 0) printf("\n"); } printf("\n"); //////////////////////////////////////////////////////////////////  
    mostra na tela. De 6 em 6. Claro, porque J é 6x10 está no arquivo. A gene só quer saber se está indo no caminho certo. O tal programa depois vai mostrar a imagem de qualquer maneira, ou você pode usar uma imagem simples com uns 1o pontos e contar um por um já que esse modo P1 é texto e você sabe muito bem, porque está no enunciado...
     

     
    E então ao ver isso na tela 
     
    * * * * * * * * * * *  
    já dá uma sensação de tranquilidade.
     
    Estou mostrando tudo isso porque pode ajudar outros a ver que --- minha opinião --- sempre é mais fácil escrever em torno dos dados e seguir passo a passo. Em geral dá certo da primeira vez, porque esses problemas são simples e buscam mostrar um ou outro conceito por vez...
     
    Eis a função toda:
     
    image read_pts(char *name, int *nl, int *nc) { // -------------------------------------------- // Para Fazer // 1. abrir o arquivo texto 'nome' para leitura // 2. ler o número de linhas e colunas // 3. ler o número 'n' de pontos // 4. alocar o vetor 'img' com nl x nc // elementos // 5. preencher o vetor imagem com zeros // 6. ler as 'n' coordenadas (i, j) e preencher // a posição correspondente de img com 1. // -------------------------------------------- // 1. FILE *f = fopen(name, "r"); if (f == NULL) return NULL; // 2,3. int pt = 0; // total de pixels '1' int res = fscanf(f, "%d %d %d", nl, nc, &pt); if (res != 3) return NULL; // não leu direito, cancela // 4. image img = alloc_memo(*nl, *nc); // 5. memset((void *)img, 0, sizeof(int) * (*nl) * (*nc)); // zera tudo // 6. for (int n = 0, i = 0, j = 0; n < pt; n += 1) { // para os 'pt' pontos if (2 != fscanf(f, "%d %d", &i, &j)) { // deu erro: free(img); return NULL; } *(img + (i * *nc) + j) = 1; // marca o pixel } ////////////////////////////////////////////////////////////////// // mostra o que leu int col = 6; pt = *nc * *nl; for (int i = 0; i < pt; i += 1) { if ( *(img + i) == 1 ) printf("* "); else printf(" "); if (++col % 6 == 0) printf("\n"); } printf("\n"); ////////////////////////////////////////////////////////////////// fclose(f); return img; }  
    Pode estar errado, mas pode muito bem estar certo. Da primeira vez em que rodar.
     
     
  2. O post de arfneto em Como concatenar uma string sem usar biblioteca especializada? foi marcado como solução   
    São 2 linhas na prática, mas veja assim
     
    1 char* strcat ( char* dest, const char* nova ) 2 { char* p = dest; // vai retornar dest 3 while ( *p != 0 ) p+=1; // avanca 4 do { *p++ = *nova++; } while ( *nova != 0 );// copia o resto 5 return dest; // retorna o mesmo 6 };  
    Está claro que strcat() retorna dest, certo?
     
    E porque isso? Para poder usar numa expressão., como
     
    Do exemplo:
     
    char* p = strcat( origem, resto); printf( "A+B = \"%s\"\n", p );  
    podia ser
     
    printf( "A+B = \"%s\"\n", strcat( origem, resto) );  
    Então é claro que o return vai ser
     
    return dest;
    a linha 5. E então tem que salvar esse valor ou não vai ter o que retornar. Por isso a linha 2
     
    char* p = dest;  
    Porque assim usa p em vez de dest para poder retornar o cara inalterado.... 
     
    Uma string em C não é uma coisa que exista: é uma convenção: uma série de coisas terminada por um zero.
     
    Então pra juntar duas, nesse caso para colocar uma segunda no fim da primeira, tem que fazer duas coisas
    achar o fim da primeira copiar até achar o fim da segunda É só isso.
     
    Como no final da string concatenada vai ter um 0 porque é uma string afinal, e se sabe que no final da segunda já tem um zero porque também é uma string, isso resolve a escolha dos loops:
    o while() testa antes, porque precisa parar ao achar o zero. O do() testa depois porque precisa incluir o 0, mesmo que a segunda string seja vazia, porque tem que ter um zero no fim. A linha 3 avança p, o ponteiro para a letrinha na string de destino, até encontrar um 0. Mas não passa do 0, porque é de onde começa a copiar a outra  : 
     
    O asterisco é um operador e *p significa o conteúdo de seja lá para onde p aponte. Como p é char* será uma letra.
     
    3 while ( *p != 0 ) p+=1; // avanca  
    A linha 4 copia as letras da string nova, até e incluindo o 0 para terminar a string de saída sem ficar fazendo testes.
     
    4 do { *p++ = *nova++; } while ( *nova != 0 );// copia o resto  
    quando o while encontra *nova == 0 e sai já  copiou o 0 e a string de saída está completa. Os ++ avançam os ponteiros, e como vem DEPOIS da variável ele copia primeiro e soma depois.
     
    E assim essa rotina deve ser bem mais rápida que a strcat() original, que usa memcpy() e strlen().
  3. O post de arfneto em Como concatenar uma string sem usar biblioteca especializada? foi marcado como solução   
    São 2 linhas na prática, mas veja assim
     
    1 char* strcat ( char* dest, const char* nova ) 2 { char* p = dest; // vai retornar dest 3 while ( *p != 0 ) p+=1; // avanca 4 do { *p++ = *nova++; } while ( *nova != 0 );// copia o resto 5 return dest; // retorna o mesmo 6 };  
    Está claro que strcat() retorna dest, certo?
     
    E porque isso? Para poder usar numa expressão., como
     
    Do exemplo:
     
    char* p = strcat( origem, resto); printf( "A+B = \"%s\"\n", p );  
    podia ser
     
    printf( "A+B = \"%s\"\n", strcat( origem, resto) );  
    Então é claro que o return vai ser
     
    return dest;
    a linha 5. E então tem que salvar esse valor ou não vai ter o que retornar. Por isso a linha 2
     
    char* p = dest;  
    Porque assim usa p em vez de dest para poder retornar o cara inalterado.... 
     
    Uma string em C não é uma coisa que exista: é uma convenção: uma série de coisas terminada por um zero.
     
    Então pra juntar duas, nesse caso para colocar uma segunda no fim da primeira, tem que fazer duas coisas
    achar o fim da primeira copiar até achar o fim da segunda É só isso.
     
    Como no final da string concatenada vai ter um 0 porque é uma string afinal, e se sabe que no final da segunda já tem um zero porque também é uma string, isso resolve a escolha dos loops:
    o while() testa antes, porque precisa parar ao achar o zero. O do() testa depois porque precisa incluir o 0, mesmo que a segunda string seja vazia, porque tem que ter um zero no fim. A linha 3 avança p, o ponteiro para a letrinha na string de destino, até encontrar um 0. Mas não passa do 0, porque é de onde começa a copiar a outra  : 
     
    O asterisco é um operador e *p significa o conteúdo de seja lá para onde p aponte. Como p é char* será uma letra.
     
    3 while ( *p != 0 ) p+=1; // avanca  
    A linha 4 copia as letras da string nova, até e incluindo o 0 para terminar a string de saída sem ficar fazendo testes.
     
    4 do { *p++ = *nova++; } while ( *nova != 0 );// copia o resto  
    quando o while encontra *nova == 0 e sai já  copiou o 0 e a string de saída está completa. Os ++ avançam os ponteiros, e como vem DEPOIS da variável ele copia primeiro e soma depois.
     
    E assim essa rotina deve ser bem mais rápida que a strcat() original, que usa memcpy() e strlen().
  4. O post de arfneto em Como concatenar uma string sem usar biblioteca especializada? foi marcado como solução   
    São 2 linhas na prática, mas veja assim
     
    1 char* strcat ( char* dest, const char* nova ) 2 { char* p = dest; // vai retornar dest 3 while ( *p != 0 ) p+=1; // avanca 4 do { *p++ = *nova++; } while ( *nova != 0 );// copia o resto 5 return dest; // retorna o mesmo 6 };  
    Está claro que strcat() retorna dest, certo?
     
    E porque isso? Para poder usar numa expressão., como
     
    Do exemplo:
     
    char* p = strcat( origem, resto); printf( "A+B = \"%s\"\n", p );  
    podia ser
     
    printf( "A+B = \"%s\"\n", strcat( origem, resto) );  
    Então é claro que o return vai ser
     
    return dest;
    a linha 5. E então tem que salvar esse valor ou não vai ter o que retornar. Por isso a linha 2
     
    char* p = dest;  
    Porque assim usa p em vez de dest para poder retornar o cara inalterado.... 
     
    Uma string em C não é uma coisa que exista: é uma convenção: uma série de coisas terminada por um zero.
     
    Então pra juntar duas, nesse caso para colocar uma segunda no fim da primeira, tem que fazer duas coisas
    achar o fim da primeira copiar até achar o fim da segunda É só isso.
     
    Como no final da string concatenada vai ter um 0 porque é uma string afinal, e se sabe que no final da segunda já tem um zero porque também é uma string, isso resolve a escolha dos loops:
    o while() testa antes, porque precisa parar ao achar o zero. O do() testa depois porque precisa incluir o 0, mesmo que a segunda string seja vazia, porque tem que ter um zero no fim. A linha 3 avança p, o ponteiro para a letrinha na string de destino, até encontrar um 0. Mas não passa do 0, porque é de onde começa a copiar a outra  : 
     
    O asterisco é um operador e *p significa o conteúdo de seja lá para onde p aponte. Como p é char* será uma letra.
     
    3 while ( *p != 0 ) p+=1; // avanca  
    A linha 4 copia as letras da string nova, até e incluindo o 0 para terminar a string de saída sem ficar fazendo testes.
     
    4 do { *p++ = *nova++; } while ( *nova != 0 );// copia o resto  
    quando o while encontra *nova == 0 e sai já  copiou o 0 e a string de saída está completa. Os ++ avançam os ponteiros, e como vem DEPOIS da variável ele copia primeiro e soma depois.
     
    E assim essa rotina deve ser bem mais rápida que a strcat() original, que usa memcpy() e strlen().
  5. O post de arfneto em funções e matrizes ISBN foi marcado como solução   
    Eu não entendo o que está tentando fazer.
     
    Essa tabela aí fui eu que escrevi. O objetivo disso era calcular quando tempo cada uma dessas funções que eu escrevi, e mais essa outro que o usuário @Midoriescreveu, levam par calcular um certo n'mero de DV. E mostrar o resultado, uma tabela. Na posição 1 da tabela está o tempo com 0, que vai ser preenchido com os tempos calculados. E o  valor será impresso foi no tópico #12 e a saída do programa era essa:
     
    [Comparando as 4 funcoes] 2000 (*1.000) testes com valores aleatorios, mesma serie Rodando a versão oficial... ok! Rodando as outras versões. versão oficial = 1.0X 0.91X para versão pesos 1..9 1.10X para versão aprovada pelo professor :) 3.64X para versão @Midori  
    O programa não lê nada. Apenas roda as 4 funções para uma mesma série de 2 milhões de ISBN e mede o tempo. Leia o tópico #12.  Era para testar 4 funções de cálculo.
     
    Nada tem a ver com seu problema original, que é ler uns números de ISBN, e calcular o DV usando uma função, que pode por exemplo ser uma das que eu escrevi ou essa quarta aí. 
     
    Eu expliquei poruqe eu estaa escrevendo aquilo.
     
    Assim me vem a pergunta:
     
    Porque está usando essa estrutura no meio disso? 
     
    E onde está o resto do código? E porque mudou de IDE no meio disso tudo?
     
    No tópico #5, https://www.clubedohardware.com.br/topic/1561085-funções-e-matrizes-isbn/?tab=comments#comment-8259805 eu te mostrei esse programa, de onde tirou a função que está usando
     
     
    /* * https://www.clubedohardware.com.br/ topic/1561085-fun%C3%A7%C3%B5es-e-matrizes-isbn/ ?tab=comments#comment-8259599 ARFNeto '21 */ #include <stdio.h> #include <stdlib.h> #include <string.h> char isbn_dv(char[9]); // a funcao char isbn_dv_oficial(char[9]); // com os pesos oficiais char isbn_dv_professor(char[9]); // como seu professor gosta int main(int argc, char** argv) { const char padrão[] = "isbn.txt"; char arquivo[30] = {0}; char linha[80]; if (argc > 1) // veio algo entao e o nome do arquivo strcpy(arquivo, argv[1]); else strcpy(arquivo, padrão); printf("Arquivo de entrada: \"%s\"\n", arquivo); FILE* entrada = fopen(arquivo, "r"); if (entrada == NULL) return -1; printf("Aberto \"%s\"\n", arquivo); char* p = fgets(linha, sizeof linha, entrada); while (p != NULL) { *(p+9) = 0; printf("%s-%c\t%s-%c\t%s-%c\n", p, isbn_dv( &linha[0]), p, isbn_dv_oficial( &linha[0]), p, isbn_dv_professor(&linha[0]) ); p = fgets(linha, sizeof linha, entrada); } fclose(entrada); return 0; } char isbn_dv(char isbn[9]) { int soma = 0; for (int d = 1; d <= 9; d += 1) soma += (isbn[d - 1] - '0') * d; int dv = soma % 11; if (dv == 10) return 'X'; return '0' + dv; }; char isbn_dv_oficial(char isbn[9]) { int soma = 0; for (int d = 10; d >= 2; d -= 1) soma += (isbn[10 - d] - '0') * d; int dv = 11 - (soma % 11); if (dv == 11) return '0'; if (dv == 10) return 'X'; return '0' + dv; }; char isbn_dv_professor(char isbn[9]) { int s1 = 0; int s2 = 0; for (int d = 0; d < 9; d += 1) s1 += isbn[d] - '0', s2 += s1; int dv = 11 - ((s1+s2) % 11); if (dv == 11) return '0'; if (dv == 10) return 'X'; return '0' + dv; };  
    É um programa completo. Te mostrei o arquivo de saída e o de entrada...
     
    013162959X 0387901442 3540901442 0201179288  
    E a saída
     
    Clube> ./or-0903 Arquivo de entrada: "isbn.txt" Aberto "isbn.txt" 013162959-X 013162959-X 013162959-X 038790144-2 038790144-2 038790144-2 354090144-2 354090144-2 354090144-2 020117928-8 020117928-8 020117928-8 Clube>  
    Onde cada coluna é o resultado de uma função.
     
    O que falta aqui para o seu caso?
     
    Tirar duas funções e colocar o lance do loop. Eu já te mostrei umas 4 vezes maneiras de fazer isso, e te mostrei em vários casos onde você está errando.
     
    Já sabe o que mudar no loop. Eu te mostrei acima. Já tem a função. Eu escrevi 3. 
     
    Sequer precisa de um IDE para um programa de 50 linhas. E que já está pronto. Use os exemplos.
     
    Juntando o que eu te disse o dia todo
     
    char isbn_dv(char[9]); // a funcao int main(int argc, char** argv) { char arquivo[30] = {0}; char linha[80]; FILE* entrada = stdin; if (argc > 1) // veio algo entao e o nome do arquivo { strcpy(arquivo, argv[1]); printf("Arquivo de entrada: \"%s\"\n", arquivo); entrada = fopen(arquivo, "r"); if (entrada == NULL) return -1; printf("Aberto \"%s\"\n", arquivo); }; char final[] = "000000000"; linha[9] = 0; // tem que ser uma string afinal char* p = fgets(linha, sizeof linha, entrada); while ( (p != NULL) && (strcmp(linha,final) != 0) ) { linha[9] = 0; printf("%s-%c\n", p, isbn_dv(&linha[0])); p = fgets(linha, sizeof linha, entrada); linha[9] = 0; } fclose(entrada); return 0; } // fim  
    É só isso.  E tem a vantagem de funcionar com qualquer arquivo na linha de comando ou lendo os dados do teclado, como seu professor folclórico recomenda.  mesmo programa.
     
    Veja (em Windows)
     
    CH> isbn.txt | outro-0905 013162959-X 038790144-2 CH> outro-0905 < isbn.txt 013162959-X 038790144-2 CH>outro-0905 isbn.txt Arquivo de entrada: "isbn.txt" Aberto "isbn.txt" 013162959-X 038790144-2 CH> type isbn.txt 013162959X 0387901442 0000000000 3540901442 0201179288 CH>  
  6. O post de arfneto em Programa que pede nome e exibe na tela foi marcado como solução   
    Leia o manual, sempre. 
     
    Basta parar o cursor sobre a função e ficar olhando....
     

     
    Pois é. E em português se o idioma estiver instalado no Visual Studio
     
    E se tem mais duvidas tem o Search Online que em geral vai direto para o manual...
     
    Em português na documentação nesse caso
     
    Mas apenas o que está na tela deveria ser suficiente: scanf_s() tem o que scanf() deveria ter desde o início: um argumento a mais para cada campo, especificando o tamanho. Pela mesma razão gets() foi praticamente banida em função de fgets() 20 anos atrás. Mas por uma questão política a Microsoft nunca conseguiu por isso no padrão.
     
    E o que está escrito lá? C6064: Falta argumento inteiro para scanf_s(), correspondente ao especificador 2, no popular o segundo.
     

     
    Seguindo o manual e o que está escrito na mensagem de erro:
     
    Note que ao seguir a documentação e colocar o tamanho do campo a mensagem de erro desaparece e o programa roda.
     
     
     
     
    Você pode também usar a implementação original de scanf() se precisa por exemplo compilar também no MAC ou no Linux e não quer manter dois programas ou um #define chato
     
    apenas configure a opção _CRT_SECURE_NO_WARNINGS para seu projeto.
     
    Como eu sei isso? Basta compilar um programa que chama scanf() no Visual Studio e ficar olhando na tela...
     
    Usando
     
    scanf("%s", nome);  
    e compilando o programa vem 
     
    or-0831.c(10): warning C4996: 'scanf': This function or variable may be unsafe. Consider using scanf_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.  
    Pois é. Se usa em português a mensagem vem em português. C4996 e o que diz? está função pode ser insegura. Considere usar scanf_s como opção. Para desabilitar obsolescência use _CRT_SECURE_NO_WARNING. Para detalhes veja a ajuda online.
     
    Sua opção foi por usar scanf_s() mas você não foi ver a diferença. Só trocou o nome... ???
     
    E o outro caso?  Apenas use nas opções do projeto o que está escrito lá na mensagem, sem stress.
     
    E onde?  Mas propriedades do projeto, claro. Vá em C/C++, definições para o pre-processador e marque exatamente o que está escrito na mensagem e que, lógico, você pode copiar com control-C...

     

     
    Ou use um #define 
     
    #define _CRT_SECURE_NO_WARNINGS  
    Em cada código em que chama alguma dessas funções inseguras, exceto gets() que não vai mesmo rolar.
     
    E sobre sua chamada a scanf() scanf_s()
     
    char nome[20]; printf("Diga seu nome\n"); scanf_s("%s", &nome);  
    Entenda: scanf() não aloca memória. Você precisa fornecer o endereço para a função transferir cada valor lido.
     
    No seu caso só lê um, então precisa de um endereço para onde transferir o que ler com o especificador "%s". Mas no caso de nome, nome é char[] e assim nome sozinho é o endereço de início do vetor, já é um ponteiro para uma variável estática, alocada ali mesmo duas linhas acima, e assim você não usa o operador &. nome já é um ponteiro.
     
    TL;DR:  use 
     
    scanf_s("%s", nome, 20 );  
    Não entendo como um curso que sugere o uso de Visual Studio não explica no mínimo isso. Acho que devia se queixar com seu instrutor.  
     
    Um exemplo mais longo  
     
    #include <locale.h> #include <stdio.h> int main() { setlocale(LC_ALL, "portuguese"); char nome[20]; unsigned i = 42; char c; printf("Diga seu nome, letra e numero "); scanf_s("%s %c %u", nome, 20, &c, 1, &i ); printf("nome \"%s\", letra '%c' e numero %d", nome, c, i ); return 0; }  
    mostra
     
    Diga seu nome, letra e numero Clube X 42 nome "Clube", letra 'X' e numero 42  
    atente para as diferenças...
     
     
     
     
     
     

  7. O post de arfneto em como retornar um vetor para main foi marcado como solução   
    int contadorL(char string[100]);  
     
    Está faltando o vetor, então você coloca o vetor... 
     
    int cLetras( char* string[], int vetor[] );  
    O enunciado é ruim e o problema não está bem formulado. Isso dá margem a alguma interpretação e pode facilitar as coisas.
     
    "O tamanho do vetor deve ser o número de palavras da string"
     
    Isso não faz sentido para a função, porque ela só vai receber o endereço de início, é um programa em C. Tanto faz se o vetor tem 50 ou 50.000 palavras. Como não sabe também quantas palavras tem na string também não pode declarar o vetor fixo. Claro que pode ter no máximo 50 strings nesse caso, mas é o que temos.
     
    Então acho que o melhor que pode fazer é passar o tamanho e o vetor, declarando
     
    int cLetras( char* string[], int vetor[], int tamanho ); // ou o equivalente int cLetras( char* string[], int* vetor, int tamanho );  
    Claro que no mundo real essa conta seria feita ao mesmo tempo, já que pouco sentido faz varrer duas vezes a string onde estão as palavras e as letras  
     
  8. O post de arfneto em Somar os multiplos, funcao c foi marcado como solução   
    int somaMulti(int t[], int size, int limite) { int soma = 0; scanf("%d", &size); for(int i = 0; i < size; ++i){ scanf("%d", t[i]); scanf("%d", &limite); for(int j = 1 ; j <= limite-1 ; j++) { if(v[size]%limite == 0 || v[size+1]%limite == 0) { soma += j; } }  
    Acho que não entendeu ainda o propósito de se escrever uma função e passar argumentos para ela.
    Se fosse para ler o vetor de novo toda vez que chamasse a função qual seria a razão de existir o argumento?
     
    Acho que já te disse isso antes, mas pergunto de novo: porque não testa o retorno de scanf()? Qual o sentido de seguir com o programa se não ler nada?
     
    A função vai calcular a soma dos múltiplos em um vetor que é fornecido, t[]. Essa é a razão de existir a função: ela soma os múltiplos para qualquer vetor.
     
    O que está fazendo com a soma? Não deveria retornar a soma para main()? 
     
     
    Notou que a função que escreveu tem um nome e a função de chama tem outro? 
     
    E o vetor mudou de nome de t[] para v[]?
     
    if(v[size]%limite == 0 || v[size+1]%limite == 0) { soma += j;  
    Não entendi essa conta. limite é o maior valor possível. Não é um fator. Os fatores são os elementos do vetor. E podem ser muitos, não apenas 2 como no seu exemplo.
     
    E não pode usar OR ou vai somar mais de uma vez se for múltiplo de mais de um elemento do vetor.
     
    Escreva isso em um papel antes de programar
     
    Pense no simples: todo numero é múltiplo de 1, certo?
     
    Isso quer dizer que se tiver 1 no vetor então o resultado será a soma de todos os números até o limite, como está escrito no enunciado. E isso é algo conhecido desde o ensino fundamental. Pode usar isso para testar seu programa
     
     
  9. O post de arfneto em Laço DO WHILE + SWITCH não funciona corretamente foi marcado como solução   
    E não é que é verdade? 
     
     
    Acabou de declarar um ponteiro para Lista. Não tem nada lá. Veja:
     
    Lista* lista_encadeada; int opcao; int num; /// lista_encadeada->inserir_inicio(num); /// lista_encadeada->mostrar(); do { cout << "1. Inserir numero no inicio da lista." << endl; cout << "2. Inserir numero no fim da lista." << endl; cout << "3. Imprimir lista completa." << endl; cout << "0. Sair." << endl; cout << "Opcao: "; cin >> opcao; switch (opcao) { case 1: cout << "Digite um numero: "; cin >> num; lista_encadeada->inserir_inicio(num); cout << "Numero inserido no inicio da lista" << endl; break;  
    Porque está usando ponteiros e essas funções todas? Está programando em C++. Não deve usar isso. Usaria em C, talvez. C++ tem listas que pode usar direto, basta declarar. Talvez pudesse dar uma olhada nos métodos de list e copiar.
     
    De todo modo, está muito errado escrever desse modo.
     
    O mais importante:
     
    é raro precisar de ponteiros assim em C++.
      TODAS essas funções que escreveu são relativas à Lista. São métodos da classe. Esse é todo o sentido de usar uma linguagem dessas: tudo fica MUITO mais fácil. Use como tal.
      Use arquivos separados para as classes/ Há uma razão para todo mundo usar isso e o próprio IDE criar assim. Se fizer como fez só vai ter mais trabalho
      Sua lista não tem um campo de tamanho? Porque?  
    Entenda que se tem tantas funções devia ter uma também para o menu, que retornasse a opção...
     
     
     
     
    int obterValor() // obtém o valor { return v; } No* obterProx() // obtém o próximo No  
    Não use comentários com acentos. Recomendo evitar esse tipo de comentário óbvio: dá pra imaginar o que faz obterValor(). Comente sobe o que está fazendo e como está fazendo.
    obterProx() e SetProx() não são funções do nó e sim da lista... 
  10. O post de arfneto em Laço DO WHILE + SWITCH não funciona corretamente foi marcado como solução   
    E não é que é verdade? 
     
     
    Acabou de declarar um ponteiro para Lista. Não tem nada lá. Veja:
     
    Lista* lista_encadeada; int opcao; int num; /// lista_encadeada->inserir_inicio(num); /// lista_encadeada->mostrar(); do { cout << "1. Inserir numero no inicio da lista." << endl; cout << "2. Inserir numero no fim da lista." << endl; cout << "3. Imprimir lista completa." << endl; cout << "0. Sair." << endl; cout << "Opcao: "; cin >> opcao; switch (opcao) { case 1: cout << "Digite um numero: "; cin >> num; lista_encadeada->inserir_inicio(num); cout << "Numero inserido no inicio da lista" << endl; break;  
    Porque está usando ponteiros e essas funções todas? Está programando em C++. Não deve usar isso. Usaria em C, talvez. C++ tem listas que pode usar direto, basta declarar. Talvez pudesse dar uma olhada nos métodos de list e copiar.
     
    De todo modo, está muito errado escrever desse modo.
     
    O mais importante:
     
    é raro precisar de ponteiros assim em C++.
      TODAS essas funções que escreveu são relativas à Lista. São métodos da classe. Esse é todo o sentido de usar uma linguagem dessas: tudo fica MUITO mais fácil. Use como tal.
      Use arquivos separados para as classes/ Há uma razão para todo mundo usar isso e o próprio IDE criar assim. Se fizer como fez só vai ter mais trabalho
      Sua lista não tem um campo de tamanho? Porque?  
    Entenda que se tem tantas funções devia ter uma também para o menu, que retornasse a opção...
     
     
     
     
    int obterValor() // obtém o valor { return v; } No* obterProx() // obtém o próximo No  
    Não use comentários com acentos. Recomendo evitar esse tipo de comentário óbvio: dá pra imaginar o que faz obterValor(). Comente sobe o que está fazendo e como está fazendo.
    obterProx() e SetProx() não são funções do nó e sim da lista... 
  11. O post de arfneto em Laço DO WHILE + SWITCH não funciona corretamente foi marcado como solução   
    E não é que é verdade? 
     
     
    Acabou de declarar um ponteiro para Lista. Não tem nada lá. Veja:
     
    Lista* lista_encadeada; int opcao; int num; /// lista_encadeada->inserir_inicio(num); /// lista_encadeada->mostrar(); do { cout << "1. Inserir numero no inicio da lista." << endl; cout << "2. Inserir numero no fim da lista." << endl; cout << "3. Imprimir lista completa." << endl; cout << "0. Sair." << endl; cout << "Opcao: "; cin >> opcao; switch (opcao) { case 1: cout << "Digite um numero: "; cin >> num; lista_encadeada->inserir_inicio(num); cout << "Numero inserido no inicio da lista" << endl; break;  
    Porque está usando ponteiros e essas funções todas? Está programando em C++. Não deve usar isso. Usaria em C, talvez. C++ tem listas que pode usar direto, basta declarar. Talvez pudesse dar uma olhada nos métodos de list e copiar.
     
    De todo modo, está muito errado escrever desse modo.
     
    O mais importante:
     
    é raro precisar de ponteiros assim em C++.
      TODAS essas funções que escreveu são relativas à Lista. São métodos da classe. Esse é todo o sentido de usar uma linguagem dessas: tudo fica MUITO mais fácil. Use como tal.
      Use arquivos separados para as classes/ Há uma razão para todo mundo usar isso e o próprio IDE criar assim. Se fizer como fez só vai ter mais trabalho
      Sua lista não tem um campo de tamanho? Porque?  
    Entenda que se tem tantas funções devia ter uma também para o menu, que retornasse a opção...
     
     
     
     
    int obterValor() // obtém o valor { return v; } No* obterProx() // obtém o próximo No  
    Não use comentários com acentos. Recomendo evitar esse tipo de comentário óbvio: dá pra imaginar o que faz obterValor(). Comente sobe o que está fazendo e como está fazendo.
    obterProx() e SetProx() não são funções do nó e sim da lista... 
  12. O post de arfneto em fopen: leitura de txt salvo em iso-8859-1 foi marcado como solução   
    Nada existe em um arquivo txt que fale sobre língua ou forma de escrever. Não há como escrever um encode/decode a menos que seja para você mesmo para os seus próprios arquivos a partir do momento em que escreveu isso.
     

    Não funciona assim. A menos que insira algo nos seus arquivos para marcar isso e estará reinventando a roda, ou criando uma só para você usar
     
    O encoding não vai no texto. No máximo o BOM. 2 bytes. 
     
    Exemplo

    Um arquivo de 1 linha
     
    Assim é. O conteúdo é uma coleção de bytes  
    Em um computador comum novo...
     

     
    Onde pode ver o BOM no início do arquivo. No Linux e no MacOS é igual.
     
    od -x é o que se chama dump na terminologia Unix, dos anos 70 --- o o é de octal, por causa das máquinas da DEC daquela época. E a seguir está o conteúdo total desse arquivo, em hexadecimal.
     
    Dependendo do locale o type, equivalente ao cat do Unix, vai mostrar o conteúdo de um certo modo. No Windows tem esse conceito de codepage, anos 80. 1252 é a página para caracteres latinos, e é diferente da padrão 850. E o texto é interpretado de outro modo. E se usar a codepage 65001, Unicode, anos 90 criado pelo criador do Unix junto com Robert Pike Pike, o criador do Go.
     
    Entenda que dentro do arquivo não tem nada exceto o byte order mark --- porque Unicode pode ter até 4 bytes e little/big endian faz diferença --- se entende o que é isso.
     
    Isso é o que estou tentando te explicar. Dentro do texto não há lugar para isso (encoding). Mesmo o BOM pode e vai dar problemas em programas de iniciantes --- não sei se é seu caso --- porque pode ser lido como conteúdo já que está mesmo lá.
     
    Em XML ou HTML tem um header, um namespace, um cabeçalho, alternativas para colocar essa definição.
  13. O post de arfneto em Arquivo txt apagando sem intenção ao iniciar compilação! <CODE> foi marcado como solução   
    Dev-C++ é um IDE, um ambiente de desenvolvimento escrito em torno de um editor de texto.
     
    Nem compila programas, mas a partir do código do programa digitado no editor ele chama o compilador para compilar o programa e o linker para gerar o executável. 
     
    Nenhum desses passos vai apagar arquivos txt
     
    Logo no início do programa você abre os arquivos para gravação, e assim claro que o conteúdo anterior vai sumir...
     
    Não escreva um programa interativo antes dele estar pronto em termos de funções. Só vai perder muito tempo.
     
    Não precisa de um arquivo para cada coisa. Basta um. Abra para leitura. Depois gere outro na saída com o que mudou e salve. E depois mude o nome. É o comum.
     
    Sobre o formato
     
    Vário IDE formatam arquivos fonte, e tem muitos formatadores, inclusive online, que pode usar. Abaixo, seu programa formatado por um desses, clang-format, a partir do Visual Studio.
     
    #include <locale.h> #include <stdio.h> #include <stdlib.h> #include <cstring> int numero; int main(int argc, char* argv[]) { setlocale(LC_ALL, "Portuguese"); FILE* p_au; // variável ponteiro para o arquivo FILE* p_as; FILE* p_aus; // FILE char usuario_c[20]; char c_usuario[20]; char senha_c[20]; char c_senha[20]; p_au = fopen( "email_cadastro.txt", "w"); // abrindo o arquivo com tipo de abertura w p_as = fopen("senha_cadastro.txt", "w"); p_aus = fopen("email_cadastro.txt", "r"); int usuario, senha, usuario_i, i_usuario, senha_i, i_senha; char sinco[] = "Senha incorreta, tente novamente!"; char csenha[] = {0}; char clogin[] = {0}; char p_aul[] = {0}; int senha1, i, t, r, s, ilogin, ip_aul; printf("Já possui login?\n\n"); printf("1 - Não\n"); printf("2 - Sim"); printf("\nEscolha a opção desejada: \n"); scanf("%d", &numero); switch (numero) { case 1: printf("Insira os dados para cadastro"); if (p_au == NULL && p_as == NULL) { printf("Erro na abertura do arquivo!"); return 1; } else { fflush(stdin); printf("\nEscreva um email para cadastro: "); scanf("%s", &usuario_c); i_usuario = strtol(usuario_c, NULL, 10); printf("\nCódigo %i\n", &i_usuario); printf("Confirme seu email"); s = 3; fflush(stdin); for (i = 0; i < 3; i++) { printf("\nVocê só terá %i chances", s); s--; printf("\nInsira o email novamente: \n"); scanf("%s*%c", &c_usuario); // usuario teste usuario_i = strtol( c_usuario, NULL, 10); // transformando string em int printf("\nCódigo rastreio %i\n", &usuario_i); fflush(stdin); if (i_usuario != usuario_i) { printf( "\nO email está incorreto, por favor tente " "novamente!"); } else { printf("\nEmail correto.\n"); fprintf( p_au, "%s", usuario_c); // usando fprintf para // armazernar string no arquivo fclose(p_au); // usando fclose para fechar o // arquivo fflush(stdin); printf("\nDados gravados com sucesso!"); break; } } // DEU CERTO *****, so não sei como, fazer o mesmo para // senha printf("\nEscreva uma senha para cadastro: "); scanf("%s", senha_c); i_senha = strtol(senha_c, NULL, 10); printf("Confirme sua senha"); r = 3; for (i = 0; i < 3; i++) { printf("\nVocê só terá %i chances", r); r--; printf("\nInsira a senha novamente: \n"); scanf("%s*%c", c_senha); // usuario teste senha_i = strtol( c_senha, NULL, 10); // transformando string em int if (i_senha != senha_i) { printf( "\nA senha está incorreta, por favor tente " "novamente!"); } else { printf("\nSenha correta.\n"); fprintf( p_as, "%s", c_senha); // usando fprintf para armazernar // string no arquivo fclose(p_as); // usando fclose para fechar o // arquivo printf("\nDados gravados com sucesso!"); // printf("\nDados gravados com sucesso!"); break; } } } break; case 2: p_aus = fopen( "email_cadastro.txt", "r"); // abrindo o arquivo com tipo de abertura w // p_as = fopen("senha_cadastro.txt", "r"); fprintf(p_aus, "email_cadastro"); if (p_aus == NULL) { printf("Não há login cadastrado"); } else { fscanf(p_aus, "email_cadastro.txt", &p_aul); printf("Insira o login: "); scanf("%s*%c", &clogin); ilogin = strtol(clogin, NULL, 10); ip_aul = strtol(p_aul, NULL, 10); } if (ilogin != ip_aul) { printf("Login incorreto"); } } }  
  14. O post de arfneto em Como faço pra dar um boost no meu roteador secundária, quê uso como repetidor? foi marcado como solução   
    Não é que você manda o sinal, apenas chega. E tem uma certa perda nesses 50m e não há como recuperar. Faça um esforço e arrume uma conexão física entre os dois. Use um cabo 5E dentro de um duto, são só 50m. Ou mesmo transmita por algum cabo de força se estiverem na mesma rede elétrica, usando algum adaptador PowerLine. Se tiver um cabo de TV já passando de uma casa para a outra pode usar um adaptador MOCA, aproveitando a blindagem do coaxial. Se não tiver um uso pesado constante na primeira conexão a banda que chega na segunda casa vai estar ok, mas a perda de sinal entre os dois não tem como recuperar se usa rádio (wifi).  
     
    300 e 150 mbits são suficientes para uns poucos aparelhos.
  15. O post de arfneto em Especificadores extern e static foi marcado como solução   
    auto significa praticamente nada em C. Ou nada mesmo. Sugiro esquecer. 
     
    Em C++ é outra coisa, especialmente com templates e coisas tipo &&
     
     
     
     
    Não. E não poderiam ser. Veja o exemplo.
     
    Pense como o linker. Ele precisa fazer algo com o programa. Contexto aqui é scope. Em
     
    // programa int x; int y = x; // fim  
    que vai fazer com x e y? claro que tem que ser alocados. E o scope tem que ser global. Se não fosse estaria onde? A menos que isso fosse incluído em um programa...  E assim são static, porque vão ter escopo global.
     
     
    todo protótipo declara a função como extern. Se ela aparecer depois no mesmo arquivo aí passa a ser local... Mas ao ler o protótipo o compilador não sabe. É pra isso que existe o protótipo afinal.
     
     
    Isso não é o mais importante: o importante é que variáveis estáticas são alocadas uma única vez (linker) e não a cada chamada da função. É o mesmo caso com main() que é uma função, só que em geral main() não é chamada de novo...
    Isso implica em que o endereço de uma variável estática dentro da função é constante, ao contrário das outras variáveis, que são recriadas a cada chamada.
     
    funções static acabam assim existindo no contexto do arquivo  porque o linker coloca o código da função em um segmento separado para esse particular bloco de código, então endereço será desconhecido fora dele.
     
     
     
    pois é. auto para as variáveis não quer dizer nada, extern para as funções não quer dizer nada. A menos que tenha um código enorme com múltiplos #include por exemplo e queira ter certeza de que ninguém dentro dele define uma certa função cujo protótipo está no header
     
     
     
    Deve gerar um warning ao menos. Mas desde que o linker encontre uma no caminho vai gerar o código.
     
     
     
     
  16. O post de arfneto em SDL 2.0: Como desenhar um simples retângulo? foi marcado como solução   
    Oh rodava que dizer que apenas compilava. Agora entendo. Só com as Surfaces eu não via como mostrar algo e aí fiquei curioso! Seria preciso carregar algo, mesmo que seja um bitmap como no exemplo acima. Ou criar o normal, window, renderer e textures. Obrigado por responder
     
     
    Pode usar exatamente o mesmo comando no Windows!
     
  17. O post de arfneto em Arvore binaria e arquivos .txt, linguagem C foi marcado como solução   
    Não, não precisa. Os nomes dos arquivos e a data de último acesso são apenas os dados em cada nó.
     
    Só que tem o lance do conteúdo do arquivo ter a data de acesso
     
     
    Imagino que não seja então para usar a data de último acesso ao arquivo, a data que é mantida pelo sistema, e sim usar essas "datas" aí.
     
    Então é uma ideia meio b3st@, mas seria o caso então de:
    criar um diretório com esses arquivos txt ao rodar o programa pegar o diretório e a tal data ler os arquivos da pasta e pegar a data, que pode ser o único conteúdo do arquivo, e colocar na árvore junto com o nome depois pegar a data de exclusão, varrer a árvore e apagar os arquivos usando o critério. 3 fases então.  Para cria os arquivos pode usar o editor de texto mesmo. Não precisa fazer parte de um programa.  
    Não entendi porque tem 1 menu em seu programa... 
     
    Não escreva programas interativos. C nem é pra isso. E seu programa não é pra isso.
     
    Use a linha de comando. São dois parâmetros de entrada: a pasta onde estão os arquivos e a data de corte. Nada mais.
     
    Se seu programa fosse chamado tst não seria o simples escrever
     
    tst pasta 04072021
    e ter o programa entrando no diretório pasta e apagando os arquivos com data de accesso anterior a essa data?
    Não há mais perguntas. Apenas o resultado. Pra que um menu, e ficar parado em frente a tela e tal?
     
  18. O post de arfneto em rotear internet do notebook via cabo foi marcado como solução   
    Em geral os telefones IP tem suporte para o contrário, ligar o telefone no ponto de rede e o notebook no telefone. Por isso esses telefones tem 2 portas de rede em geral.
     
    Mas se não tem nenhuma porta para o telefone ou o notebook, pode sim fazer o contrário, ligando o notebook via wifi e o telefone na porta de rede do notebook. Configure o serviço de acordo no Windows e pode usar a porta de rede do notebook como bridge --- no popular, conexões de ponte --- da rede local. ou configurar o compartilhamento da conexão no Windows como o antigo ICS, como descrito em um post acima. 
     
  19. O post de arfneto em Ponteiros e Vetores (argc e argv) foi marcado como solução   
    termo = (argv[0]); frase = (argv[1]);  
    Qual a razão desses parenteses? 
     
    Não entendi seu programa.
     
    for (l = 0; termo[l] != '\0'; l++);//verifica o tamanho for (i = 0, j = 0; frase[i] != '\0' && termo[j] // ...  
    NUNCA escreva assim se a lógica não exigir. Declare as variáveis de controle DENTRO do for.
     
    NUNCA use variáveis globais com nomes ingênuos como i e l. Isso sempre cai na sua cabeça. Além de ser proibido e toda parte, escolas e empresas.
     
    Se está usando Linux veja se seu compilador oferece a função getopt() 
     
    argv[0] é o nome do programa.
     
    Seu programa deve ter CINCO argumentos.
     
    Porque não escreve um programa que simplesmente mostra antes de tudo os argumentos? Te daria mais informação sobre o que está fazendo em uma linha de programa... os argumentos são constantes.
     
    Seu executável deve ser 1.
  20. O post de arfneto em Criar espaço na memória para CHAR, com propriedades de VETOR em LISTA estática. foi marcado como solução   
    Poste suas dúvidas, aqui por exemplo. Um tópico = uma dúvida. Pode ter sucesso, ou pode achar aqui pessoas mais confusas e complexas  não sei. Não sei se sua escola é paga, mas o forum é grátis  
     
     Imagino que não tenha achado confuso e complicado o que eu te expliquei, já que nada perguntou. Vou te mostrar algo ainda sobre a diferença entre a maneira que usou e uma maneira de escrever sua estrutura em torno dos seus dados.
     
     
    A fila pode ser implementada usando uma lista. A lista pode ser representada usando um vetor e parece ser o que está tentando fazer. E a lista é "encadeada" --- linked --- através dos índices de um vetor. É uma maneira comum de implementar, porque a performance é muito boa.
     
    Se quer usar mesmo uma seção linear do vetor para a fila, uma coisa assim serviria, e pode até compilar já:
     
    #define TAM 5 #include <stdio.h> typedef struct { char arquivo[20]; char extensao[20]; int matricula[5]; int ra[5]; } Info; typedef struct { Info info[TAM]; unsigned size; unsigned ini; unsigned fim; } Fila; int add_info(Info* dado, Fila* fila); int del_info(Info* dado, Fila* fila, char campo); int show_info(Info* dado); int cria_fila(Fila* fila); int apaga_fila(Fila* fila); int mostra_fila(Fila* fila); int main(void) { return(0); } // insere dado na fila int add_info(Info* dado, Fila* fila) { return 0; }; // apaga dado da fila conforme o valor de opt int del_info(Info* dado, Fila* Fila, char opt){ return 0; }; // mostra um registro na tela int show_info(Info* dado) { return 0; }; // zera uma fila existente int apaga_fila(Fila* fila) { return 0; }; // prepara uma fila vazia int cria_fila(Fila* fila) { return 0; }; // mostra todos registros da fila int mostra_fila(Fila* fila) { return 0; }; // funcoes aux. void clear() {}; // mostra o menu, retorna a opcao int menu() { return 0; };  
    Entenda que em geral não se alocaria um vetor de estruturas mas provavelmente um vetor de ponteiros para Info.
     
    Se escrever assim pode ter filas de qualquer coisa, pode ter várias filas no mesmo programa, e tudo fica mais fácil de testar e manter.
     
     
     
  21. O post de arfneto em Calculo com chamada com programa em C foi marcado como solução   
    Não entendo qual a sua dúvida. Pode explicar de outro modo?
     
    Entendeu o programa que te mostrei? Rodou em sua máquina? Viu a explicação passo a passo do cálculo que te mostrei? Não perguntou nada...
     
    Porque não faz o que te mostrei e passa a string para a função e a função devolve o tal DV? Não é mais simples?
     
    Qual  a razão de fazer uma parte em main(0 e uma parte em calcula_dv() ???
     
    Porque está lendo a string do teclado se ainda não sabe fazer o cálculo? Porque não usa constantes depois de saber o resultado???????
     
     
    Eu te mostrei o cálculo aqui e o DV é 3.
     
     
    Então porque não testa seu cálculo assim?
     
    declare o que já te mostrei:
     
     
    e chame assim
     
    int teste_do_digito = calcula_dv("1541253"): printf("Quanto acha que vale o DV? %d\n", teste_do_digito );  
    e testa sua função até ela imprimir 3. E aí testa com outros números. E aí coloca a p0rr@ da leitura do teclado que só vai te atrasar ao ficar digitando durante os testes....
  22. O post de arfneto em O que colocar no .h e no .c? foi marcado como solução   
    Note que nenhum dos dois é a biblioteca. 
     
    Você vai usar o compilador C no caso para criar o código de sua biblioteca. E vai gerar um arquivo com extensão LIB no windows usando o programa.... LIB 
     
    clube> lib /? Microsoft (R) Library Manager Version 14.28.29915.0 Copyright (C) Microsoft Corporation. All rights reserved. usage: LIB [options] [files] options: /DEF[:filename] /ERRORREPORT:{NONE|PROMPT|QUEUE|SEND} /EXPORT:symbol /EXTRACT:membername /INCLUDE:symbol /LIBPATH:dir /LINKREPRO:dir /LINKREPROTARGET:filename /LIST[:filename] /LTCG /MACHINE:{ARM|ARM64|ARM64EC|EBC|X64|X86} /NAME:filename /NODEFAULTLIB[:library] /NOLOGO /OUT:filename /REMOVE:membername /SUBSYSTEM:{BOOT_APPLICATION|CONSOLE|EFI_APPLICATION| EFI_BOOT_SERVICE_DRIVER|EFI_ROM|EFI_RUNTIME_DRIVER| NATIVE|POSIX|WINDOWS|WINDOWSCE}[,#[.##]] /VERBOSE /WX[:NO] clube>  
     
    E aí claro o programa C desaparece. 
     
    E como alguém vai usar sua bibioteca? 
     
    Você vai criar um arquivo em geral com a extensão h, onde estão os protótipos das funções e constantes de sua biblioteca e vai distribuir os dois, o arquivo lib e o arquivo h, muitas vezes por um preço  
     
    E vai guardar os arquivos C com cuidado porque serão a única maneira de manter a biblioteca.
     
    Eis um roteiro passo a passo de como criar uma usando um IDE: https://docs.microsoft.com/pt-br/cpp/build/walkthrough-creating-and-using-a-static-library-cpp?view=msvc-160
     
    Pode ajudar a entender o uso
  23. O post de arfneto em Desenvolvimento de Programa - Calcula Dígito Verificador foi marcado como solução   
    Você ao menos rodou  programa que te mostrei no tópico #6? 
     
    É praticamente a solução de seu problema.
     
    E leu a explicação sobre o cálculo como eu expliquei?
     
    Eu te mostrei como escrever, assim:
     
    int DV( const char*); int main(void) { const char string[] = { "\ para formatacao do valor como: .(ponto), -(traco), virgula 1234 e 5678 outros;" }; printf( "Exemplo de entrada: \"%s\"\n", string); int valor = DV(string); printf( "DV() retornou %d\n", valor ); return 0; }  
    e te mostrei até a saída do programa.
     
    E aí você posta isso 15 dias depois:
     
    void caucula_dv(){ }  
    Porque não fez como eu disse? Tem um motivo para inovar e escrever uma função assim?
     
    E qual a fórmula do cálculo do DV afinal?
     
     
     
     
     
     
    Descreva o cálculo do DV como está no enunciado e eu te mostro um exemplo
  24. O post de arfneto em Estou tentando fazer um macro foi marcado como solução   
    Para qualquer linguagem, desde que use as convenções de chamada da linguagem C, a API do Windows é o simples. Esse é o caso de C# e C++ e claro C. Veja a documentação da API do Windows para essas mensagens:
     
    #define WM_LBUTTONDOWN                  0x0201 #define WM_LBUTTONUP                    0x0202 #define WM_APPCOMMAND                   0x0319 #define WM_KEYDOWN                      0x0100  
    A documentação completa está onde se espera... em Microsoft Docs.
     
    Segurar o click é o que acontece entre 0x201 e 0x202. Descer o cursor, se tem esse conceito na janela em foco, é mandar o comando para descer, como a seta para baixo, e mandar a 0x319 para a janela com o código certo da tecla via a outra mensagem, 0x100 passando o código da tecla que quer "pressionar"
     
     
     
     
  25. O post de arfneto em <the-dereferencing-pointer-to-incomplete-type-error> Como resolver esse erro? foi marcado como solução   
    facilite _mesmo_ postando o código completo de modo que quem achar que pode ajudar possa testar...
     
    No seu programa aparentemente Rac pode ser uma estrutura anônima. 
     
    Onde está a definição da estrutura?
     
    Não há razão para declarar 
     
    Rac* num1; // ... num1 = cria_racional(1,2);  
    prefira o simples
     
    Rac* num1 = cria_racional(1,2);  
    Provavelmente o que você queria escrever era, no header
     
    typedef struct { int numerador; int denominador; } Rac;  
    E a função está onde?

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

Redes-Wi-Fi-capa-3d-newsletter.png

EBOOK GRÁTIS!

CLIQUE AQUI E BAIXE AGORA MESMO!