entering Posted May 23, 2006 at 05:31 PM Report #29142 Posted May 23, 2006 at 05:31 PM Introdução Uma string é um conjunto de caracteres armazenados num vector. As strings são representadas utilizando aspas enquanto os caracteres entre plicas. Poderemos pensar que C é fraco no tratamento de strings visto que strings não é tipo básico da linguagem e única forma de representar um conjunto de caracteres é recorrendo a um vector. Por exemplo não podemos fazer: uma atribuiçao s1="OLA"; (apenas podemos fazer isto na declaração); compará-las s1=="OLA"; concatenar. No entanto C possui uma poderosa biblioteca de funções que permite realizar estas tarefas e muito mais, e se por acaso não encontrarmos nenhuma função que faça o que queremos podemos sempre fazer manipulação carácter a carácter e resolver o problema (algumas linguagens que tratam strings como um todo e não um conjunto de caracteres não o permitem). A declaração de strings obedece à sintaxe de declaração de vectores, sendo a primeira posição 0. Uma string termina no carácter \0. NOTA: Na declaração de uma string não se esqueça de 'guardar' espaço para o \0. Exemplo: char linha[101]; : Declaração de um vector que conterá uma string com 100 caracteres e um para o \0. Referi em cima que não é possível fazer uma atribuição deste estilo s1="OLA";. No entanto ao ser declarada pode ser atribuída uma string. Exemplo: char nome[]="OLA"; : Equivalente a char nome[3+1]="OLA";. Leitura e escrita se strings #include <stdio.h> int main (void) { char palavra[]="OLA"; printf("%s\n",palavra); puts(palavra); return 0; } *Nota a função puts após escrever uma string muda de linha, enquanto a função printf não (a função puts (put string) só permite a escrita de strings tal como o nome indica). #include <stdio.h> int main (void) { char s[20]; scanf("%s",s); printf("%s",s); return 0; } *Nota: não é precedida de um & ao contrário de outro tipo de variáveis (scanf). A função scanf lê todos os caracteres até encontrar um espaço ou enter, em seguida coloca o \0 (ou seja, só permite ler uma palavra). Cuidado ao usarem por causa de seg faults. $ ./a.out aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa Segmentation fault (core dumped) Isto porque o input ultrapassou os 20 caracteres, isto acontece quando um programa tenta aceder a memória que não lhe é destinada. A funçao gets (get string) permite colocar numa variável todos os caracteres introduzidos pelo utilizador (desde que dentro do limite), ou seja, não está limitada a leitura de uma única palavra como a função scanf. Sintaxe: gets(nome_da_var);. Tal como o scanf também tem o problema dos seg faults. Recomendo sempre o uso da função fgets! char *fgets(char *s, int n, FILE *stream); É retornado NULL se algum erro acontecer. Para ler do stdin (standard input): fgets(s, MAX-CARACTERES, stdin);. Atenção que ao contrário do scanf, que "suprime" o \n, o fgets não faz isso. Mais a frente iremos ver uma maneira simples de se necessário "retirar" o \n. Algumas funções para manipulação de strings, #include <string.h> strlen int strlen (char *s) Devolve o número de caracteres existentes numa string sem contar com o \0. #include <stdio.h> #include <string.h> int main (void) { char str[]="Olá Mundo"; printf ("%i\n",strlen(str)); return (0); } O código desta função seria algo deste género: #include <stdio.h> int strlen (char *s) { int i; for (i=0;s[i]!='\0';++i); return i; } strcpy char * strcpy ( char * dest, const char * src ); Esta função copia a string src para dest e retorna dest. #include <stdio.h> #include <string.h> int main (void) { char str[20]; printf ("%s\n",strcpy(str,"Olá Mundo")); return (0); } O código de strcpy poderá ser algo deste género: char *strcpy (char *dest, char *src) { int i=0; // Variável inicializada a 0 para apontar para a primeira posição while (dest[i]=src[i]) /* dest[i]=src[i] não é um teste de igualdade mas sim uma atribuição, como se trata de uma atribuição o carácter atribuído é devolvido, se for o carácter terminador sai do while */ ++i; return dest; } strcat char *strcat (char * dest, const char * src); Coloca a string src imediatamente a seguir ao final da string dest e retorna dest. #include <stdio.h> #include <string.h> int main (void) { char str[20]="Olá "; printf ("%s\n",strcat(str,"Mundo")); return (0); } O código da strcat poderá ser algo deste género: char *strcat (char *dest, char *src) { int i=0,len=strlen(dest); while (dest[len++]=src[i++]); return dest; } memset void * memset ( void * buffer, int c, size_t n ); Altera os primeiros n bytes de buffer pelo valor c. #include <stdio.h> #include <string.h> int main (void) { char str[]="Quase todos os programadores devem conheçer o memset."; memset (str,'-',5); puts (str); return (0); } $ ./a.out ----- todos os programadores devem conheçer o memset. memcpy void * memcpy ( void * dest, const void * src, size_t num ); Copia num bytes de src para dest. #include <stdio.h> #include <string.h> int main (void) { char str1[]="Ola ...",str2[5]; memcpy (str2,str1,3); puts (str2); return (0); } [Artigo no Wiki]
entering Posted May 23, 2006 at 05:31 PM Author Report #29143 Posted May 23, 2006 at 05:31 PM fico por aqui por hoje nos próximos dias continuo
TheDark Posted May 23, 2006 at 06:42 PM Report #29154 Posted May 23, 2006 at 06:42 PM Atenção que na strcpy os índices foram comidos. Desaparecido.
Warrior Posted May 23, 2006 at 09:05 PM Report #29205 Posted May 23, 2006 at 09:05 PM de facto deveria ser dest[ i ]=src[ i ] bons olhos TheDark :o
TheDark Posted May 23, 2006 at 09:54 PM Report #29223 Posted May 23, 2006 at 09:54 PM LOL Fizeste a mesma coisa. Cuidado com os [ i ], metam espaços la dentro ou metam em code 👍 Desaparecido.
entering Posted May 23, 2006 at 10:08 PM Author Report #29224 Posted May 23, 2006 at 10:08 PM corrigido
Warrior Posted May 24, 2006 at 08:05 PM Report #29368 Posted May 24, 2006 at 08:05 PM Pois, eu pensei que ele se tinha esquecido de os colocar, e não me lembrei que fosse devido ao BBCode :/
Rui Carlos Posted May 24, 2006 at 08:44 PM Report #29379 Posted May 24, 2006 at 08:44 PM uma função de manipulação de strings bastante útil e que não foi mencionada é a 'strdup' char* strdup(const char* str) esta função copia uma string, mas ao contrário da 'strcpy', não é necessário alocar espaço previamente... exemplo #include <stdio.h> #include <string.h> int main() { char str1[]="exemplo"; char* str2; str2=strdup(str1); puts(str2); free(str2); return 0; } caso quisesse usar a função 'strcpy' teria que declarar 'str2' como um array ou então alocar o espaço dinâmicamente (através de um 'calloc' ou algo parecido). quando usamos a função 'strdup' e deixamos de precisar da variável para onde foi copiada a string devemos libertar o espaço por ela ocupado com o 'free'. Rui Carlos Gonçalves
Gurzi Posted May 24, 2006 at 09:25 PM Report #29387 Posted May 24, 2006 at 09:25 PM Como moderador desta secção, peço que cada vez que façam referência a alguma função pré declarada, que exponham a sua constituição por favor.
entering Posted May 24, 2006 at 10:24 PM Author Report #29400 Posted May 24, 2006 at 10:24 PM ainda nao acabei de escrever sobre strings irei referir a strdup, já conheçia mas nem me tinha lembrado dela, mas tens razão bastante útil 👍
Knitter Posted May 26, 2006 at 02:11 PM Report #29598 Posted May 26, 2006 at 02:11 PM Ainda não tive tempo para ler tudo mas deixa-me fazer uma sugestão antes que me esqueça. Substitui : Uma string é um conjunto de caracteres armazenados num vector. Por: "Uma string é um vector de caracters terminados pelo caracater '\0'" Eu sei que dizes isso mais abaixo, mas titulos dão sempre impacto 😁, vou continuar a ler.... (...) Gostei, simples claro e eficaz. Tenho mais algumas sugestões, agora que acabei de ler 👍 , não me preocupei com erros de código, acho até que ao existirem ajudam muito quem quer aprender, claro desde que nãosejam em demasia.... 'segmentation fault' são, neste caso, o resultado de 'buffer overflows' que estão muito ligados ao uso de strings e que são muito dificeis de detectar, no entanto nem sempre uma escrita errada na memória provoca 'segmentation fault', por vezes um simples 'scanf' provoca comportamentos estranhos em toda a aplicação. O uso da função 'fgets' ajuda muito mas não elimina por completo o perigo de 'buffer overflow'. 'memset' embora muito útil é uma função perigosa, especialmente para quem começa B) Bem, concluíndo, está muito bom, fico à espera da continuação B)
CuotlX Posted June 5, 2008 at 03:43 PM Report #189648 Posted June 5, 2008 at 03:43 PM ja agora podem-me me responder se no caso de fgets para um string ele inclui o caracteres de terminação \0 ?
Rui Carlos Posted June 5, 2008 at 03:44 PM Report #189649 Posted June 5, 2008 at 03:44 PM ja agora podem-me me responder se no caso de fgets para um string ele inclui o caracteres de terminação \0 ? O '\0' tem que lá estar, senão não saberás onde termina a string. Rui Carlos Gonçalves
Aezrel Posted June 22, 2008 at 12:14 PM Report #192779 Posted June 22, 2008 at 12:14 PM Para ler do stdin (standard input) fgets (s,MAX-CARACTERES,stdin); Atenção que ao contrário do scanf que 'suprime' o \n o fgets não faz isso. Mais a frente iremos ver uma maneira simples de se necessário 'retirar' o \n pff alguem me pode explicar como faço isso? Precisava de saber com alguma urgência. Já ando com a cabeça nisto há algumas horas.
Hipnoted Posted June 22, 2008 at 12:47 PM Report #192785 Posted June 22, 2008 at 12:47 PM pff alguem me pode explicar como faço isso? Precisava de saber com alguma urgência. Já ando com a cabeça nisto há algumas horas. Uma maneira é: variavel[strlen(variavel)-1] = '\0'; "Nunca discutas com um idiota. Eles arrastam-te até ao seu nível e depois ganham-te em experiência"
Aezrel Posted June 22, 2008 at 03:01 PM Report #192828 Posted June 22, 2008 at 03:01 PM Obrigado, mas ainda assim continuo com um problema... estou a fazer o meu primeiro programa recorrendo a manipulação de ficheiros, ainda não domino muito bem essa área. mas pronto, o objectivo desta função é apenas receber um Username e uma password do utilizador e de seguida, ler as dados contidos no ficheiro .txt onde anteriormente "criou uma conta". depois disso compara as duas strings, para o caso de ele inserir um username ou password inválidas. posto aqui a função: login() { char username[25], username_file[25]; /*vector que recebe os dados lidos do ficheiro*/ int password, password_file; /*variavel que recebe os dados lidos do ficheiro*/ FILE *fp = fopen("base_dados.txt", "r"); printf("\t ||||||||||||||| |||||||||||||| ||||||||||||||||\n"); printf("\t |||||||||||||||| ||||||||||||||| ||||||||||||||||\n"); printf("\t |||| |||| |||| |||| |||||\n"); printf("\t |||| |||| |||| ||||| |||||\n"); printf("\t |||||||||||||| |||||||||||||| ||||||||||\n"); printf("\t |||||||||||||| ||||||||||||| ||||||||||\n"); printf("\t ||||||||||||||| ||||||||||| ||||||||\n"); printf("\t |||| |||||| ||||| |||||\n"); printf("\t |||| ||||| ||||| |||||\n"); printf("\t ||||||||||||||| ||||| |||||\n"); printf("\t |||||||||||||| ||||| |||||\n"); printf("\t\t\t<Banco de Planeamento Financeiro>\n"); do { while(getchar()!='\n'); //limpar o buffer puts("Nome de Utilizador: "); gets(username); //recebe o Username do utilizador puts("Password: "); scanf("%d", &password); // recebe a password do utilizador fgets(username_file,MAX_LINHA,fp); // le o nome de utilizador do ficheiro fscanf(fp, "%d", &password_file); // le a password do ficheiro username_file[strlen(username_file)-1] = '\0'; if(username != username_file || password != password_file) // comparação das strings printf("Nome de Usuario/Password Invalidos. Pff volte a inserir:\n"); else printf("Login efectuado com sucesso! Dentro de breves instantes sera redireccionado..."); } while (username_file != username || password_file != password); fclose(fp); Sleep(2500); } o problema, é que na altura de comparaçao das strings de Usernames, dá inválido! já confirmei e é mesmo das strings pois as passwords estao a funcionar. acredito que hajam maneiras mais fáceis e mais eficazes de efectuar a mesma coisa que isto...se puderem dar uma ajudinha ... 😛
Baderous Posted June 22, 2008 at 03:12 PM Report #192833 Posted June 22, 2008 at 03:12 PM A comparação de strings faz-se através da função strcmp. http://www.cplusplus.com/reference/clibrary/cstring/strcmp.html
Aezrel Posted June 22, 2008 at 04:37 PM Report #192854 Posted June 22, 2008 at 04:37 PM agradecido! 😛 :P já está a funcionar! 😛
anolsi Posted July 11, 2008 at 09:07 PM Report #197656 Posted July 11, 2008 at 09:07 PM Tutorial no Wiki em http://wiki.portugal-a-programar.pt/dev_geral:c:strings. Está a aberto às mais diversas colaborações, de modo a tornar-se mais completa. "Nós somos o que fazemos repetidamente, a excelência não é um feito, e sim, um hábito."Não respondo a questões por PM que possam ser colocadas no fórum!
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now