2

I'm learning C by myself and I'm trying to use my knowledge (i.e. no library use) to create a program that does the following:

  • Split a string into words (words are separated by spaces)
  • Put each word in an array

So, in the end, I must have an array of strings (an array of array of chars).

This is my code:

#include <stdio.h>

int main () {
int i, conta, indice_completo=0, indice_nome=0, indice_caractere=0;
char nome [90], nomevetor [30] [90];


scanf ("%[^\n]s", nome);

while (nome[indice_completo] != '\0') {
    while (nome[indice_completo] != ' ' && nome [indice_completo] != '\0') {
        nomevetor [indice_nome] [indice_caractere] = nome [indice_completo];
        indice_completo++;
        indice_caractere++;
    }
    nomevetor [indice_nome] [indice_caractere] = '\0';
    indice_caractere=0;
    indice_nome++;
}
conta=indice_nome;

for (i=0 ; i<conta; i++) {
    printf ("Nome %d: %s\n", i+1, nomevetor [i]);
}

return 0;
}

But when I compile it using:

gcc -ansi -Wall -g programa.c -o programa

I get segmentation fault.

  • Why did I get segmentation fault?
  • Is my algorithm correct?
  • Is there a better way to do what I want?
1
  • I've corrected your English a bit. Commented Nov 17, 2013 at 20:26

2 Answers 2

1

Your coding problem is that when you reach a blank in the input, you don't ever get past it.

Add a loop:

while (nome[indice_completo] == ' ')
    indice_completo++;

just before the end of the main loop.

Fixed code:

#include <stdio.h>

int main(void)
{
    int i, conta, indice_completo = 0, indice_nome = 0, indice_caractere = 0;
    char nome[90], nomevetor[30][90];


    scanf("%[^\n]s", nome);

    while (nome[indice_completo] != '\0')
    {
        while (nome[indice_completo] != ' ' && nome[indice_completo] != '\0')
        {
            nomevetor[indice_nome][indice_caractere] = nome[indice_completo];
            indice_completo++;
            indice_caractere++;
        }
        nomevetor[indice_nome][indice_caractere] = '\0';
        printf("Word: <<%s>>\n", nomevetor[indice_nome]);
        indice_caractere = 0;
        indice_nome++;
        while (nome[indice_completo] == ' ')
            indice_completo++;
    }
    conta = indice_nome;

    for (i = 0; i < conta; i++)
    {
        printf("Nome %d: %s\n", i+1, nomevetor[i]);
    }

    return 0;
}

Example run:

$ ./segfault
Arterial blockage I believe
Word: <<Arterial>>
Word: <<blockage>>
Word: <<I>>
Word: <<believe>>
Nome 1: Arterial
Nome 2: blockage
Nome 3: I
Nome 4: believe
$

(Only the program is now misnamed — it doesn't seg fault any more.)

You need to make sure nothing overflows the limits, too. Mainly, that would be using %89[^\n] in the format string, since you can't have more than 45 alternating non-blank and blank in a 90-character buffer.

If the input starts with a blank, the first 'word' will be empty. You could fix that by putting the 'skip' loop at the top of the main loop.

Sign up to request clarification or add additional context in comments.

Comments

1

Looks good overall, but when you detect a space, you still need to increment indice_completo otherwise you'll never get past it.

And then, you'l keep on incrementing indice_nome until you fall off the end of the array, hence the seg fault.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.