我遇到了结构数组的问题。我需要逐行读取文本文件,并将这些值并排比较。例如,“Mama”将返回2 ma,凌晨1点因为你有mama。我有一个结构:
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");
}
}
如果有更好的方法,我很乐意明显地改变一切。我必须使用上面的结构,必须有一个结构数组,并且必须使用内存分配。这是唯一的限制。
答案 0 :(得分:3)
为struct数组分配内存就像为一个struct分配一样简单:
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 ... }
答案 1 :(得分:0)
所以,如果我做对了,你会计算一对字符出现的次数吗?当你可以将频率表保存在64KB阵列中时,为什么所有关于嵌套循环和使用该对结构的问题,这更简单,数量级更快。
这大致是我要做的事情(SPOILER ALERT:特别是如果这是作业,请不要只是复制/粘贴):
#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表的上下文中喜欢它们,但为了清晰起见,它们可以用乘法和加法等替换。