0

我在使用结构数组时遇到问题。我需要逐行读取文本文件,并并排比较这些值。例如“妈妈”会返回 2 ma , 1 am 因为你有妈妈。我有一个结构:

typedef struct{
    char first, second;
    int count;
} pair;

我需要为整个字符串创建一个结构数组,然后比较这些结构。我们还介绍了内存分配,因此我们必须为任何大小的文件执行此操作。这就是我真正遇到麻烦的地方。如何为结构数组正确重新分配内存?这是我现在的主要内容(不编译,有错误显然有问题)。

int main(int argc, char *argv[]){
//allocate memory for struct
pair *p = (pair*) malloc(sizeof(pair));
//if memory allocated
if(p != NULL){
    //Attempt to open io files
    for(int i = 1; i<= argc; i++){
        FILE * fileIn = fopen(argv[i],"r");
        if(fileIn != NULL){
            //Read in file to string
            char lineString[137];
            while(fgets(lineString,137,fileIn) != NULL){
                //Need to reallocate here, sizeof returning error on following line
                //having trouble seeing how much memory I need
                pair *realloc(pair *p, sizeof(pair)+strlen(linestring));
                int structPos = 0;
                for(i = 0; i<strlen(lineString)-1; i++){
                    for(int j = 1; j<strlen(lineSTring);j++){
                        p[structPos]->first = lineString[i];
                        p[structPos]->last = lineString[j];
                        structPos++;
                    }
                }
            }
        }
    }
}
else{
    printf("pair pointer length is null\n");
}

}

如果有更好的方法,我很乐意改变事情。我必须使用上述结构,必须有一个结构数组,并且必须使用内存分配。这些是唯一的限制。

4

2 回答 2

3

为结构数组分配内存就像为一个结构分配内存一样简单:

pair *array = malloc(sizeof(pair) * count);

然后您可以通过订阅“数组”来访问每个项目:

array[0] => first item
array[1] => second item
etc

关于 realloc 部分,而不是:

pair *realloc(pair *p, sizeof(pair)+strlen(linestring));

(这在语法上无效,看起来像是 realloc 函数原型及其同时调用的混合),您应该使用:

p=realloc(p,[new size]);

实际上,您应该使用不同的变量来存储 realloc 的结果,因为在内存分配失败的情况下,它会返回 NULL,同时仍然保留已分配的内存(然后您将失去它在内存中的位置)。但是在大多数 Unix 系统上,当进行临时处理(不是一些繁重的任务)时,达到 malloc/realloc 返回 NULL 的点在某种程度上是一种罕见的情况(你必须用尽所有虚拟空闲内存)。还是最好写:

pair*newp=realloc(p,[new size]);
if(newp != NULL) p=newp;
else { ... last resort error handling, screaming for help ... }
于 2012-04-17T19:02:22.473 回答
0

因此,如果我做对了,您会计算成对字符出现的次数吗?当您可以将频率表保存在 64KB 数组中时,为什么还要使用嵌套循环和使用该对结构,这更简单,速度也快了几个数量级。

这大致是我会做的(剧透警告:特别是如果这是家庭作业,请不要只是复制/粘贴):

#include <stdlib.h>
#include <stdio.h>
#include <ctype.h>

void count_frequencies(size_t* freq_tbl, FILE* pFile)
{
    int first, second;

    first = fgetc(pFile);
    while( (second = fgetc(pFile)) != EOF)
    {
        /* Only consider printable characters */
        if(isprint(first) && isprint(second))
            ++freq_tbl[(first << 8) | second];

        /* Proceed to next character */
        first = second;
    }
}

int main(int argc, char*argv[])
{
    size_t* freq_tbl = calloc(1 << 16, sizeof(size_t));;
    FILE* pFile;
    size_t i;

    /* Handle some I/O errors */
    if(argc < 2)
    {
        perror ("No file given"); 
        return EXIT_FAILURE;
    }

    if(! (pFile = fopen(argv[1],"r")))
    {
        perror ("Error opening file"); 
        return EXIT_FAILURE;
    }

    if(feof(pFile))
    {
        perror ("Empty file"); 
        return EXIT_FAILURE;
    }

    count_frequencies(freq_tbl, pFile);

    /* Print frequencies */
    for(i = 0; i <= 0xffff; ++i)
        if(freq_tbl[i] > 0)
            printf("%c%c : %d\n", (char) (i >> 8), (char) (i & 0xff), freq_tbl[i]);
    free(freq_tbl);

    return EXIT_SUCCESS;
}

抱歉,位操作和十六进制表示法。我只是碰巧在这种 char 表的上下文中喜欢它们,但为了清楚起见,它们可以用乘法和加法等替换。

于 2012-04-17T23:01:43.397 回答