将文本文件读入结构

时间:2014-04-21 18:30:09

标签: c text struct

我正在尝试编写一个程序,可以从文本文件中获取数据并将其放入结构中,然后我将结构添加到链表中,然后显示列表。没有数组。 目前我在逐行读取结构的每个字段时遇到问题,因为当我尝试显示列表时,它给了我错误的值/乱码。 我关注的部分是主要方法。

这是我想读的文本文件:

#1 Flat Blade Screwdriver
12489
36
.65
1.75
#2 Flat Blade Screwdriver
12488
24
.70
1.85
#1 Phillips Screwdriver
12456
27
0.67
1.80
#2 Phillips Screwdriver
12455
17
0.81
2.00
Claw Hammer
03448
14
3.27
4.89
Tack Hammer
03442
9
3.55
5.27
Cross Cut Saw
07224
6
6.97
8.25
Rip Saw
07228
5
6.48
7.99
6" Adjustable Wrench
06526
11
3.21
4.50

这是我目前的计划:

#include "stdafx.h"
#include <stdio.h>
#include <stdlib.h>
#include <stddef.h>

typedef struct inventory
{
    char invName[36];
    int  invPartNo;
    int  invQOH;
    float invUnitCost;
    float invPrice;
}stock;

struct  NODE
{
    union
    {
        int  nodeCounter;
        void  *dataitem;
    }item;
    struct NODE *link;
};

struct NODE *InitList();
void DisplayNode(struct inventory *);
struct inventory * ReadData(FILE *);
void DisplayList(struct NODE *);
struct NODE* GetNode(FILE *);
void  Add2List(struct NODE *, struct NODE *);
struct NODE* SearchList(struct NODE *, int );
void  DeleteNode(struct NODE *, int );


int main(int argc, char* argv[])
{
    struct NODE *header;
    header = InitList();
    char line[50];

    int i, j;
    i = 0;
    FILE *fp = fopen("input.txt", "r");
    if( fp != NULL )
    {
        while(fgets(line, sizeof(line), fp))
        {
            struct NODE *nNode =  (struct NODE*)malloc(sizeof NODE);
            struct inventory *newNode =  (struct inventory*)malloc(sizeof inventory);
            fscanf(fp,"%s %d %d %f %f ", newNode->invName, &newNode->invPartNo,&newNode->invQOH,&newNode->invUnitCost,&newNode->invPrice);

            /*
            fscanf(fp, "%s", newNod->invName);
            fscanf(fp, "%d", newNod->invPartNo);
            fscanf(fp, "%d", newNod->invQOH);
            fscanf(fp, "%f", newNod->invUnitCost);
            fscanf(fp, "%f", newNod->invPrice);
            */

            nNode->item.dataitem = newNode;
            nNode->item.nodeCounter++;
            Add2List(header, nNode);
        }
     }
    DisplayList(header);

    //startNode->invName = array[0].invName;
    //struct inventory *startNode;

    /*
    char line[BUFSIZ];
    while ( fgets(line, sizeof line, fp) != NULL && sscanf(line, " %s %d %11s %19s %lf", &record.empNum, record.firstName, record.lastName, &record.hourRate) == 4 )
    {

    }*/

    /*
    struct NODE *header;
    header = InitList();

    int  PCounter = 2;
    while (PCounter--)
    {
        Add2List(header,GetNode(stdin));
    }

    DisplayList(header);
    */

    return 0;
}

struct NODE *InitList()
{
    struct NODE *temp = (struct NODE*)malloc(sizeof NODE);

    temp->item.nodeCounter = 0;
    temp->link = NULL;
    return temp;
}


void  Add2List(struct NODE *start, struct NODE *NewNode)
{
    struct NODE *current = start;

    while (current->link != NULL)
        current = current->link;

    current->link = NewNode;
    NewNode->link = NULL;

    start->item.nodeCounter++;
}


struct NODE* GetNode(FILE *fptr)
{
    struct NODE *temp = (struct NODE*)malloc(sizeof NODE);

    temp->item.dataitem = ReadData(fptr);
    temp->link = NULL;

    return temp;
}


void DisplayList(struct NODE *start)
{
    struct NODE *current = start->link;

    while (current != NULL)
    {
        DisplayNode((struct inventory *)current->item.dataitem);
        current = current->link;

    }
}


void DisplayNode(struct inventory *stuff)
{
    printf("Name: %s", stuff->invName);
    printf("Part Number: %d", stuff->invPartNo);
    printf("Quantity on hand: %d", stuff->invQOH);
    printf("Unit Cost: %0.2f", stuff->invUnitCost);
    printf("Price %0.2f", stuff->invPrice);
}


struct inventory * ReadData(FILE *fptr)
{
    struct inventory *temp = (struct inventory *)malloc(sizeof inventory);

    if(fptr==stdin)
        printf("Enter item name: ");
    fscanf_s(fptr, "%s", temp->invName);
    if(fptr==stdin)
        printf("Enter item part number: ");
    fscanf_s(fptr, "%d", &temp->invPartNo);
    if(fptr==stdin)
        printf("Enter item quantity on hand: ");
    fscanf_s(fptr, "%d", &temp->invQOH);
    if(fptr==stdin)
        printf("Enter item unit cost: ");
    fscanf_s(fptr, "%f", &temp->invUnitCost);
    if(fptr==stdin)
        printf("Enter item price: ");
    fscanf_s(fptr, "%f", &temp->invPrice);

    return temp;
}

struct NODE* SearchList(struct NODE *start, int oldData)
{
    struct NODE* current = start;
    struct inventory * st = (struct inventory *)current->link->item.dataitem;

    while (st->invPartNo != oldData && current != NULL)
    {
        current = current->link;
        if(current->link)
            st = (struct inventory *)current->link->item.dataitem;
    }
    return current;
}

void  DeleteNode(struct NODE *start, int oldData)
{
    struct NODE *current, *oldNode;

    current = SearchList( start, oldData);
    oldNode = current->link;
    current->link = oldNode->link;
    free(oldNode);
    start->item.nodeCounter -= 1;
}


struct inventory* readFromFile( )
{
    /*
    FILE *fp;
    fp = fopen("input.txt", "r");
    struct inventory *header, *temp;
    //header = InitList();

    char invName[36];
    int  invPartNo;
    int  invQOH;
    float invUnitCost;
    float invPrice;

    fscanf(fp, "%s", temp->invName);
    fscanf(fp, "%d", &temp->invPartNo);
    fscanf(fp, "%d", &temp->invQOH);
    fscanf(fp, "%f", &temp->invUnitCost);
    fscanf(fp, "%f", &temp->invPrice);
    fclose(fp);
    */

    /*
    char invName[36];
    int  invPartNo;
    int  invQOH;
    float invUnitCost;
    float invPrice;

    //---------------------------------------------------------------
    char ch, file_name[100];
   FILE *fp;
   printf("Enter the name of file you wish to see\n");
   gets(file_name);
   fp = fopen(file_name,"r"); // read mode
   if( fp == NULL )
   {
      perror("Error while opening the file.\n");
      exit(EXIT_FAILURE);
   }
 //---------------------------------------------------------------
   int i = 0;
   //while( ( ch = fgetc(fp) ) != EOF)
   //while(!feof(fp))
   while((ch != '\n') && (ch != EOF))
   {
       struct inventory *temp;
       char *fgets(temp->invName, 100, fp);
       fscanf(fp, "%d", &temp->invPartNo);
       fscanf(fp, "%d", &temp->invQOH);
       fscanf(fp, "%f", &temp->invUnitCost);
       fscanf(fp, "%f", &temp->invPrice);
   }*/
    return 0;
}

void readFile()
{
    stock array[20]; //9 items to read from list
    int i, j;
    i = 0;
    FILE *fp = fopen("input.txt", "r");
    if( fp != NULL )
    {
        while(fgets(array[i].invName, sizeof array[i].invName, fp))
        {
            fscanf(fp,"%d %d %f %f ",&array[i].invPartNo,&array[i].invQOH,&array[i].invUnitCost,&array[i].invPrice);
            i++;
        }
     }

}

1 个答案:

答案 0 :(得分:0)

您使用fgets读取了一行,然后尝试使用fscanf读取结构。这不起作用,因为fgets已经吃了一行,当你执行fscanf时就会丢失这一行。您的代码可能看起来像

struct inventory buf;
while (fscanf(fp,"%s %d %d %f %f ", buf.invName, &buf.invPartNo, ...) == 5) {
    /* do something with data, copy it to dynamic memory */
    struct NODE *nNode =  (struct NODE*)malloc(sizeof NODE);
    struct inventory *newNode =  (struct inventory*)malloc(sizeof inventory);
    *newNode = buf;
    nNode->item.dataitem = newNode;
    nNode->item.nodeCounter++;
    Add2List(header, nNode);
}

这会将输入读入临时缓冲区,以便在存储或处理输入时使用。

更新

另一种方法可能是测试EOF并保留循环的其余部分

while(!feof(fp)) {
    struct NODE *nNode =  (struct NODE*)malloc(sizeof NODE);
    struct inventory *newNode =  (struct inventory*)malloc(sizeof inventory);
    fscanf(fp, "%s %d %d %f %f ", newNode->invName, &newNode->invPartNo, &newNode->invQOH, &newNode->invUnitCost, &newNode->invPrice);
    nNode->item.dataitem = newNode;
    nNode->item.nodeCounter++;
    Add2List(header, nNode);
}