我的目标是从带有动态数组的文件中读取文本,并使用参数“numline”打印出您想要的任何行。我必须使用循环单链表来完成这项工作。当我运行函数时,我只得到第一行X numline。我很困惑,我是否在添加节点分区或遍历和打印输出分区时出错?
EDiT:我编辑了文件......
void last(char* numline,char* fileptr)
{
struct node *start,*newnode,*lastnode;
struct node *ptr=start;
char *linebuffer;
int maxlinelen=512;
int i=0;
int j;
FILE *fp;
linebuffer=(char*)malloc(maxlinelen * sizeof(char*));
if(linebuffer==NULL)
{
fprintf(stderr,"Command: last:Memory allocating failed for linebuffer\n");
exit(1);
}
if((fp=fopen(fileptr,"r"))!=NULL)
{
start=NULL;
while((fgets(linebuffer,maxlinelen,fp))!=NULL)
{
while(strlen(linebuffer)==maxlinelen-1)
{
maxlinelen*=2;
linebuffer=realloc(linebuffer,maxlinelen * sizeof(char));
if(linebuffer==NULL)
{
fprintf(stderr,"Command: last: Memory reallocating failed for linebuffer\n");
exit(1);
}
fgets(linebuffer+(maxlinelen/2-1),(maxlinelen/2)+1,fp);
}
if(start==NULL)
{
newnode=(struct node *)malloc(sizeof(struct node));
strcpy(newnode->data,linebuffer);
printf("linebuffer newnoda kopyalandi\n");
start=newnode;
newnode->next=newnode;
// start=newnode;
i++;
printf("ikinciburda");
}
else{
newnode=(struct node *)malloc(sizeof(struct node));
strcpy(newnode->data,linebuffer);
lastnode=start;
while(lastnode->next!=start)
{
lastnode=lastnode->next;
}
lastnode->next=newnode;
newnode->next=start;
i++;
}
}
printf("toplam line sayisi :%d\n",i);
ptr=start; //<----- i added this line
for(j=i-(atoi(numline));j<i;j++)
{
ptr=ptr->next;
}
while(ptr!=start)
{
printf("%s\n",ptr->data);
ptr=ptr->next;
}
fclose(fp);
}
}
答案 0 :(得分:2)
这些行
while(start->next!=start)
{
printf("%s\n",start->data);
/// especially this one
start=start->next;
}
看起来很可疑。
在第一次迭代中,您将start->next
分配给start
,然后立即退出循环(因为很明显,start == start->next
)。
您应该做的就是创建一个struct node* ptr
,为其指定开头,然后创建一个ptr = ptr->next
“totallines” - “numline”次:
struct node* ptr = start;
for(j = atoi(numline) ; j < i ; j++) { ptr = ptr->next; }
while(ptr != start)
{
printf("%s\n", ptr->data);
ptr = ptr->next;
}
当然,你应该检查numline <= totaline
- 为了简洁,我省略了这个检查。
重要编辑:
插入
后 for(j = i - atoi(numline) ; j < i ; j++)
{
// debug statement
printf("skip %s\n", ptr->data);
ptr = ptr->next;
}
我注意到,链表的构造不正确 - 上面的迭代只给出了第一行。
EDIT2(有些注释):
您的错误处理代码很好,并且不确定行长度的动态缓冲区也很好,因为代码变得非常冗长,并且查找问题并不容易。我想很多人都是因为写了这么多答案,而且大部分都与链表无关,顺便说一下,代码中不是。我猜是
struct node
{
struct node* next;
char data[SomeBigNumber];
};
EDIT3:列表构建
“add-last-node”部分中的代码更加棘手,应该澄清lastnode / newnode的混乱。
错误在于:
/// once again, here lastnode->next IS start, as you want it to be
lastnode->next=start;
/// and this condition is always false (see the previous line)
while(lastnode->next!=start)
{
lastnode=lastnode->next;
}
您已注释掉了//lastnode = start;
行,但它应该在循环之前到达最后一个元素。
// add additional nodes
必须是:
else { //add additional nodes
newnode=(struct node *)malloc(sizeof(struct node));
strcpy(newnode->data,linebuffer);
lastnode=start;
while(lastnode->next!=start) { lastnode=lastnode->next; }
lastnode->next=newnode;
newnode->next=start;
i++;
}
当然,每次插入节点时寻找最后一个元素都是一种过度杀伤力。你应该保持lastnode
总是指向最后一个元素(或者当列表最初为空时为NULL)。