用于分隔字符串的算法中的分段错误

时间:2013-11-17 20:23:04

标签: c string algorithm gcc split

我正在自学C语言,并且我正在尝试使用我的知识(即没有使用库)来创建执行以下操作的程序:

  • 将字符串拆分为单词(单词用空格分隔)
  • 将每个单词放在数组中

所以,最后,我必须有一个字符串数组(一组字符数组)。

这是我的代码:

#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;
}

但是当我使用:

编译它时
gcc -ansi -Wall -g programa.c -o programa

我得到了分段错误。

  • 为什么我会出现分段错误?
  • 我的算法是否正确?
  • 有没有更好的方法来做我想要的事情?

2 个答案:

答案 0 :(得分:1)

整体看起来不错,但是当您检测到空格时,仍然需要增加indice_completo,否则您将永远不会超过它。

然后,你继续递增indice_nome直到你从数组的末尾掉落,因此seg错误。

答案 1 :(得分:1)

您的编码问题是当您在输入中找到空白时,您永远不会超越它。

添加循环:

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

在主循环结束之前。

固定代码:

#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;
}

示例运行:

$ ./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
$

(现在只有程序被错误命名 - 它不会再出现故障。)

你需要确保没有任何东西溢出限制。主要是,在格式字符串中使用%89[^\n],因为在90个字符的缓冲区中,不能有超过45个交替的非空白和空白。

如果输入以空白开头,则第一个“单词”将为空。你可以通过将'skip'循环放在主循环的顶部来解决这个问题。