将字符数组解析为指针数组中的字(C编程)

时间:2014-10-08 20:40:38

标签: c arrays string parsing

我试图将每个单词与字符数组分开并将它们放入指针数组中,每个插槽一个字。另外,我应该使用isspace()来检测空白。但如果有更好的方法,我全都耳朵。在代码的最后我想打印出参数数组的内容。

让我们说这句话是:“这是一句话”。会发生的是它打印出“句子”(行中的最后一个单词,通常后跟一些随机字符)4次(单词数)。然后我得到“Segmentation fault(core dumped)”。

我哪里错了?

int split_line(char line[120])
{
    char *param[21]; // Here I want to put one word for each slot
    char buffer[120]; // Word buffer
    int i; // For characters in line
    int j = 0; // For param words   
    int k = 0; // For buffer chars

    for(i = 0; i < 120; i++)    
    {
        if(line[i] == '\0')
            break;
        else if(!isspace(line[i]))   
        {    
            buffer[k] = line[i];
            k++;    
        }    
        else if(isspace(line[i]))
        {
            buffer[k+1] = '\0';
            param[j] = buffer; // Puts word into pointer array   
            j++;    
            k = 0;    
        }   
        else if(j == 21)    
        {
            param[j] = NULL;    
            break;    
        }    
    }    

    i = 0;
    while(param[i] != NULL)    
    {    
        printf("%s\n", param[i]);    
        i++;    
    }    
    return 0;    
}

3 个答案:

答案 0 :(得分:3)

此代码中存在许多小问题:

  • param[j] = buffer; k = 0;:你在缓冲区开头重写,删除前面的单词
  • if(!isspace(line[i])) ... else if(isspace(line[i])) ... else ...isspace(line[i])或者为假,你总是使用2个首选,而不是第3个选择。
  • if (line[i] == '\0'):您忘记通过'\ 0'
  • 终止当前单词
  • 如果有多个空格,您当前(尝试)在param中添加空字

这是一个工作版本:

int split_line(char line[120])

{

    char *param[21]; // Here I want to put one word for each slot
    char buffer[120]; // Word buffer
    int i; // For characters in line
    int j = 0; // For param words
    int k = 0; // For buffer chars
    int inspace = 0;

    param[j] = buffer;

    for(i = 0; i < 120; i++) {
        if(line[i] == '\0') {
            param[j++][k] = '\0';
            param[j] = NULL;
            break;
        }
        else if(!isspace(line[i])) {
            inspace = 0;
            param[j][k++] = line[i];
        }
        else if (! inspace) {
            inspace = 1;
            param[j++][k] = '\0';
            param[j] = &(param[j-1][k+1]);
            k = 0;
            if(j == 21) {
                param[j] = NULL;
                break;
            }
        }
    }



    i = 0;

    while(param[i] != NULL)

    {

        printf("%s\n", param[i]);

        i++;

    }

    return 0;

}

我只修复了错误。作为练习,我为您留下了以下改进:

  • split_line例程不应该打印自己,而是返回一个单词数组 - 注意你不能返回一个自动数组,但这将是另一个问题
  • 你的代码中不应该有魔术常量(120),你应该至少有一个#define并使用符号常量,或者更好地接受任何大小的行 - 这里也不是很简单,因为你必须在适当的地方使用malloc和free,而且这将是一个不同的问题

无论如何,在学习那个好老C时好运: - )

答案 1 :(得分:1)

这条线对我来说似乎不对

param[j] = buffer;

因为您继续为不同的buffer分配相同的值param[j]

我建议您将char的所有line[120]复制到buffer[120],然后将param[j]指向buffer + Next_Word_Postition的位置。

答案 2 :(得分:0)

您可能需要查看strtok中的string.h。听起来这就是你要找的东西,因为它会根据你选择的分隔符分隔单词/标记。要用空格分隔,只需使用:

dest = strtok(src, " ");

其中src是源字符串,dest是源字符串上第一个标记的目标。循环直到dest == NULL将为您提供所有单独的单词,您所要做的就是每次根据指针数组更改dest。同样值得注意的是,为NULL参数传递src将继续从strtok停止的位置进行解析,因此在循环外的初始strtok之后,只需使用src = NULL里面。我希望有所帮助。祝你好运!