Ir ao conteúdo
  • Cadastre-se

codigo rapido

Membro Pleno
  • Posts

    275
  • Cadastrado em

  • Última visita

posts postados por codigo rapido

  1. obrigado!

    não consigo escrever uma resposta melhor porque o site parece com problemas.
     

    10 horas atrás, Gimael disse:

    A injeção de código é possível em linguagens que interpretam e/ou compilam o código. Nativamente a linguagem C não faz isso - quer dizer, não há uma função eval em C, como há em linguagens de scripting, que pode receber código, compilá-lo, e depois executá-lo.

    Obrigado! É isso mesmo!

     

     

    10 horas atrás, Gimael disse:

    Escrever um programa que faça isso não é muito difícil


    Na verdade não pretendo fazer isso. Eu estou fazendo um servidor bem simples com base no tiny.c que encontrei e me veio essa preocupação. A preocupação pra mim então é só com o sql injection. Isso pra mim é fácil. Muito obrigado pelas dicas!

  2. Olha isso:
     

    
    #include <stdio.h>
    int main()
    {
    	float matriz[4][3];
    	//char *s = (float *) malloc(10*3*sizeof(float)); // se não usar malloc:
    	char s[255];
    
    	printf("Cole os valores:\n");
    	gets(s);
    	printf("\n");
    
    	//cole os dados:
    	//62.0 66.0 2.1, 59.0 113.2 1.3, 47.0 94.2 1.7, 21.0 85.2 2.0
    
    	sscanf(s, "%f %f %f, %f %f %f, %f %f %f, %f %f %f", 
    	&matriz[0][0],&matriz[0][1],&matriz[0][2],
    	&matriz[1][0],&matriz[1][1],&matriz[1][2],
    	&matriz[2][0],&matriz[2][1],&matriz[2][2],
    	&matriz[3][0],&matriz[3][1],&matriz[3][2] );
    
    	for(int i=0; i<4; i++)
    	{
    		for(int j=0; j<3; j++)
    		{
    			if(j==0)
    			printf("%0.0f ", matriz[i][j]);
    			else
    			printf("%0.1f ", matriz[i][j]);
    		}
    		printf("\n");
    	}
    	//free(s); // se usar malloc
    	return 0;
    }


    Não tá completo, não é exatamente como definiu, mas é só adaptar o exemplo para o que quer.

  3. 11 horas atrás, V!OLADOR disse:

     

    Não vale a pena. Alocação dinâmica é muito custosa. É mais eficiente alocar um bom pedaço de memória no inicio e apenas dobrar esse pedaço quando tiver esgotado todo o espaço. Na hora de reduzir você apenas define o índice que referencia o "topo" da parte utilizável de maneira que os índices acima referem-se a parte da memória alocada (e pronta pra uso) mas não utilizada. Esse método previne também a fragmentação da memória que vai ocorrer com as sucessivas chamadas de malloc, realloc e free.

    De forma geral, essa ideia transforma o processo relativamente ineficiente de alocar, realocar e liberar memória numa simples manipulação de ponteiros, ou seja, super rápido. Na industria de games AAA, por exemplo, malloc, realloc, free, new e delete não são utilizados nas partes críticas do projeto.



    Eu tava pensando em casos em que se insere um dado e a deleção dele só acontece quando se abaixa uma flag nos dados, representando a exclusão. Nos casos em que se insere, imaginei que eu deveria já criar uma tabela vazia e ir adicionando o mais disperso possivel, para que se eu tiver a necessidade de inserir entre algum valor, eu ter os espaços vazios para ir jogando pra frente os que estiverem atrapalhando...
    Eu to cheio de ideias pra fazer uns programas sobre isso. É um assunto muito legal e interessante. Mas infelizmente o o pouco tempo que tenho vai me obrigar a deixar isso pra depois.

    Valeu! Ogrigado!

  4. Antigamente existiam algumas formas de se hackear sites utilizando algumas vulnerabilidades, como injeção de código na linguagem do site ou na linguagem do banco de dados usado pelo site. O SQL injection era uma maneira interessante de pegar as tabelas de nomes e senhas de usuários. Existe forma de se fazer o mesmo em C? Se sim, quais caracteres eu devo fazer escape para evitar que algum hacker consiga fazer algo prejudicial ao sistema?

    Hoje eu fiz um url decode. Percebi que o GEdit tem iso-8859-1 para salvar meus arquivos .c, mas quando eu faço um locale, só aparece UTF-8. Então fiquei imaginando um cliente com o mesmo problema e que não queira atualizar sua maquina e fiz o seguinte programa:
     

    //fonte: http://tivideotutoriais.blogspot.com/2021/08/linguagem-c-url-decode-iso-8859-1.html
    char *matriz[16][16] = {	
    	{"^@","^A","^B","^C","^D","^E","^F","^G","^H","^I","<br>","^K",  "^L","^M",  "^N","^O"},
    	{"^P","^Q","^R","^S","^T","^U","^V","^W","^X","^Y","^Z","^[", "^\\","^]",  "^^","^_"},
    	{ " ", "!","\"", "#", "$", "%", "&","\'", "(", ")", "*", "+",   ",", "-",   ".", "/"},
    	{ "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", ":", ";","&lt;", "=","&gt;", "?"},
    	{ "@", "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K",   "L", "M",   "N", "O"},
    	{ "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", "[",  "\\", "]",   "^", "_"},
    	{ "`", "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k",   "l", "m",   "n", "o"},
    	{ "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z", "{",   "|", "}",   "~","^?"},
    	{ " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ",   " ", " ",   " ", " "},
    	{ " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ",   " ", " ",   " ", " "},
    	{ " ", "¡", "¢", "£", "¤", "¥", "¦", "§", "¨", "©", "ª", "«",   "¬", " ",   "®", "¯"},
    	{ "°", "±", "²", "³", "´", "µ", "¶", "·", "¸", "¹", "º", "»",   "¼", "½",   "¾", "¿"},
    	{ "À", "Á", "Â", "Ã", "Ä", "Å", "Æ", "Ç", "È", "É", "Ê", "Ë",   "Ì", "Í",   "Î", "Ï"},
    	{ "Ð", "não", "Ò", "Ó", "Ô", "Õ", "Ö", "×", "Ø", "Ù", "Ú", "Û",   "Ü", "Ý",   "Þ", "ß"},
    	{ "à", "á", "â", "ã", "ä", "å", "æ", "ç", "è", "é", "ê", "ë",   "í", "ì",   "î", "ï"},
    	{ "ð", "não", "ò", "ó", "ô", "õ", "ö", "÷", "ø", "ù", "ú", "û",   "ü", "ý",   "þ", "ÿ"}
    };
    
    int hex(char x)
    {
    	if(x=='0'){ return 0;}
    	if(x=='1'){ return 1;}
    	if(x=='2'){ return 2;}
    	if(x=='3'){ return 3;}
    	if(x=='4'){ return 4;}
    	if(x=='5'){ return 5;}
    	if(x=='6'){ return 6;}
    	if(x=='7'){ return 7;}
    	if(x=='8'){ return 8;}
    	if(x=='9'){ return 9;}
    	if(x=='A'||x=='a'){ return 10;}
    	if(x=='B'||x=='b'){ return 11;}
    	if(x=='C'||x=='c'){ return 12;}
    	if(x=='D'||x=='d'){ return 13;}
    	if(x=='E'||x=='e'){ return 14;}
    	if(x=='F'||x=='f'){ return 15;}
    	return -1;
    }
    
    char hexch(int x)
    {
    	if(x== 0){ return '0';}
    	if(x== 1){ return '1';}
    	if(x== 2){ return '2';}
    	if(x== 3){ return '3';}
    	if(x== 4){ return '4';}
    	if(x== 5){ return '5';}
    	if(x== 6){ return '6';}
    	if(x== 7){ return '7';}
    	if(x== 8){ return '8';}
    	if(x== 9){ return '9';}
    	if(x==10){ return 'A';}
    	if(x==11){ return 'B';}
    	if(x==12){ return 'C';}
    	if(x==13){ return 'D';}
    	if(x==14){ return 'E';}
    	if(x==15){ return 'F';}
    	return '\0';
    }
    
    char *dec(int a, int b)
    {
    	return matriz[a][b];
    }
     
    int urlDecode(char *out, char *s )
    {
    	int a, b;
    	int tm = strlen(s);
    	int remove=0;
    	char c, decoded[8];
    	strcpy(out, ""); //limpa tudo que tiver em out
    	for(int i=0; i<tm; i++)
    	{
    		c = *s++;
    		if (c=='%')
    		{
    			a = hex(*s++) ;// primeiro hexadecimal
    			b = hex(*s++) ;// segundo  hexadecimal
    			strcpy(decoded, "");
    			strcat(decoded, dec(a,b));
    			strcat(out, decoded);
    			//nem todos são formados por um 
    			//unico caractere. Remove ecesso no final
    			remove+=strlen(decoded);
    		} 
    		else if (c == '+')
    		{
    			strcat(out, " ");
    		}
    		else
    		{
    			char m[2]={c,'\0'};
    			strcat(out, m);
    		}
    	} 
    	out[strlen(out)-remove]='\0'; 
    	return strlen(out);
    }
    
    void matrixDecode()
    {
    	printf( "\nMatriz de decodificação:\n"); 
    	for(int i=0; i<16; i++)
    	{
    		for(int j=0; j<16; j++)
    		{
    			printf("%c%c=%s\t", hexch(i),hexch(j),dec(i,j));
    		}
    		printf("\n");
    		for(int j=0; j<16; j++)
    		{
    			printf("%i=%s\t", i*16+j,dec(i,j));
    		}
    		printf("\n");
    		printf("\n");
    	}
    }
    
    void testaDecode()
    {
    	printf( "\nTestando decode:\n"); 
    	char *url = "username=%C1gatha+Silva&email=agata%40dasilva.com";
    	printf( "url = %s\n", url ); 
    	int tm = strlen(url);
    	printf( "tamanho url = %i\n\n", tm);
    	char resp[tm];
    	tm = urlDecode(resp, url) ;
    	printf( "decodificado = %s\n", resp);
    	printf( "tamanho do decod = %i\n", tm); 
    }
    
    int main()
    {
    	matrixDecode();
    	testaDecode();
    	return 0;
    }


    Esses fontes são interessantes, mas não funcionaram pra mim:


    https://www.rosettacode.org/wiki/URL_encoding
    https://www.rosettacode.org/wiki/URL_decoding

    Se esse programa rodar no servidor, quem poderia me mostrar um exemplo de encode que poderia fazer algo inesperado com o sistema?

     

  5. Isso é só pra demonstrar que o tamanho na declaração do array não deveria ser importante para a função que recebe o parametro:
     

    #include <stdio.h>
    #include <stdlib.h>
    #include <stdbool.h>
    
    typedef struct
    {
    	char nome[50];
    	int idade;
    } pessoa;
    
    int s1(pessoa pessoas[])
    {
    	printf("----------------------------------\n");
    	int i=0;
    	for(; pessoas[i].idade!=NULL; i++)
    	{
    		//printf("Nome: %s Idade:%i\n", pessoas[i].nome, pessoas[i].idade);
    	}
    	printf("Tamanho: %i \n", i);
    	return 0;
    }
    
    int main()
    {
    	pessoa pessoas1[] = {{"Luiz", 44}, {"Sofia", 11}, {"Daniele", 35}, {NULL, NULL}};
    	s1(pessoas1);
    
    	pessoa pessoas2[] = {{"Maria", 70}, {"Gabriel", 15}, {"Samuel", 11}, {"Luiz", 44}, {"Sofia", 11}, {"Daniele", 35}, {NULL, NULL}};
    	s1(pessoas2);
    	return 0;
    }

     

    E funciona.
    Só que é feio porque sou obrigado a fazer um while... de alguma forma outras linguagens fazem isso de forma invisivel.
    E é feito porque tenho que utilizar um marcador com a struct com NULLs...

  6. 3 horas atrás, arfneto disse:

    Só não ofereci o lanche nem bebida aos leitores.

     

    Só não paguei o lanche e a bebida para os leitores.


    Eu não te pedi nada além de coerencia.
    E lhe agradeci muito pelo pelo navegador que postou.
    Mas isso não lhe dá direito nenhum de falar assim com ninguem.
     

    Citação

    Eu te disse como fazer. E seria trivial. Só que sua pergunta não era essa.


    Era essa sim. E eu ainda repeti em #5. Mas a pergunta é tão compreensivel que logo no primeiro post que fiz o usuário Flavio Pedroza entendeu e respondeu rapidamente eu eu já lhe dei like e o atribui como o solucionador do problema. Por isso que quero saber se você é uma inteligencia artificial. porque por ética, você, como robo do forum é obrigado a dizer se é ou não.

    deixa eu te explicar o que aconteceu...
    você veio e disse que tinha uma forma de fazer. fez um post gigante #8 e eu para não te deixar no vácuo, postei um link de um post meu #9, que é mais antigo a esses seus posts pra te dar uma dica que desse modo eu sabia como pegar o tamanho de arrays. Eu tava tentando ser gente boa contigo, pra não te deixar no vácuo porque tava sendo legal ao mostrar seu navegador, que eu já lhe agradeci.

     

     

    Citação

    De todo modo sugiro incorporar as coisas que eu longamente expliquei ao seu programa inicial.

     

    Como apagar registros de um vetor de estruturas

     

    Esse pode ser seu próximo tópico e pode conseguir respostas nesse sentido.

     

    O que posso dizer sobre isso agora só pra ajudar?


    Ok. Mas eu não to aqui pra usar ctrl+c + ctrl+v. Eu to aqui para entender e criar meus proprios metodos. No link que eu passei, mostra que eu já fiz o equivalente. porque eu iria fazer um post como esse?
     

    Citação

    e é uma questão super válida para iniciantes e mesmo desenvolvedores que não tem familiaridade com ponteiros, gravação de arquivos e uso de fseek() e ftell() e fread() para acesso a arquivos em C.

     

    Foi por isso que me dei ao trabalho de escrever isso "tudo", uma resposta "tão grande para uma pergunta tão simples".


    ok... sua suposição foi boa porque foi além do esperado. Mas não tente advinhar o que um usuário quer fazer a partir de uma pergunta simples.

    Citação

    E eu expliquei que isso não funciona. E porque não funciona.

    ok! Desculpa. falou sim. Mas o porque não funciona, eu não vi, ou não entendi. Se se refere ao que disse que o compilador não sabe o tamanho do registro que irá receber como parametro, isso não é uma resposta que explica o porque.

  7. Citação

    Esse exemplos são o simples. Sugiro esquecer isso de "pegar o tamanho do array". Isso não existe. Se precisa mesmo disso, e essas técnicas que mostrei não servem, provavelmente precisa de outra estrutura de dados.

     

    Moço, acho que já te falei isso... uma hora você fala uma coisa e logo depois fala o contrário ou diz que não entendeu...
    Olha o que escreveu no mesmo post:

     

    Citação

    Isso que eu escrevi foi só um exemplo, não é minha ideia. É como se faz isso desde sempre. Não entendi o que quiz dizer com "apagou todo o grupo".

     

    Citação

    Eu não apaguei nenhum grupo, nenhuma pessoa exceto na função que apaga... :)  o grupo. Eu não fiz de cada pessoa. Não é assim que funciona.

     

    Quem determinou isso? Desde sempre o que? Não é assim que funciona o que?

    Sim. Os exemplos são simples. Mas o problema é mais simples ainda... veja:
    você tem um array e passa apenas ele para uma função que deve imprimir a quantidade de pessoas do array:
     

    pessoa pessoas[] = {{"Luiz", 44}, {"Sofia", 11}, {"Daniele", 35}};
    escrever_arquivo(pessoas); // deve imprimir a quantidade de elementos do array pessoas
    // escrever_arquivo(pessoas, tm);// não achei elegante esse método. 


    Agora olha as funções que criou:
     

    Em Grupo1* cria_grp1(unsigned init, unsigned incr)
    você fez
    Grupo1* G = (Grupo1*)malloc(sizeof(Grupo1));
    E em que Lugar dá free nisso? em
    Grupo1* apaga_grp1(Grupo1* g)
    tem
    free(g);
     

    Em Grupo2* cria_grp2(unsigned init, unsigned incr)
    você fez
    Grupo2* G = (Grupo2*)malloc(sizeof(Grupo2));
    E em que Lugar dá free nisso? em
    Grupo2* apaga_grp2(Grupo2* g)
    tem
    free(g);
     

    Em Grupo3* cria_grp3(unsigned init, unsigned incr)
    você fez
    Grupo3* G = (Grupo3*)malloc(sizeof(Grupo3));
    E em que Lugar dá free nisso?
    Mas... Em
    Grupo3* apaga_grp3(Grupo3* g)
    você não fez free(g) nessa função.

    Ou seja... você não pode ser uma inteligencia artificial por isso. Mas deixa duvidas que seja. você é uma inteligencia artificial? pra mim está claro que apagou todo o grupo.

    Ou seja, você criou uma função que apaga todo o grupo de uma vez e não uma pessoa de cada vez. Então dizer que você não apagou é um absurdo semantico, pois você delegou isso à função (escolha sua). você não vai com lapis escrever e borracha apagar do HD ou da memória. Não quero dizer que seu codigo está errado, ate porque mesmo dentro dessas funções demonstram o conhecimento o suficiente para qualquer um fazer sua propria função apaga_pessoa e cada um pode fazer a mesma coisa de formas diferentes. Eu não entendi porque você deu uma resposta tão grande para uma pergunta tão simples.


    Os grupos normalmente (dependedo do contexto, é claro) existem na forma de struct (sem precisar de malloc), mesmo que vazios de pessoas. Mas as pessoas nem sempre existem. Podem ser inseridas, editadas, mostradas ou excuidas do grupo.

     


     

  8. Pelo que andei lendo, é posivel sim. Mas exige certos procedimentos que me parecem ser complexos de mais. Algo arriscado e que não compensa.

    Pelo que imagino o que devo fazer se tiver várias threads necessitando de algo assim, eu tenho que colocar cada pedido de leitura e/ou gravação em um tipo de pilha que irá sendo executada na sequencia, atendendo cada thread uma por uma.

    • Curtir 1
  9. Em 22/08/2021 às 19:46, alexandre.mbm disse:

     

    Não vejo nada de genial aí. É só uma esperteza que nem requer inteligência diferenciada.

     

    As pessoas veem mérito no possível, quando o mérito estaria no rejeitar fazer o que é possível e errado.

     

    O verdadeiro conhecedor sabe fazer também o que é errado, e opta por não fazê-lo.

    Não quis dizer que aprovo! Quis dizer que foi muito inteligente.
    Achei algo bem elaborado e bem possivel de se passar pela fiscalização sem ser percebido.
    Algo que pode até ser utilizado com outros produtos.
    A receita e a policia rodoviária federal devem ter a mesma esperteza pra não deixar coisas semelhantes passarem despercebidas.

  10. Citação

    O programa exemplo trata até 99.999 registros.

    Muito legal. Para a minhas necessidades eu só precisava de 9.999 registros!
    Tá bom de mais da conta!
     

    Eu fiz um exemplo desses utilizando array dinamicos (maloc), mas pensei que tinha forma mais simples do que a que fiz. Ficou um pouco parecido com a struct Grupo:
    https://www.clubedohardware.com.br/forums/topic/1558865-alocação-dinamica-de-array-inclusão-exclusão-e-free/     

     

    Agora aqui, busquei uma forma sem uso de strutc, querendo pegar o tamanho do array sem precisar passar parametros além do array ou ficar utilizando contadores, como na struct grupo dos seus exemplos ou do Array do link acima que passei.
    Vejo que não é tão simples como pensei que fosse, pois achava que existia uma forma de pegar o tanhado do array ja dentro da função sem uso de struct e contadores. Bem... pelo menos eu não consigo fazer.
    Acredito que especifiquei errado o problema. De qualuqer forma, obrigado. Gostei de muita coisa que postou aqui.

     


    voltando ao seu post...
     

    Citação

     Eis o que acontece:

        conforme o array aumenta essas realocações podem e vão rapidamente se transformar em cópias de tudo que já tem para a nova área. E o sistema não vai pedir licença para copiar.  Quando for a hora acontece. E o programa para. e vai perder o cache. Um desastre ao excluir registros.
            teria que movimentar todo o vetor para eliminar o infeliz excluído.
            Pode só marcar os excluídos mas aí vai perder tempo a cada acesso porque precisa testar CADA registro pra ver se é válido e lá se vai a performance
            só que de tempos em tempos precisa passar a régua em tudo e eliminar os excluídos porque vai degradar a performance e aumentar o desperdício. Quando entrar com a compactação vai perder um tempo enorme.

     

    Sim. Percebi isso na função int deleteByIndexInArray(Array *a, int item) , do exemplo do link que passei. Realmente isso não é legal porque fica fazendo copias. Feio... Mas o que você fez de diferente? Não entendi. você simplesmente apagou todo o grupo. E não apenas ou uma sequencia de pessoas quais queres.
    Para evitar tanta movimentação, acredito que a função void insertInArray(Array *a, myData element) multiplique o tamanho por 2 sempre que atinge o tamanho limite. Isso eu tinha achado interessante. E nos seus insere, em todos, você utiliza realloc. A diferença, que eu gostei bastante, é que você permite o tamanho do incremento passado por parametro.  Achei mais bonito. Mais elegante.
    pra eu passar a régua, sem ficar copiando e apagando sempre que alterar um registro, eu teria que usar uma lista. Ou seja, uma estrutura em que existe um ponteiro apontando para o dado anterior e outro ponteiro apontando para o dado posterior. É bem legal, bonito e interessante.

    Citação

    Por isso se usam listas ligadas, pilhas, filas,  conjuntos, árvores, dicionários, hash e tal... São dados com comportamento. Algoritmos.

    Sim. Entendo isso como metadados. Eles melhoram a eficiencia das operações com os dados. Exemplo os ponteiros que apontam para o elemento anterior e posterior ao elemento "selecionado".
     

    Não entendi porque você fez isso nos grupos cria_grp1, cria_grp2 e cria_grp3:
    Grupo1* G = (Grupo1*)malloc(sizeof(Grupo1));
    Grupo2* G = (Grupo2*)malloc(sizeof(Grupo2));
    Grupo3* G = (Grupo3*)malloc(sizeof(Grupo3));
    No meu entendimento o equivalente disso é a struct Array que fiz fiz em:
    https://www.clubedohardware.com.br/forums/topic/1558865-alocação-dinamica-de-array-inclusão-exclusão-e-free/
    porque fez isso, algo que necessitaria de um free depois que terminasse de utilizar?
    Não sei se daria certo para mim na maioria dos meus casos, pois geralmente quando gravo dados sobre pessoas, se eu for apagar, eu apago um de cada vez. Não apago todo o grupo de pessoas (array) de uma vez.
    No meu entendimento, talvez tenha sido por isso que fez dessa maneira, pois não havendo necessidade de apagar o grupo e sim uma pessoa de cada vez, não precisaria fazer um maloc de cada grupo, como foi feita na sua sugestão.
    Em resumo: não estou certo do porque fez o maloc de cada grupo, mas entendo porque fez de cada pessoa.

     

    Citação

    Esse modo é útil quando se tem processos intermediários, que vão pegar estruturas e passar todas pela ordem para outra fase, processando em lote. Isso porque se pode apenas seguir no loop até vir um NULL.


    Não entendi o que quis dizer com isso. O que quer dizer processos intermediários?
    O que entendi é que o NULL serve como um marcador. Mas em que isso torna melhor que os outros dois primeiros modos? Quando isso será mais util que os dois primeiros?

     

    //Ok! Mas como eu faço para que a função que recebe o seguinte array como parametro pegar o tamanho dele? 
    pessoa pessoas[] = {{"Luiz", 44}, {"Sofia", 11}, {"Daniele", 35}};
    // usando uma função simples assim:
    escrever_arquivo(pessoas);



    Amei sua função int testa_arquivo(const char* arquivo). O navegador para o arquivo "binário". Lindo isso! Cara, valeu! Mesmo! De mais da conta!
     

    • Curtir 1
  11.     Pessoa gente[20];
        printf("Tamanho do vetor: %zd\n", sizeof(gente) / sizeof(gente[0]));
        return 0;


    Isso eu sei. Mas como fazer isso sem ser obrigado a passar por parametro o tamanho. Nem sempre se sabe o tamanho antes de se chamar a função. E é nisso que mora a beleza da coisa. Quando o array é populado de forma dinamica.

    Mas acredito que essa seja a solução:
     

    Citação

    3. Um vetor de ponteiros null-terminated

    E nesse caso você pega o tamanho como strlen() faz para toda string: pega o endereço inicial e conta até achar um 0.

     

    Então eu uso o tamanho da struct do array (no caso pessoa), e vou retirando, a partir do endereço de pessoas até encontrar \0.

    vou testar isso.

    Obrigado

     

    • Curtir 1
  12. 29 minutos atrás, Flávio Pedroza disse:

    Apesar do formato binário se mais eficiente, eu recomendo usar o formato .xml para persistência de dados.

    como não pretendo usar banco de dados para um projetinho aqui, acho que vou fazer isso mesmo.
    mas me incomoda não conseguir encontrar uma forma de recuperar dados corrompidos nesses DATs.
    imagino que seria melhor eu salvar nos dois formatos. O DAT para ter a eficiencia e o XML para garantia.
     

  13. 3 horas atrás, Flávio Pedroza disse:

    "porque sempre tenho que adicionar ';' dentro do primeiro case?"

    A linguagem não permite colocar declaração de variável logo após um rotulo, apenas instrução. Então você coloca uma instrução vazia (;) para superar essa limitação.

    Em relação ao outro problema, acredito que não há como fazer o que quer. Sugiro mudar a função acrescentando um parâmetro:

    int escrever_arquivo(pessoa pessoas[], int n) //n eh a quantidade de pessoas

    Lembrando que isso

    int escrever_arquivo(pessoa pessoas[])

    é equivalente a isso

    int escrever_arquivo(pessoa* pessoas)

    E

    int len_vet = sizeof(pessoas);

    retorna o tamanho em bytes do ponteiro de memoria (8 bytes, para sistemas de 64 bits).


    Muito obrigado!
    Achei isso estranho. Estou acostumado com java. por isso achei isso feio...
    Parece (estou certo?) que eu só devo utilizar ponteiros na passagem de parametros se eu tiver criado ele com maloc. De outro modo, a passagem de ponteiros é desnecessário, sendo melhor trabalhar com o array. Veja que consegui fazer usando arrays acrescentando mais um parametro, como sugeriu:
     

    #include <stdio.h>
    #include <stdlib.h>
    #define MAX 100
    
    typedef struct
    {
    	char nome[50];
    	int idade;
    } pessoa;
    
    int escrever_arquivo(pessoa pessoas[], int tm)
    {
    	FILE * arq;
    	arq = fopen("dados.bin", "ab");
    
    	if(arq == NULL)
    	{
    		printf("\nErro ao abrir o arquivo para leitura!\n");
    		fclose(arq);
    		return -1;
    	}
    	for(int i=0; i<tm; i++)
    	{
    		fwrite(&pessoas[i], sizeof(pessoa), 1, arq);
    	}
    	fclose(arq);
    	return 0;
    }
    
    int ler_arquivo(pessoa aux_pessoas[])
    {
    	FILE * arq = fopen("dados.bin", "rb");
    	if(arq == NULL)
    	{
    		printf("\nErro ao abrir o arquivo para leitura!\n");
    		return -1;
    	}
    	int indice = 0;
    	pessoa p;
    	while(fread(&p, sizeof(pessoa), 1, arq))
    	{
    		aux_pessoas[indice++] = p;
    	}
    	fclose(arq);
    	return indice;
    }
    
    int main(int argc)
    {
    	char oper;
    	int len_vet;
    	pessoa aux_pessoas[MAX];
    
    	while (oper != 's')
    	{
    		printf("================ MENU ================ \n");
    		printf("Escolha: \ng - Para gravar\nl - para ler\ns - para sair\n");
    		scanf(" %c", &oper);
    		switch (oper) 
    		{
    			case 'g':;
    				pessoa pessoas[] = {{"Luiz", 44}, {"Sofia", 11}, {"Daniele", 35}, {"claudia", 55}};
                	// Sei que é 4, mas aqui pego o tamanho de forma dinamica:
    				int tm = sizeof(pessoas)/sizeof(pessoa); 
                	// É estranho que a função consiga ler todo o conteudo, mas não sabe onde ele termina
                	// mesmo trabalhando com ponteiro, fazendo algo assim:
                	// pessoa *p = pessoas;
                	// e passando por parametro o p, sou obrigado a passar tm por parametro. Ou seja, 
                	// não faz diferença fazer isso e por simplicidade é melhor deixar como está. 
    				escrever_arquivo(pessoas, tm);
    				break;
    			case 'l':
    				len_vet = ler_arquivo(aux_pessoas);
    				if(len_vet>0)
    				{
    					printf("=========================================\n");
    					for(int i=0; i<len_vet; i++)
    					{
    						printf("Nome: %s\n", aux_pessoas[i].nome);
    						printf("Idade: %d\n", aux_pessoas[i].idade);
    						printf("-----------------------------------------\n");
    					}
    				}
    				break;
    			case 's':
    				break;
    			default:
    				printf("opcao invalida!\n");
    				break;
    		}
    	}
    	return 0;
    }


     

    • Curtir 2
  14. Gostaria de pegar o tamanho do array, mas não sei porque estou errando:

     

    #include <stdio.h>
    #include <stdlib.h>
    #define MAX 100
    
    
    
    typedef struct
    {
    	char nome[50];
    	int idade;
    } pessoa;
    
    
    int escrever_arquivo(pessoa pessoas[])
    {
    	FILE * arq;
    	arq = fopen("dados.bin", "ab");
    
    	//to apanhando aqui e tentei várias coisas sem sucesso:
    	int len_vet = sizeof(pessoas);
    	//int len_vet = sizeof(pessoas)/sizeof(pessoas[0]);
    	//int len_vet = sizeof(pessoas)/sizeof(pessoa);
    	printf("tamanho deveria ser 3, mas é = %i\n", len_vet);
    	printf("tamanho do tipo = %i, tá errado esse tamanho!\n", sizeof(pessoa));
    	printf("tamanho do pessoas[0] = %i, tá errado esse tamanho!\n", sizeof(pessoas[0]));
    
    	if(arq == NULL)
    	{
    		printf("\nErro ao abrir o arquivo para leitura!\n");
    		fclose(arq);
    		return -1;
    	}
    	for(int i=0; i<len_vet; i++)
    	{
    		fwrite(&pessoas[i], sizeof(pessoa), 1, arq);
    	}
    	fclose(arq);
    	return 0;
    }
    
    
    int ler_arquivo(pessoa aux_pessoas[])
    {
    	FILE * arq = fopen("dados.bin", "rb");
    	if(arq == NULL)
    	{
    		printf("\nErro ao abrir o arquivo para leitura!\n");
    		return -1;
    	}
    	int indice = 0;
    	pessoa p;
    	while(fread(&p, sizeof(pessoa), 1, arq))
    	{
    		aux_pessoas[indice++] = p;
    	}
    	fclose(arq);
    	return indice;
    }
    
    int main(int argc, char *argv[])
    {
    	char oper;
    	int len_vet;
    	pessoa aux_pessoas[MAX];
    
    	while (oper != 's') 
    	{
    		printf("================ MENU ================ \n");
    		printf("Escolha: \ng - Para gravar\nl - para ler\ns - para sair\n");
    		scanf(" %c", &oper);
    		switch (oper) 
    		{
    			case 'g':
    				;
    				pessoa pessoas[] = {{"Luiz", 44}, {"Sofia", 11}, {"Daniele", 35}};
    				escrever_arquivo(pessoas);
    				break;
    			case 'l':
    				len_vet = ler_arquivo(aux_pessoas);
    				if(len_vet>0)
    				{
    					printf("=========================================\n");
    					for(int i=0; i<len_vet; i++)
    					{
    						printf("Nome: %s\n", aux_pessoas[i].nome);
    						printf("Idade: %d\n", aux_pessoas[i].idade);
    						printf("-----------------------------------------\n");
    					}
    				}
    				break;
    			case 's':
    				break;
    			default:
    				printf("opcao invalida!\n");
    				break;
    		}
    	}
    	return 0;
    }

     

    porque sempre tenho que adicionar ';' dentro do primeiro case?
     

    			case 'g':
    				; // <- aqui!
    				pessoa pessoas[] = {{"Luiz", 44}, {"Sofia", 11}, {"Daniele", 35}};

     

    • Curtir 1
  15. 8 minutos atrás, alexandre.mbm disse:

     

    É só uma forma de "disfarçar"...

     

    25 toneladas desse plástico seria mais caro do que 25 de toneladas de arroz

    Nossa! Mas isso seria uma jogada genial. Tem lógica sim!
    Eu tava imaginando que fosse alguém querendo lucrar, mesmo que fosse com a morte de alguém.

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

 

GRÁTIS: ebook Redes Wi-Fi – 2ª Edição

EBOOK GRÁTIS!

CLIQUE AQUI E BAIXE AGORA MESMO!