如何将每个句子存储为数组的元素?

时间:2016-11-17 20:56:08

标签: c arrays string

所以,假设我有一个数组(程序要求我写一些文本):

char sentences[] = "The first sentence.The second sentence.The third sentence";

我需要将每个句子存储为数组,我可以访问任何单词,或者将句子存储在单个数组中作为元素。 (句子[0] =“第一句话”;句子[1] =“第二句”;)

如何分别打印出每个句子我知道:

char* sentence_1 = strtok(sentences, ".");
char* sentence_2 = strtok(NULL, ".");
char* sentence_3 = strtok(NULL, ".");

printf("#1 %s\n", sentence_1);
printf("#2 %s\n", sentence_2);
printf("#3 %s\n", sentence_3);

但是如何让程序将这些句子存储在1或3个数组中我不知道。 请帮助!

1 个答案:

答案 0 :(得分:3)

如果您将其保留在main中,因为您的sentences内存是静态的(无法删除),您只需执行此操作:

#include <string.h>
#include <stdio.h>

int main()
{
  char sentences[] = "The first sentence.The second sentence.The third sentence";
  char* sentence[3];
  unsigned int i;

  sentence[0] = strtok(sentences, ".");

  for (i=1;i<sizeof(sentence)/sizeof(sentence[0]);i++)
  {
    sentence[i] = strtok(NULL, ".");
  }

  for (i=0;i<sizeof(sentence)/sizeof(sentence[0]);i++)
  {
    printf("%d: %s\n",i,sentence[i]);
  }

  return 0;

}

在一般情况下,首先必须复制输入字符串:

char *sentences_dup = strdup(sentences);
sentence[0] = strtok(sentences_dup, ".");

原因很多:

  • 你不知道输入的生命周期/范围,它通常是指针/参数,因此只要输入内存被释放/超出范围,你的句子就会无效
  • 传递的缓冲区可能是const:您无法修改其内存(strtok修改传递的缓冲区)
  • 在上面的示例中按sentences[]更改*sentences并且您指向只读区域:您必须复制缓冲区。

不要忘记存储重复的指针,因为您可能需要在某个时候释放它。 另一种选择是在那里复制:

  for (i=1;i<sizeof(sentence)/sizeof(sentence[0]);i++)
  {
    sentence[i] = strdup(strtok(NULL, "."));
  }

所以你可以立刻释放你的大标记化字符串,并且句子有自己独立的记忆。

编辑:这里剩下的问题是你还需要事先知道输入中有多少句话。

为此,您可以计算点数,然后分配适当数量的指针。

int j,nb_dots=0;
char pathsep = '.';
int nb_sentences;
int len = strlen(sentences);
char** sentence;

// first count how many dots we have
for (j=0;j<len;j++)
{
    if (sentences[j]==pathsep)
    {
        nb_dots++;
    }       
}
nb_sentences = nb_dots+1; // one more!!
// allocate the array of strings
sentence=malloc((nb_sentences) * sizeof(*sentence));

现在我们有了多少个字符串,我们可以执行strtok循环。由于数组类型的更改,请注意使用nb_sentences而不是sizeof(sentence)/sizeof(sentence[0])现在不相关(值1)。

但此时你也可以像answer of mine

中提出的那样完全摆脱strtok