【问题标题】:Circular Doubly Linked List, Print Function循环双向链表,打印功能
【发布时间】:2014-02-18 07:53:33
【问题描述】:

我需要创建一个带有哨兵节点的循环双向链表,该节点应该从文件中读取数据并将其插入列表中,而不是对其执行一些操作。现在我被困在一个简单的打印功能上,由于某种原因它不会从列表中打印出来。文件中的数据是字符串的形式, 例如:“流行的排序算法, 冒泡排序、归并排序、“空行”等

到目前为止,这是我的代码:

头文件包含:

typedef struct NODE {
 struct NODE *prev;
 char *value;
 struct NODE *next;
} NODE;

typedef struct LIST {
 int count;
 struct NODE *next;
 struct NODE *prev;
 } LIST;

int InsertEnd(NODE *head, char * value, int *lineCount);
void printLines(int *lineCount);
void Traverse(NODE *head);

主要包含:

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include "header.h"


int main()
{
    int lineCount = 0;
    NODE *head;

    head = (NODE *)malloc(sizeof(NODE)); /* creates head node dynamically */

    head->next = NULL;   /* points to first element */
    head->prev = NULL;   /* points to last element */
    head->value = "HEAD"; /* not needed, but it was pretty useful when debugging */

    //*********BEGIN OF OPEN FILE FUNCTION
    FILE* fp;
    char *fname = NULL;
    fname = (char *)malloc(200); <<<<<===== I would prefer to set the size dynamically adjusting but I dont know how

        printf("Reading file input.txt\n");

    //Checks if the file us unable to be opened, then it shows the error message
    if ( !(fp = fopen("input.txt", "r")))
    {
        printf("\nError, Unable to open the file for reading \n");
        exit(100);
    }

    //*********BEGIN OF READ FROM FILE FUNCTION

    while (!feof(fp))
    {
        fgets(fname, 150, fp);  //reads the file and stores in buffer

        fname[strlen(fname) - 1] = '\0'; // reduces empty strings for input

        if (fname != '\0')
        {

            InsertEnd(head, fname, &lineCount);
        //printf("%s\n", head->next->value);  <<<<==== If uncomment this print function would work properly but only in this context

        }
        else
        {
            printf("Error'\n"); // For debugging
        }

    }
    Traverse(head); // Print Function Should Be Working in Here
    printf("Debugging print\n");
    printLines(&lineCount); // Shows Line Count
    return 0;
}
// Function inserts a new node at the end of the LIST
int InsertEnd(NODE *head, char * value, int* lineCount)
{
    int lineCounter = *lineCount;
    /* create new node */
    NODE *newnode;
    newnode = (struct NODE *)malloc(sizeof( struct NODE));
    newnode->value = value;
    /* placing new node in LIST */
    if (head->next == NULL) /* LIST was empty */
    {
        newnode->next = head;
        newnode->prev = head;
        head->next = newnode;
        head->prev = newnode;
        lineCounter++;               // Increment line counter
    }
    else /* LIST wasn't empty */
    {
        newnode->next = head;
        newnode->prev = head->prev;
        head->prev->next = newnode; /* adjust node that was previously last */
        head->prev = newnode;       /* adjust head node */
        lineCounter++;                // Increment line counter
    }
    *lineCount = lineCounter;
    return lineCount;
}


// This function prints how many lines there are in the LIST, but I need to get rid of the empty spaces
void printLines(int *lineCount)
{
 printf("Line counter is %d", *lineCount);  // Shows the number of lines, but doesn't skip empty ones.
}


void Traverse(NODE *head)
{
    NODE *current = head;

    printf("Forward:");
    while (current!= head->prev)
    {
        printf("%s \n", current->value);

        current = current->next;
    }
    printf("\n");
}

因此,到目前为止,我有几个问题:

1) 我很可能需要删除列表中的空字符串。什么是更好的方法,在阅读时摆脱它们或在打印时不显示?我该怎么做呢?

2) 如何修复我的 print(traverse) 功能以及那里出了什么问题?

3) 此外,所有这些都应该通过菜单管理器进行,它会提示输入命令(我认为这是对的)。但是有些功能我不知道如何实现。例如,当使用点击“I”时,它应该调用插入函数并提示用户输入另外两个值和,然后在适当的位置插入。我该怎么做?示例“I 1 8”

4) 与上一个类似,应该有 List 函数,它应该打印特定值之间的行。用户输入格式应为“L to”列表(含)。示例“L 2 5”

5) 与前面类似,应该有一个包含“D”格式的删除函数。示例“D 3 7”

6) 最后是“S”格式的保存功能示例“S output.txt”

感谢您的帮助!

【问题讨论】:

  • 您可以将此添加到您的待处理事项列表中:while (!feof(fp)) is wrong。并且确保 fgets() 在假设它工作之前完全未检查潜在故障。

标签: c linked-list


【解决方案1】:

我在您的代码中至少看到了这些问题,

main()

 if (fname != '\0') 

这应该是

 if (fname[0] != '\0')     

InsertEnd()

newnode->value = value;

应该是

newnode->value = strdup(value);    

【讨论】:

    【解决方案2】:

    在您的代码中应该有一些正确性,首先根据您的请求非常有帮助,您需要动态分配缓冲区但不知道 file 长度,因此可以通过这个来实现

    int sz;
    printf("Reading file input.txt\n");
    
    //Checks if the file us unable to be opened, then it shows the error message
    if ( !(fp = fopen("sample.txt", "r")))
    {
        printf("\nError, Unable to open the file for reading \n");
        exit(100);
    }
    
    fseek(fp, 0L, SEEK_END);
    sz = ftell(fp);
    
    printf("size of file %d\n",sz);
    
    fname = (char *)malloc(sz);
    rewind(fp);
    

    现在从您检查的文件中读取内容 fname\0 这是不正确的,我更正了您的 while..loop

    while (!feof(fp))
    {
        if(fgets(fname,256, fp) != 0)
        {
            fname[strlen(fname) - 1] = '\0'; // reduces empty strings for input
            InsertEnd(head, fname, &lineCount);
        }
        else
        {
            printf("Error'\n"); // For debugging
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-11-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-07-05
      相关资源
      最近更新 更多