Jump to content

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


Localhost

Recommended Posts

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

Link to comment
Share on other sites

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

#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

Link to comment
Share on other sites

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

Link to comment
Share on other sites

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

Link to comment
Share on other sites

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.

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

Link to comment
Share on other sites

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

Link to comment
Share on other sites

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

Link to comment
Share on other sites

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.

Link to comment
Share on other sites

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.

Link to comment
Share on other sites

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

Link to comment
Share on other sites

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.

Link to comment
Share on other sites

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

Link to comment
Share on other sites

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.

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...

Important Information

By using this site you accept our Terms of Use and Privacy Policy. We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.