Ir para o conteúdo
  • Revista PROGRAMAR: Já está disponível a edição #60 da revista programar. Faz já o download aqui!

Localhost

Implementação de funções da biblioteca standard de C

Mensagens Recomendadas

Localhost

Olá pessoal. Bem vou começar aqui a fazer umas séries de códigos de funções conhecidas. Vou começar com a função strlen:

#include <stdio.h>

int StrLen(char *wanted_s){
   int s_count=0;
   while(*wanted_s != '\0'){
      s_count++;
      wanted_s++;
   }
   return s_count;
}

int main(void){
   char s_ex[100] = "example";
   int len;
   len = StrLen(s_ex);
   printf("String lenght: %d\n", len);
   return 0;
}


here since 2009

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
Localhost

Mais uma função aí. A Puts, a maneira como pûs o \n no final é um bocado estúpida  :confused:

#include <stdio.h>

int Puts(const char *);

int main(void){
   char s_put[100] = "example";
   Puts(s_put);
   return(0);
}

int Puts(const char *s_wanted){
   while(*s_wanted != '\0'){
      putchar(*s_wanted);
      s_wanted++;
   }
      putchar('\n');
      return 1;
}


here since 2009

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
KiNgPiTo

Não querendo menosprezar o teu trabalho (que vejo que tem sido bastante e bom) mas:

- Em vez de mostrares o código das funções que bibliotecas do C já traz, porque não dares exemplos de como as utilizares e chamares a respectiva biblioteca?

- Podias pôr na Wiki estes artigos e criares um tópico onde adicionasses uma mensagem sempre que adicionasses uma nova para alertar o pessoal...

Cumprimentos

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
Localhost

A primeira parte do teu post não percebi bem o que querias dizer :s

Quanto à segunda parte eu já mandei uma MP ao administrador Rui Carlos e estou a aguardar uma resposta para que possa meter tudo isto na wiki. O problema desse tópico que falas é que se não fosse fixo acabaria por se perder pelo forúm e ninguém poderia encontrar os artigos...

EDIT: O que eu queria mostrar aqui era também a passagem de ponteiros para strings para parametros de funções. Eu não fui buscar o código a lado nenhum, fui eu que o fiz de maneira a dar uma ideia de como trabalham as funções e como já disse os ponteiros.


here since 2009

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
scorch

1º Podes escrever na Wiki como quiseres, não precisas de permissão nem nada que se pareça.

2º Se tu, sempre que postasses uma nova função, postasses no fim do tópico também a dizer: Uma nova função ou algo do género, o tópico voltaria para a primeira página do quadro.

EDIT: Porque é que fazes a verificação, se uma vez que 1 é sempre igual a 1, estás a gastar tempo de processamento.


scorch_pp.png

PS: Não respondo a perguntas por mensagem que podem ser respondidas no fórum.

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
Localhost

1- Ok, mas não sei como se faz xD

2- Sim, isso eu percebo, o problema é que o intervalo entre postar uma coisa nova o tópico já se tinha perdido, e durante esse tempo ninguém podia ver.

Quanto à verificação, se reparares se eu não fizesse a verificação das duas uma, ou eu não punha o \n ou então punha-o só que ficava depois do terminador nulo ou seja, não era contado na mesma. 


here since 2009

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
Localhost

Bem, desenvolvi uma função parecida com a strcpy só que esta tem a pequena mas grande diferença de ser segura. O que ela faz é que se o array de caracteres que a vai receber for de menor capacidade do que aqueles que vão ser copiados ela pára. No exemplo eu pûs um caso em que ela pára. Ela tem os seguintes parámetros: s_copy(string_destino, string_origem, numero_de_caracteres_suportados_pela_string_destino). Espero que usem esta função  B)

#include <stdio.h>
#include <string.h>

int s_copy(char *, char *, int);

int main(void){
char str1[10] = "ola";
char str2[20] = "AAAAAAAAAAAAAAAAA";
s_copy(str1,str2,10);
printf("%s\n", str1);
return 0;
} 

int s_copy(char *s_1, char *s_2, int len){
int s_len = strlen(s_2);
if(s_len > len){
	printf("Função parada, perigo de buffer overflow\n");
	return(0);
}
while(*s_2 != '\0'){
	*s_1 = *s_2;
	s_1++;
	s_2++;
}
        *s_2 = '\0';
return(0);
}


here since 2009

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
Localhost

Sim, eu sei, aquilo só foi mesmo para se perceber! Eu podia tirar o printf e pronto. Quanto à função, eu já conhecia mas não existia outra?

Obrigado pela opinião  B)


here since 2009

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
mogers

Visto que a verificação é feita através do parâmetro da função, não vejo grande melhoria na segurança. Como é o programador a preencher esse campo, penso que ele continua com a mesma responsabilidade de quando usa o strcpy.

Tens um errozito. Falta-te colocar o \0 no final da string de destino, caso contrário acontece algo como

char str1[10] = "ola";

char str2[20] = "AA";

...

output: "AAa"


"What we do for ourselves dies with us. What we do for others and the world, remains and is immortal.", Albert Pine

Blog pessoal : contém alguns puzzles, algoritmos e problemas para se resolver com programação.

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
mogers

Quanto à verificação, se reparares se eu não fizesse a verificação das duas uma, ou eu não punha o \n ou então punha-o só que ficava depois do terminador nulo ou seja, não era contado na mesma. 

Penso que o que o Scorch quis dizer é que o que tens é equivalente a

int Puts(const char *s_wanted){
   while(*s_wanted != '\0'){
      putchar(*s_wanted);
      s_wanted++;
   }
   putchar('\n');
   return 1;
}

O if não está ali a fazer nada porque a condição é sempre verdadeira.

PS: não percebi o que querias dizer com "então punha-o só que ficava depois do terminador nulo ou seja, não era contado na mesma.  "


"What we do for ourselves dies with us. What we do for others and the world, remains and is immortal.", Albert Pine

Blog pessoal : contém alguns puzzles, algoritmos e problemas para se resolver com programação.

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
Localhost

Não porque repara, se fosse copiado por exemplo um argumento de linha de comandos... Se fosse com a strcpy normal o que aconteceria era que ele não ia verificar, assim ele verifica. E é obvio que é o programador que tem de definir o tamanho disponivel na string que vai receber.

Quanto ao erro, penso que não está errado porque ele vai copiar para a string todos os caracteres inclusive o nulo... Mas posso estar errado.

Amanhã vou escrever alguma coisa sobre buffer overflow visto que estamos a falar nisso. Abraço  B)


here since 2009

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
mogers

Não porque repara, se fosse copiado por exemplo um argumento de linha de comandos... Se fosse com a strcpy normal o que aconteceria era que ele não ia verificar, assim ele verifica. E é obvio que é o programador que tem de definir o tamanho disponivel na string que vai receber.

O meu ponto de vista é como a função depende desse len, se este parâmetro tiver um valor errado (que poderia ser propositado para provocar erros), a função continua a comportar-se tal e qual o strcpy.

Eu penso que esse if deve ser feito fora da função (antes desta ser invocada), num local onde o programador sabe qual é o tamanho da string de destino.

Quanto ao erro, penso que não está errado porque ele vai copiar para a string todos os caracteres inclusive o nulo... Mas posso estar errado.

Basta experimentares o exemplo que dei para comprovares que o nulo não é copiado B)


"What we do for ourselves dies with us. What we do for others and the world, remains and is immortal.", Albert Pine

Blog pessoal : contém alguns puzzles, algoritmos e problemas para se resolver com programação.

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
_deXter

Sinceramente, não estou a par dos standarts, mas em funções do mesmo tipo que esta, geralmente, o valor de retorno 0 significa sucesso. Neste caso estás a fazer ao contrário, 0 para insucesso e 1 para sucesso.

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
Localhost

Dexter, pelo que sei no ansi C 0 significa falso e 1 verdadeiro, não sei se aplica também às funções, eu segui esse standard.

Mogers, não tou a perceber muito bem o que queres dizer. O valor não pode ser mudado. Tenta aplicar a minha função com argumentos de linha de comando, ele vai parar se o argumento que passares for muito grande. A minha função trabalha exactamente da mesma forma da strncpy, ela também pede o número de elementos que a string destino pode comportar. A minha função verifica se o número é maior. Testa de todas as maneiras...

Quanto ao erro eu vou corrigir, claro, eu não tinha prestado atenção, fiz num while, ele quando vê que é igual a \0 nem entra.


here since 2009

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
Localhost

Atenção que eu me enganei, não se pode utilizar strlen para chamar a função no último parametro, tem de se utilizar mesmo um numero, já corrigi.


here since 2009

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
_deXter

Dexter, pelo que sei no ansi C 0 significa falso e 1 verdadeiro, não sei se aplica também às funções, eu segui esse standard.

Certo, no entanto, quanto a valores de retorno a coisa não funciona dessa forma. Caso contrário, porque retornas 0 então na função main? B)

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
mogers

Dexter, pelo que sei no ansi C 0 significa falso e 1 verdadeiro

Sim, mas a convenção aplicada nos valores de retorno de funções deste género não é essa. Como existem diferentes razões que podem causar um erro, normalmente é usado o 0 para indicar que não houve erros e um valor diferente de 0 que indica o código do erro que ocorreu. Repara que a tua função main retorna 0, seguindo este esquema.

Mogers, não tou a perceber muito bem o que queres dizer. O valor não pode ser mudado. Tenta aplicar a minha função com argumentos de linha de comando, ele vai parar se o argumento que passares for muito grande.

O que eu quero dizer é que:

  • O strcpy assume que a string de destino é suficientemente grande para ser uma copia da string de origem
  • A tua função assume que o parâmetro len é o tamanho real da string de origem

Ou seja, na tua função, estás dependente da correcção do parâmetro len. Se houver um erro neste parâmetro, a função pode aceder a memória inválida tal como o strcpy.

No fundo, acho que não é mais segura do que o strcpy.

A minha função trabalha exactamente da mesma forma da strncpy, ela também pede o número de elementos que a string destino pode comportar. A minha função verifica se o número é maior. Testa de todas as maneiras...

Cudado que a função strncmp não faz isso. Esta função copia os primeiros n caracteres de uma string para outra.

Copies the first num characters of source to destination. If the end of the source C string (which is signaled by a null-character) is found before num characters have been copied, destination is padded with zeros until a total of num characters have been written to it.

edit: parece que demorei muito tempo a escrever o post B)


"What we do for ourselves dies with us. What we do for others and the world, remains and is immortal.", Albert Pine

Blog pessoal : contém alguns puzzles, algoritmos e problemas para se resolver com programação.

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
Localhost

Mas na realidade tudo depende do programador. Mas qual é o programador que se vai enganar a ler o número de caracteres de um array? Mas a pensar assim, e não tenho a certeza do que vou dizer a função fgets também não é mais segura do que a gets porque se te enganares e puseres caracteres a mais no numero que pode suportar a diferença entre o que pode suportar e o que puseste vai dar a mais...


here since 2009

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
Localhost

Experimenta este código aí na tua máquina:

#include <stdio.h>

int main(void){
char str[8];
fgets(str,20,stdin);
return 0;
}


here since 2009

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
mogers

É uma boa analogia, mas penso que a situação do gets/fgets é um pouco diferente. Aí não sabes o tamanho "do que vem aí", enquanto que no strcpy sabes aquilo que queres copiar.

De qualquer forma, para mim, o ponto mais importante é

Eu penso que esse if deve ser feito fora da função (antes desta ser invocada), num local onde o programador sabe qual é o tamanho da string de destino.


"What we do for ourselves dies with us. What we do for others and the world, remains and is immortal.", Albert Pine

Blog pessoal : contém alguns puzzles, algoritmos e problemas para se resolver com programação.

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
Localhost

Não sei o tamanho do que vem? Eu só tenho de definir o qual o tamanho do vector mais nada... E a situação do fgets é exactamente a mesma coisa pois se errares no tamanho também é igual à gets, é uma coisa tão pouco provável de se errar que nem se nota.


here since 2009

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites

Crie uma conta ou ligue-se para comentar

Só membros podem comentar

Criar nova conta

Registe para ter uma conta na nossa comunidade. É fácil!

Registar nova conta

Entra

Já tem conta? Inicie sessão aqui.

Entrar Agora

×

Aviso Sobre Cookies

Ao usar este site você aceita os nossos Termos de Uso e Política de Privacidade. Este site usa cookies para disponibilizar funcionalidades personalizadas. Para mais informações visite esta página.