将数据从文件读入链表,并在链表中搜索元素

时间:2017-12-10 06:13:26

标签: c++ struct linked-list

我正在尝试编写代码并从文件中获取数据并将其存储到结构中并创建链接列表。我没有看到我的代码有任何直接问题,但我做了一个函数来检查链表中的任何结构中是否存在一个zipcode并且它似乎不起作用。以下是文件中的数据:

ID,价格,卧室,卫生间,平方英尺,yr_built,邮编

1370804430,543115,2,1,1380,1947,98199

3744000040,518380,4,2.5,2810,2014,98038

3313600266,190000,3,1,1180,1966,98002

编辑我实现了用于将文件读入链接列表的新代码,但我找到邮政编码的功能并不起作用。当我输入一个我知道存在于文件中的邮政编码时,没有任何内容被打印出来。

typedef struct housetype house;
struct housetype{
int id;
int price;
int bedrooms;
double bathrooms;
int sqft;
int year;
int zipcode;
house *next; };


int findzipcode(house* head, int zip){
    house* current = head;
    while(current != NULL){
        if(current->zipcode == zip){
            cout << "Zipcode exists" << endl;
            return 1;
            break;}
            current = current->next;
    }
return 0;}



int main(){
house *head = NULL;
FILE *houseinfo = NULL;
houseinfo = fopen("house-info-v4.txt", "r");

if (houseinfo == NULL) {
    cout << "Error reading file" << endl;
}
else {
    int res;         
    house *last = head;    
    house h;               
    do {
        res = fscanf(houseinfo, "%d,%d,%d,%lf,%d,%d,%d",
                  &h.id, &h.price, &h.bedrooms, &h.bathrooms,
                  &h.sqft, &h.year, &h.zipcode);
        if (res > 0) {      // <== fscanf successful (if file fits!)
            house *n = (house*)malloc(sizeof(house)); 
            memcpy(n, &h, sizeof(house)); 
            n -> next = NULL;
            if (last) last->next = n; 
            if ( ! head) head = n;    
            last = n;               
        }
    } while (res > 0);
}
int zip;
cout << "Enter a zipcode" << endl;
cin >> zip;
findzipcode(head, zip);}

5 个答案:

答案 0 :(得分:0)

您提供的代码只会加载第一个项目,因此如果您要搜索以后的项目,它将无效。

注意fscanf的代码没有循环。

答案 1 :(得分:0)

我认为你只从数据中读取一行,并为链表制作了一个节点。如果要创建链表,则必须从文件中读取所有行并创建每行的节点并将其与循环链接。

例如

while (1)
    read_file
    if feof:
        break
    make_node
    add row_info -> node
    link_node

尝试用c ++编写此代码

答案 2 :(得分:0)

至少有两个问题

  • head仍为NULL
  • 只从文件中读取一个房屋

尝试类似

的内容
if (houseinfo == NULL) {
    cout << "Error reading file" << endl;
}
else {
    int res;                // <== fscanf result
    house *last = head;     // <== last house set (head is still null)
    house h;                // <== holds values until fscanf check
    do {
        res = fscanf(houseinfo, "%d,%d,%d,%lf,%d,%d,%d",
                  &h.id, &h.price, &h.bedrooms, &h.bathrooms,
                  &h.sqft, &h.year, &h.zipcode);
        if (res > 0) {      // <== fscanf successful (if file fits!)
            house *n = (house*)malloc(sizeof(house)); // c++ cast malloc
            memcpy(n, &h, sizeof(house)); // <== copy to allocated house
            n -> next = NULL;
            if (last) last->next = n; // last next is our n 
            if ( ! head) head = n;    // set head if necessary
            last = n;                 // last house set is n, now
        }
    } while (res > 0);
}

解释在评论中。基本上

  • 循环 fscanf ,直到文件
  • 中没有其他行
  • 读取本地变量h
  • 中的值
  • 如果 fscanf 成功,请分配并设置n
  • 如果我们有最后一个,请将 next 设置为新的n
  • 如果head尚未设置,请将其设置为
  • 最后,last指向n以便在下一次迭代中使用

答案 3 :(得分:0)

首先选择一种语言。无论是C还是C ++。

您的代码存在问题。问题是,你在这里有内存泄漏,并且在某种程度上是问题的原因。

好好详细说一下,你分配内存并获取输入并将其存储在该内存中,然后你就会忘记它。你不要忘记,但是没有办法你可以访问它。这是内存泄漏。然后你将一个NULL值指针传递给搜索函数,它不返回任何内容。

此更改将解决问题,

        house *n = malloc(sizeof(house));
        head = n; //<----- We are not losing the allocated memory
        fscanf(houseinfo, "%d.....
        ..

你的代码中还有一个多余的东西(这不会导致问题,但是你应该知道这一点。)

        cout << "Zipcode exists" << endl;
        return 1;
        break; //<--- this is redundant
       } 

执行return语句后,永远不会执行break。只需输入return语句即可。没有必要把break放在这里。

另一点你没有释放分配的内存。(啊!释放你需要跟踪它 - 你没有在这里做)。完成它之后你应该释放它。

       findzipcode(head, zip);
       free(head);

同时检查malloc的返回值。如果它返回NULL采取必要的行动。

答案 4 :(得分:0)

在以下提议的代码中:

  1. 检查错误条件并采取行动
  2. 该问题的大部分意见已纳入
  3. 现在,建议的代码:

    #include <cstdio>
    #include <cstdlib>
    #include <errno.h>
    
    
    struct housetype
    {
        int id;
        int price;
        int bedrooms;
        double bathrooms;
        int sqft;
        int year;
        int zipcode;
        struct housetype *next;
    };
    typedef struct housetype house;
    
    
    void findzipcode(house* head, int zip)
    {
        house* current = head;
    
        while( current )
        {
            if(current->zipcode == zip)
            {
                cout << "Zipcode exists" << endl;
                return;
            }
    
            current = current->next;
        }
    }
    
    
    
    int main( void )
    {
        house *head = NULL;
    
        FILE *houseinfo = fopen("house-info-v4.txt", "r");
        if ( !houseinfo )
        {
            cerr << "fopen failed due to" << strerror( errno )  << endl;
            exit( EXIT_FAILURE );
        }
    
        // implied else, fopen successful
    
        int res;
        house *last = NULL;
        house h;
    
    
        while( 7 == (res = fscanf(houseinfo, "%d,%d,%d,%lf,%d,%d,%d",
                      &h.id, &h.price, &h.bedrooms, &h.bathrooms,
                      &h.sqft, &h.year, &h.zipcode) ) )
    
            house *n = new house;
            if( !n )
            {
                cerr << "malloc failed due to: " << strerror( errno ) << endl;
                exit( EXIT_FAILURE );
            }
    
            // implied else, malloc successful
    
            memcpy(n, &h, sizeof(house));
            n -> next = NULL;
    
            if (last)
                last->next = n;
    
            else if ( ! head)
                head = n;
    
            last = n;
        }
    
        int zip;
        cout << "Enter a zipcode" << endl;
        cin >> zip;
        findzipcode(head, zip);
    
        while( head )
        {
            house *nextHouse = head->next;
            delete head;
            head = nextHouse;
        }
    }
    

    当然,如果您真的想使用C ++,那么建议使用vector而不是链接列表