iam trying to read the data i saved in the file record.txt with the function and then read from file and insert the data into the linked list again but iam getting an infinite loop when I display the data from the list with i cant find the problem!
idk if the problem in the save function or the getfile function or the dispal i cant find any hint on my problem
Code:
#include<stdlib.h>
#include<string.h>
#include<stdio.h>
#include<windows.h>
#include <unistd.h>
int import = 0 ;
struct Repertoire
{
char phone[10];
char name[100];
char lastname[100];
char adresse[100];
char date[100];
char email[100];
struct Repertoire *next;
}* head;
void insert(char* phone, char* name, char* lastname, char* adresse, char* email, char* date)
{
struct Repertoire * rep = (struct Repertoire *) malloc(sizeof(struct Repertoire));
strcpy(rep->phone, phone);
strcpy(rep->name, name);
strcpy(rep->lastname, lastname);
strcpy(rep->adresse, adresse);
strcpy(rep->email, email);
strcpy(rep->date, date);
rep->next = NULL;
if(head==NULL){
// if head is NULL
// set student as the new head
head = rep;
}
else{
// if list is not empty
// insert student in beginning of head
rep->next = head;
head = rep;
}
}
void display()
{
struct Repertoire * temp = head;
while(temp!=NULL){
printf("Phone Number: %s\n", temp->phone);
printf("Name: %s\n", temp->name);
printf("Lastname: %s\n", temp->lastname);
printf("Adresse: %s\n", temp->adresse);
printf("Date of birth: %s\n", temp->date);
printf("email: %s\n", temp->email);
temp = temp->next;
}
}
void insertFile(){
struct Repertoire * temp = head;
FILE *ptr;
ptr=fopen("record.txt","a+");
while(temp!=NULL){
fprintf(ptr,"%s %s %s %s %s %s\n",temp->phone,temp->name,temp->lastname,temp->adresse,temp->date,temp->email);
temp = temp->next;
}
fclose(ptr);
}
void SaveFile(){
struct Repertoire * temp = head;
FILE *ptr;
ptr=fopen("new.txt","w");
while(temp!=NULL){
fprintf(ptr,"%s %s %s %s %s %s\n",temp->phone,temp->name,temp->lastname,temp->adresse,temp->date,temp->email);
temp = temp->next;
}
fclose(ptr);
remove("record.txt");
rename("new.txt","record.txt");
}
void GetFile(){
char phone[10];
char name[100];
char lastname[100];
char adresse[100];
char date[100];
char email[100];
FILE *ptr;
ptr=fopen("record.txt","r");
struct Repertoire * rep = (struct Repertoire *) malloc(sizeof(struct Repertoire));
while(fscanf(ptr,"%s %s %s %s %s %s\n",phone,name,lastname,adresse,date,email)!=EOF){
strcpy(rep->phone, phone);
strcpy(rep->name, name);
strcpy(rep->lastname, lastname);
strcpy(rep->adresse, adresse);
strcpy(rep->email, email);
strcpy(rep->date, date);
rep->next = NULL;
if(head==NULL){
// if head is NULL
// set student as the new head
head = rep;
}
else{
// if list is not empty
// insert student in beginning of head
rep->next = head;
head = rep;
}
}
free(rep);
printf("Data Ipmorted Successfully !!");
import = 1 ;
fclose(ptr);
}
I found the answer :
void GetFile(){
FILE *ptr;
ptr=fopen("record.txt","r");
struct Repertoire * rep = (struct Repertoire *) malloc(sizeof(struct Repertoire));
while(!feof(ptr)){
fscanf(ptr,"%s %s %s %s %s %s\n",rep->phone,rep->name,rep->lastname,rep->adresse,rep->date,rep->email);
insert(rep->phone,rep->name,rep->lastname,rep->adresse,rep->date,rep->email);
}
printf("Data Ipmorted Successfully !!\n");
import = 1 ;
fclose(ptr);
}
Related
I have written so far the program below, but the point is that this one creates a list for all the packets, that succeed to enter the list. I want to have 10 lists instead of 1 and that is because I have 10 text files to open. I think that using the same insert function 10 times, will create the same list, so do I have to create 10 head pointers, so when text file 1 opens, the packets from it will enter the list 1 and etc.? Any help will be greatly appreciated.
struct Packet
{
int rollnumber;
int src;
int dest;
double gentime;
struct Packet *next;
}* head;
void insert(int rollnumber, int src, int dest, double gentime)
{
struct Packet * packet = (struct Packet *) malloc(sizeof(struct Packet));
packet->rollnumber = rollnumber;
packet->src=src;
packet->dest=dest;
packet->gentime = gentime;
packet->next = NULL;
if(head==NULL){
// if head is NULL
// set packet as the new head
head = packet;
}
else{
// if list is not empty
// insert packet in beginning of head
packet->next = head;
head = packet;
}
}
void display()
{
struct Packet * temp = head;
while(temp!=NULL)
{
printf("Roll Number: %d\n",temp->rollnumber);
printf("src: %d\n", temp->src);
printf("dest: %d\n", temp->dest);
printf("gentime: %0.1f\n\n", temp->gentime);
//printf("offtime: %0.1f\n\n", temp->offtime);
temp = temp->next;
}
}
int main(int argc, char **argv)
{
char line[MAX_LINE_LENGTH] = {0};
int src,dest;
int rollnumber;
double gentime;
int i=1;
static unsigned long pos[] = {0};
FILE *file;
char filename_format[] = "fptg_%d.txt";
double Time=12.0;
int insertedpackets[1000];
struct node * head = NULL;
for (Time=12.0; Time<60.0; Time=Time+12.0){
for(i=1;i<=10;i++){
char to_open[32];
snprintf(to_open,32, "fptg_%d.txt", i);
printf("\n\nFPTG_%d.txt\n", i);
if ((file = fopen(to_open, "r")) == NULL)
{
break;
}else{
fseek(file , pos[i], SEEK_CUR);
fgets(line, sizeof(line), file);
sscanf(line,"%d %d %d %lf",&rollnumber, &src, &dest, &gentime);
printf("%s", line);
printf("Return value=%d\n",sscanf(line, " %d %d %d %lf", &rollnumber, &src, &dest, &gentime));
printf("gentime=%.1f\n", gentime);
pos[i] = ftell(file);
if (gentime<Time){
printf("ok\n");
insert(rollnumber,src,dest,gentime);
printf("Time=%0.1f\n", Time);
}
fclose(file);
}
}
}
printf("\n\nTHE LIST:\n");
display();
}
I'm writing this code for a college project, and I need to load this text file into a Singly Linked List. But When printing it only prints the first line in the file (the first node in the LinkedList).
Lines in the .txt files are as follows:
VOLKSWAGEN GOLF 2017 WHITE 120000
VOLKSWAGEN GOLF 2017 BLACK 121000
VOLKSWAGEN POLO 2018 ORANGE 95000
VOLKSWAGEN CADDY 2015 BLACK 145000
VOLKSWAGEN CADDY 2015 BLACK 145000 etc..
Any help would be greatly appreciated, thanks!
See code:
struct sCar{
char manufacturer[15];
char model[15];
int year;
char colour[10];
float price;
struct sCar *nextInLine;
};
//Changing name for convenience.
typedef struct sCar * LIST;
typedef struct sCar * NODE;
int main()
{
printf("\n\n** START **\n\n");
LIST carsList;
carsList = MakeEmpty(NULL); //Initialized. (carsList) is now the Head.
NODE temp;
temp = (NODE)malloc(sizeof(struct sCar));
FILE *fPtr;
if ((fPtr = fopen("cars.dat", "r")) == NULL)
puts("File could not be opened");
else
{
fscanf(fPtr, "%s %s %d %s %f", &temp->manufacturer, &temp->model,
&temp->year, &temp->colour, &temp->price);
if(carsList->nextInLine == NULL)
{
carsList->nextInLine = temp;
temp->nextInLine = NULL;
}
else
while(fscanf(fPtr, "%s %s %d %s %f", &temp->manufacturer, &temp->model, &temp->year, &temp->colour, &temp->price) == 5)
{
NODE newNode;
newNode = (NODE)malloc(sizeof(struct sCar));
fscanf(fPtr, "%s %s %d %s %f", &newNode->manufacturer, &newNode->model, &newNode->year, &newNode->colour, &newNode->price);
temp->nextInLine = newNode;
temp = newNode;
temp->nextInLine = NULL;
}
}
printNodes(carsList);
return 0;
}
LIST MakeEmpty(LIST L)
{
if(L != NULL)
DeleteList(L);
L = NULL;
L = (LIST)malloc(sizeof(struct sCar));
if(L==NULL)
printf("Out of Memory. Can't Allocate List.");
else
L->nextInLine = NULL;
return L;
}
void printNodes(LIST L)
{
LIST temp;
temp = L->nextInLine;
while(temp != NULL)
{
printf("\n\nManufacturer: %s", temp->manufacturer);
printf("\nModel: %s", temp->model);
printf("\nYear: %d", temp->year);
printf("\nColour: %s", temp->colour);
printf("\nPrice: %.2f\n", temp->price);
temp = temp->nextInLine;
}
}
struct sCar {
char manufacturer[15];
char model[15];
int year;
char colour[10];
float price;
struct sCar *nextInLine;
};
typedef struct sCar * LIST;
typedef struct sCar * NODE;
void printNodes(LIST L)
{
while(L != NULL) {
printf("\n\nManufacturer: %s", L->manufacturer);
printf("\nModel: %s", L->model);
printf("\nYear: %d", L->year);
printf("\nColour: %s", L->colour);
printf("\nPrice: %.2f\n", L->price);
L = L->nextInLine;
}
}
int main()
{
printf("\n\n** START **\n\n");
LIST carsList;
carsList = malloc(sizeof(struct sCar));
FILE *fPtr;
if((fPtr = fopen("cars.dat", "r")) == NULL)
puts("File could not be opened");
else
{
NODE NEXT = carsList;
while(NEXT != NULL && fscanf(fPtr, "%s %s %i %s %f", &(*NEXT->manufacturer), &(*NEXT->model), &(*NEXT).year, (*NEXT).colour, &(*NEXT).price) != EOF) {
NODE newNode;
newNode = (NODE)malloc(sizeof(struct sCar));
NEXT->nextInLine = newNode;
NEXT = newNode;
}
printNodes(carsList);
}
}
I'll leave it to you to find out how you want to stop the loop. last item printed on the console is an empty sCar with no fields set.
Whenever I attempt to scan in my input, example: JASON BOURNE JULY 5 1972, the program crashes.
scanf("%s %s %s %d %d", temp->fname, temp->lname, temp->month, temp->day, temp->year);
I determined it has to do with the %d's whereas if I put:
scanf("%s %s %s", temp->fname, temp->lname, temp->month);
scanf("%d %d", temp->month, temp->day);
The String values are correct and the program crashed before int's could be assigned.
Here's a copy of my struct:
typedef struct node{
char fname [29];
char lname [29];
char month [9];
int day;
int year;
struct student * next;
struct student * previous;
} student;
and here is a copy of my function in main():
student * head = malloc(sizeof(student));
student * temp = head;
int num = numStudents;
while(num != 0){
scanf("%s %s %s %d %d", temp->fname, temp->lname, temp->month, temp->day, temp->year);
printf("FUNCTION NEVER REACHES THIS POINT");
temp = temp->next = malloc(sizeof(student));
num--;
}temp->next = NULL;
Here's what I did to get everything to work if anyone is interested:
#include <stdio.h>
#include <stdlib.h>
#include<string.h>
//Struct for Student
struct student{
char fname [29];
char lname [29];
char month [9];
int day;
int year;
struct student *next;
struct student *previous;
};
//Pre-Call
void printList(struct student *node);
struct student * insertNode(struct student * list, char fname[29], char lname[29], char month[9], int day, int year);
//Main function
int main(){
//Take Input and Assign Variables
int classes, i;
scanf("%d", &classes);
for(i = 0; i < classes; i++){
int numStudents, j;
scanf("%d", &numStudents);
struct student *list = NULL; //Create LL
int num = numStudents, day, year;
char fname[29]; char lname[29]; char month[9];
//Assign Values
while(num != 0){
scanf("%s %s %s %d %d", &fname, &lname, &month, &day, &year);
list = insertNode(list, fname, lname, month, day, year);
num--;
}
//
printList(list);
}
return 0;
}
//Function to insert a node to the LL
struct student * insertNode(struct student * list, char fname[29], char lname[29], char month[9], int day, int year){
//If the list is empty
if(list == NULL){
struct student * tempNode = (struct student *) malloc(sizeof(struct student));
strcpy(tempNode->fname,fname);
strcpy(tempNode->lname,lname);
strcpy(tempNode->month,month);
tempNode->day = day;
tempNode->year = year;
tempNode->next = NULL; // Extremely Important
return tempNode;
}
//If the list has a node
list->next = insertNode(list->next, fname, lname, month, day, year);
return list;
}
//Function to print a LL
void printList(struct student * node){
if(node->next == NULL)
printf("%s %s %s %d %d\n", node->fname, node->lname, node->month, node->day, node->year);
else
{
printf("%s %s %s %d %d\n", node->fname, node->lname, node->month, node->day, node->year);
printList(node->next);
}
}
I created a linked list that hold int and char type data. A function adds the data to the list and the other prints it out. When i only print the int type i get no problems but when i try to also print the char type the program crashes.
So it has to do the way i'm defining the char* in the printing function print_list().
To be more specific my problem is here in print_list() :
printf("\n [%s] \n", ptr -> name);
printf("\n [%s] \n", ptr -> lastn);
So my actual code is (getting 0 errors and 0 warnings but the program crashes):
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
// Creating structure for node
struct test_struct
{
int val; // val is member id number
char name;
char lastn;
int age;
struct test_struct *next;
};
// declaring global head and curr pointers
struct test_struct *head = NULL;
struct test_struct *curr = NULL;
// creating a list
struct test_struct* create_list(int val, char* name, char* lastn, int age)
{
printf("\n creating list with head node as [%d] [%s] [%s] [%d] \n", val, name, lastn, age);
struct test_struct *ptr = malloc(sizeof(struct test_struct)); // creating list
if(NULL == ptr) {
printf("\n Node creation failed \n");
return NULL;
}
ptr->val = val;
ptr->name = *name;
ptr->lastn = *lastn;
ptr->age = age;
ptr->next = NULL;
head = curr = ptr;
return ptr;
}
// add member to list
struct test_struct* add_to_list(int val, char *name, char *lastn, int age, bool add_to_end)
{
if(NULL == head) {
return (create_list(val, name, lastn, age));
}
if(add_to_end) {
printf("\n Adding node to end of list with data [%d] [%s] [%s] [%d] \n", val, name, lastn, age);
} else {
printf("\n Adding node to beginning of list with data [%d] [%s] [%s] [%d] \n", val, name, lastn, age);
}
struct test_struct *ptr = malloc(sizeof(struct test_struct));
if(NULL == ptr) {
printf("\n Node creation failed \n");
return NULL;
}
ptr->val = val;
ptr->name = *name;
ptr->lastn = *lastn;
ptr->age = age;
ptr->next = NULL;
if (add_to_end) {
curr-> next = ptr;
curr = ptr;
} else {
ptr -> next = head;
head = ptr;
}
return ptr;
}
//printing the list
void print_list(void)
{
struct test_struct *ptr = head;
printf("\n -----Printing list Start----- \n");
while(ptr != NULL) {
printf("\n [%d] \n", ptr -> val);
printf("\n [%s] \n", ptr -> name);
printf("\n [%s] \n", ptr -> lastn);
printf("\n [%d] \n", ptr -> age);
ptr = ptr->next;
}
printf("\n -----Printing list end---- \n");
return;
}
// main function
int main(void)
{
struct test_struct *ptr = NULL;
// for adding member to list
add_to_list(123, "william", "shakespeare", 30, true);
add_to_list(124, "william", "gibson", 35, true);
add_to_list(125, "chuck", "palahniuk", 40, true);
add_to_list(126, "mario", "puzio", 50, true);
add_to_list(127, "umberto", "eco", 60, true);
add_to_list(128, "ezra", "pound", 125, true);
print_list();
return 0;
}
You have declared name and lastn as single characters
struct test_struct
{
int val; // val is member id number
char name;
char lastn;
int age;
struct test_struct *next;
};
you need to declare them either as fixed size arrays or pointers which point to allocated space to hold the strings. A string is a series of characters terminated by a \0.
struct test_struct
{
int val; // val is member id number
char name[MAXLEN];
char lastn[MAXLEN];
int age;
struct test_struct *next;
};
then copy arguments to the function to the fields in the struct
e.g.
strcpy(ptr->name,name);
strcpy(ptr->lastn,lastn);
printf("\n [%s] \n", ptr -> name);
printf("\n [%s] \n", ptr -> lastn);
%s expects char * not char as both name and lastn are char variables.
And to store name and last name of a person you should prefer char array as single char variable can't store it . Therefore , declare them as char arrays .
Example -
struct test_struct
{
int val; // val is member id number
char name[20]; // or any desired length to store a name
char lastn[20]; // similar as for name
int age;
struct test_struct *next;
};
And then to copy data in it use strncpy-
ptr->name = *name; // strncpy(ptr->name,name,strlen(name));
ptr->lastn = *lastn; // strncpy(ptr->lastn,lastn,strlen(lastn));
I am working on a program that can process structure items in linkedlist/nodes.
I have most of the functions running fine, however am stuck on how to read from a txt file into a structure (the readFromFile function).
I have been reading around but am still quite confused, mainly on how to write this as a function instead of in main, and also reading into a structure
any help would be appreciated.
EDIT:
I cannot seem to get the functions in the answers to work at the moment, so I am changing to trying to make the program read from txt in main.
I could open the file, but the problem is:
How do I read data into my linked list?
(code has been modified)
The text file I am reading from is formatted like this:
#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
My program so far:
#include "stdafx.h"
#include <stdlib.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 ch, file_name[25];
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);
}
printf("The contents of %s file are :\n", file_name);
while( ( ch = fgetc(fp) ) != EOF )
{
//what to put here?
}
fclose(fp);
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)
{
/*
char invName[36];
int invPartNo;
int invQOH;
float invUnitCost;
float invPrice;
*/
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;
}
You can use fscanf() and fgets() to read the data as,
void readFromFile( )
{
stock array[20];
int i,j;
i=0;
fp = fopen("input.txt", "r");
if( fp != NULL ){
while ( !feof(fp ) ){
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++;
}
}
The array[] will have the data and i will be number of struct data read.
Here all spaces in fscanf() are put to skip the [enter] character since the data is in different lines.
read about fscanf() with its format matching and fgets() it can help in reading files.
To avoid feof() can use,
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++;
}
for This particular file format.
The algorithm:
Open the text file in 'text' 'read' mode.
Create an array of stock structures, if you know number of items beforehand, else use a linked list with each node of type stock.
To read data from file to corresponding field you can use fscanf .
When you think you have finished reading data, close the file.
Notes:
The file pointer is automatically incremented so you need not worry about incrementing it to read next set of data.
Do not forget to close the file.
To check whether the file handling functions are working fine, do check the return value of all the functions.
Important:
Since your invPartNo field in the file has integer data starting with 0, you may not want to read it as integer, otherwise it will be treated as "octal number" not a decimal number.
Your _tmain could look like below, this code assumes that the contents in the file are complete (i.e. contains the correct number of lines):
int _tmain(int argc, _TCHAR* argv[])
{ struct NODE *header = InitList();
if (argc > 1)
{ FILE *f;
if ((f = fopen(argv[1], "rt") == NULL)
{ printf(_T("Could not open file %s\n"), argv[1]);
return 1;
}
while (!feof(f))
Add2List(header, GetNode(f));
fclose(f);
}
else
{ int PCounter = 2;
while (PCounter--)
Add2List(header,GetNode(stdin));
}
DisplayList(header);
return 0;
}
EDIT:
Run the program from the command-prompt and pass the file name as a parameter