Uma cadeia de caracteres é uma seqüência finita de caracteres. Na linguagem C, uma cadeia de caracteres, ou string, é um vetor (= array) de caracteres em que o caracter nulo ('\0') é interpretado como marca de fim-de-cadeia. Exemplo:
char s[20]; s[0] = 'E'; s[1] = 'X'; s[2] = 'E'; s[3] = 'M'; s[4] = 'P'; s[5] = 'L'; s[6] = 'O'; s[7] = '\0'; s[8] = 'S';
Depois da execução desse fragmento de código, o vetor s contém a cadeia de caracteres "EXEMPLO". O caracter nulo marca o fim dessa cadeia. A porção s[8..19] do vetor é ignorada.
Eis um exemplo familiar: o primeiro argumento das funções printf e scanf é uma string constante:
scanf ("%d", &n); printf ("O valor de n é %d", n);
O mesmo efeito do exemplo que abriu esta seção é produzido pelo fragmento de código
char s[20]; strcpy (s, "EXEMPLO");
onde strcpy é uma função que será discutida na próxima seção. O segundo argumento de strcpy no exemplo é uma string constante. Note que strings constantes são indicadas por aspas duplas (e o caracter nulo final é subentendido).
Toda string é representada pelo endereço do seu primeiro caracter, como acontece com qualquer vetor. Assim, a variável s no exemplo acima é do tipo char * (mas dizemos, informalmente, que s é uma string).
Um efeito semelhante ao do exemplo que abriu esta seção é produzido por
char *s; s = "EXEMPLO";
[Mas char s[20]; s = "EXEMPLO"; não está correto, por razões que não quero explicar agora.]
A função abaixo conta o número de vogais em uma string. [Inspirada na aula 12 da edição 2003 de MAC0110.] A função conta apenas as vogais não-acentuadas, mas é muito fácil modificar o código para que todas as vogais sejam contadas.
/* Devolve o número de vogais na string s. */
int contaVogais (char s[]) {
char *vogais;
int numVogais, i;
vogais = "aeiouAEIOU";
numVogais = 0;
for (i = 0; s[i] != '\0'; i++) {
char ch;
int j;
ch = s[i];
for (j = 0; vogais[j] != '\0'; j++) {
if (vogais[j] == ch) {
numVogais += 1;
break;
}
}
}
return numVogais;
}
A biblioteca-padrão string da linguagem C contém várias funções de manipulação de cadeias de caracteres. Para usar essas funções, o seu programa deve incluir o arquivo-interface string.h:
#include <string.h>
No que segue, as cadeia de caracteres serão tratadas como um novo tipo-de-dados:
typedef char *string;
1. A função strlen, cujo nome é uma abreviatura de string length, recebe uma string e devolve o seu comprimento. O comprimento (= length) de uma string é o seu número de caracteres, sem contar o caracter nulo final. O código dessa função poderia ser escrito assim:
int strlen (string s) { int i; for (i = 0; s[i] != '\0'; i++) ; return i; }
(Na verdade, o código acima está ligeiramente incorreto, pois strlen devolve um unsigned int.)
2. A função strcpy, cujo nome é uma abreviatura de string copy, recebe duas strings e copia a segunda (inclusive o caracter nulo final) para o espaço ocupado para a primeira. O conteúdo original da primeira string é perdido. Antes de chamar a função, o programador deve certificar-se de que o espaço alocado à primeira string é suficiente para acomodar a cópia da segunda string. O código dessa função poderia ser escrito assim:
void strcpy (string s, string t) { int i; i = 0; while (t[i] != '\0') { s[i] = t[i]; i += 1; } s[i] = '\0'; }
(Na verdade, o código acima está ligeiramente incorreto, pois a função devolve o endereço da primeira string. Mas os usuários da função usualmente só estão interessados no efeito da função e não n'o que ela devolve.)
3. A função strcmp, cujo nome é uma abreviatura de string compare, recebe duas strings e compara as duas lexicograficamente. Ela devolve um número negativo se a primeira string for lexicograficamente menor que a segunda, devolve 0 se as duas strings são iguais e devolve um número positivo se a primeira string for lexicograficamente maior que a segunda. O código dessa função poderia ser escrito assim:
int strcmp (string s, string t) { int i; for (i = 0; s[i] == t[i]; i++) if (s[i] == '\0') return 0; return s[i] - t[i]; }
Convém lembrar que o valor da expressão
s[i] - t[i]
é calculado como se ela fosse
(int)
(unsigned char)
s[i] -
(int) (unsigned char) t[i].
A ordem lexicográfica entre strings é análoga à ordem das palavras em um dicionário. Ela se baseia na ordenação dos caracteres estabelecida na tabela ISO8859-1, da mesma forma que a ordem das palavras em um dicionário se baseia na ordenação das letras no alfabeto. Para comparar duas strings s e t, procura-se a primeira posição, digamos k, em que as duas strings diferem. Se s[k] vem antes de t[k] na tabela ISO então s é lexicograficamente menor que t.
char a[], b[]; strcpy (a, "cenoura"); strcpy (b, "cereja"); if (a < b) printf ("%s precede %s no dicionário", a, b);