Como ler uma string do teclado usando C? recebendo falha de segmentação passando em char *

Eu quero ler uma string digitada pelo usuário. Eu não sei o comprimento da string. Como não há sequências no IC declarado um ponteiro:

char * word; 

e usei scanf para ler a input do teclado:

 scanf("%s" , word) ; 

mas eu tenho uma falha de segmentação.

Como posso ler a input do teclado em C quando o comprimento é desconhecido?

Você não tem armazenamento alocado para a word – é apenas um ponteiro pendente .

Mudança:

 char * word; 

para:

 char word[256]; 

Observe que 256 é uma escolha arbitrária aqui – o tamanho desse buffer precisa ser maior que a maior cadeia possível que você pode encontrar.

Note também que fgets é uma opção melhor (mais segura) que scanf para leitura de strings de tamanho arbitrário, em que é necessário um argumento de size , que por sua vez ajuda a evitar overflows de buffer:

  fgets(word, sizeof(word), stdin); 

Não consigo ver por que há uma recomendação para usar o scanf() aqui. scanf() é seguro somente se você adicionar parâmetros de restrição à string de formato – como %64s ou mais.

Uma maneira muito melhor é usar char * fgets ( char * str, int num, FILE * stream ); .

 int main() { char data[64]; if (fgets(data, sizeof data, stdin)) { // input has worked, do something with data } } 

(não testado)

Ao ler a input de qualquer arquivo (stdin incluído) onde você não sabe o comprimento, geralmente é melhor usar o getline vez de scanf ou fgets porque o getline manipulará a alocação de memory para sua string automaticamente desde que você forneça um ponteiro nulo para receber a string digitada. Este exemplo irá ilustrar:

 #include  #include  int main (int argc, char *argv[]) { char *line = NULL; /* forces getline to allocate with malloc */ size_t len = 0; /* ignored when line = NULL */ ssize_t read; printf ("\nEnter string below [ctrl + d] to quit\n"); while ((read = getline(&line, &len, stdin)) != -1) { if (read > 0) printf ("\n read %zd chars from stdin, allocated %zd bytes for line : %s\n", read, len, line); printf ("Enter string below [ctrl + d] to quit\n"); } free (line); /* free memory allocated by getline */ return 0; } 

As partes relevantes são:

 char *line = NULL; /* forces getline to allocate with malloc */ size_t len = 0; /* ignored when line = NULL */ /* snip */ read = getline (&line, &len, stdin); 

Definir a line como NULL faz com que o getline aloque a memory automaticamente. Exemplo de saída:

 $ ./getline_example Enter string below [ctrl + d] to quit A short string to test getline! read 32 chars from stdin, allocated 120 bytes for line : A short string to test getline! Enter string below [ctrl + d] to quit A little bit longer string to show that getline will allocated again without resetting line = NULL read 99 chars from stdin, allocated 120 bytes for line : A little bit longer string to show that getline will allocated again without resetting line = NULL Enter string below [ctrl + d] to quit 

Portanto, com o getline você não precisa adivinhar quanto tempo a string do seu usuário será.

 #include int main() { char str[100]; scanf("%[^\n]s",str); printf("%s",str); return 0; } 

input: leia a string
saída: imprima a string

Este código imprime a seqüência de caracteres com lacunas, conforme mostrado acima.

Você precisa ter o ponteiro para apontar em algum lugar para usá-lo.

Experimente este código:

 char word[64]; scanf("%s", word); 

Isso cria uma matriz de caracteres de lenth 64 e lê a input para ele. Observe que, se a input tiver mais de 64 bytes, a matriz de palavras estourará e seu programa não será confiável.

Como Jens apontou, seria melhor não usar o scanf para ler strings. Esta seria uma solução segura.

 char word[64] fgets(word, 63, stdin); word[63] = 0;