我想实现一个简单的单词计数程序,它将打开一个 文本文件,作为命令行参数提供,然后计算单词数, 该文本中的非字母单词(例如:1998,2-3等)句子和段落的数量 文件。假设两个空格之间的字符数组计为单词,非字母单词由数字,连字符等组成。每个句子都以'。'(点)字符结束,而段落则为 用换行符分隔。我将使用一个保持字数,非字母的结构 每个段落的字数,句子数和起始行如下:
struct {
int word;
int sentence;
int nonAlpha;
int startingLine;
struct Paragraph*next;
}Paragraph;
我决定使用链接列表。那么我应该知道并学习将使用多少段并初始化链表,链接它们,或者只是在从文件读取新段落并且需要存储在结构中时继续分配?
Paragraph->next=(struct Paragraph*) calloc(1,sizeof(struct Paragraph));
感谢您的帮助。
答案 0 :(得分:2)
如何在不给出SIZE的情况下动态分配它?
在不知道大小的情况下,无法分配连续的数组。
我会给你一些选择:
使用malloc
在大型块中预分配并复制到其中。如果您在阅读文件realloc
较大的块时耗尽了大小。
首先计算文件中的单词数量malloc
,然后再次读取该文件。
使用链接列表结构。每个单词malloc
,并指向下一个单词。
答案 1 :(得分:1)
struct Paragraph *dynamicParagraph = malloc(SIZE * sizeof(Paragraph));
因为在C / C ++中,数组和指针基本相同,所以可以将它用作数组:
Paragraph specificParagraph = dynamicParagraph[index]; //Assuming index < SIZE and > 0
答案 2 :(得分:0)
根据您的说明,您希望每个段落有一个struct
个实例。因此,每次遇到换行符时,都要开始新的段落计数。
首先动态分配初始数量的Paragraph
个对象(足以覆盖大多数情况),然后根据需要扩展该块:
#define INITIAL_SIZE ... // some initial value, say 5 or 10
...
size_t numParas = 0; // keep track of the array size
size_t parasRead = 0; // keep track of the paragraphs read
...
struct Paragraph *paras = malloc(sizeof *paras * INITIAL_SIZE);
if (paras)
{
numParas = INITIAL_SIZE;
}
else
{
perror("Could not allocate initial memory...exiting");
exit(-1);
}
... // open the file and read input
while (more_data)
{
int c = fgetc(input);
// update the various fields of paras[parasRead]
// based on the value of current_character
if (c == '\n')
{
// ready to start a new paragraph. If we've reached the end
// of the paras array and don't have a new slot available,
// extend the array by doubling its size
if (parasRead + 1 == numParas)
{
struct Paragraph *tmp = realloc(paras, sizeof *paras * (numParas * 2));
if (tmp)
{
paras = tmp;
numParas *= 2;
}
else
{
perror("Could not extend the paras array...exiting");
free(paras);
exit(-1);
}
}
parasRead++;
moreData = (c != EOF);
}
}
// display results
...
free(paras);
至少应该让你开始。如果realloc
无法扩展缓冲区,则必须决定该怎么做。在上面的示例代码中,我将其视为致命错误并立即退出,但您可以尝试将缓冲区扩展较小的量(而不是加倍,将其增加1.5倍,如果失败则增加1.25倍等) 。您可以决定退出循环并显示您的结果。或者完全不同的东西。
也可能有更好的方法来组织这个;最好将阵列管理代码分离到一个单独的函数中。但这应该会让你了解所需要的东西。
答案 3 :(得分:0)
使用链接列表而不是数组。在这种情况下,您只需要在需要时分配新成员。