Writing linked list to txt file(Saving process) - c++

struct node
{
string info;
struct node *next;
}*start, *last;
long nodecount=0;
class teditor
{
public:
node* create_node(string);
void insert_pos();
void save();
void display();
void delete_pos();
teditor()
{
start = NULL;
}
};
node *teditor::create_node(string value)
{
struct node *temp, *s;
temp = new(struct node);
if (temp == NULL)
{
cout<<"Memory not allocated "<<endl;
return 0;
}
else
{
temp->info = value;
temp->next = NULL;
return temp;
}
}
void teditor::save()
{
struct node *info;
ofstream listfile;
listfile.open("example.txt",ios::out|ios::app |ios::binary) ;
node *temp;
temp=start;
if(!listfile){
cout<<"\nError";
}
else{
while(temp!=NULL)
{
listfile.write((char*)(temp),sizeof(nodecount));
temp=temp->next;
}
}
listfile.close();
cout<<"\n\n\n\t\tLink list has been saved in file example.txt in current folder.";
cout<<"\n\n\t\tPress a key to continue ... ";getch();
}
void teditor::insert_pos()
{
string value; int counter;
int pos;
cout<<"Enter the value to be inserted: ";
cin>>value;
struct node *temp, *s, *ptr;
temp = create_node(value);
cout<<"Enter the postion at which node to be inserted: ";
cin>>pos;
nodecount++;
int i;
s = start;
while (s != NULL)
{
s = s->next; counter++;
}
if (pos == 1)
{
if (start == NULL)
{
start = temp;
start->next = NULL;
}
else
{
ptr = start;
start = temp;
start->next = ptr;
}
}
else if (pos > 1 )
{
s = start;
for (i = 1; i < pos; i++)
{
ptr = s;
s = s->next;
}
ptr->next = temp;
temp->next = s;
}
else
{
cout<<"Positon out of range"<<endl;
}
}
void teditor::display()
{
/*
Need to merge as a string and show to display just in one line like writing
why cannot save health because of application saving pointers.
*/
node *temp;
temp=start;
cout<<"\n\n\n";
while(temp)
{
cout<<"\t\t\t"<<temp->info;
temp=temp->next;
}
cout<<"\n\n\t\t "<<nodecount<<" records displayed ,Press a key to continue.....";getch();
}
void teditor::delete_pos()
{
int pos, i, counter = 0;
if (start == NULL)
{
cout<<"List is empty"<<endl;
return;
}
cout<<"Enter the position of value to be deleted: ";
cin>>pos;
struct node *s, *ptr;
s = start;
if (pos == 1)
{
start = s->next;
}
else
{
while (s != NULL)
{
s = s->next;
}
if (pos > 0 && pos <= counter)
{
s = start;
for (i = 1;i < pos;i++)
{
ptr = s;
s = s->next;
}
ptr->next = s->next;
}
else
{
cout<<"Position out of range"<<endl;
}
free(s);
}cout<<s<<" Element Deleted"<<endl;nodecount--;
cout<<"There is left "<<nodecount<<" nodes"<<endl;
}
Hi,guys!I have problem while I trying to save my linked list to txt.Everytime I tryin and txt gave me a chinese writing.Teacher also said I need to merged with string or I need to give node to string that application can easily save that string line.Maybe because of I 'm trying to write node *temp.Anybody know how can I solve my problem?After other processes it will be copy,cut,paste and replace with nodes.

Change
listfile.write((char*)(temp),sizeof(nodecount));
to
listfile << temp->info;

You did not want to write the pointer temp into your files, you wanted the info that is inside the node that temp is pointing at. Then why you are writing temp instead of writing the info? YOu could do that "through" your pointer temp, right?
The below will do the above for you:
listfile << temp->info;

ok, you have a serialization problem. You want text in the file. But you are simply dumping memory to the file.
listfile.write((char*)(temp),sizeof(nodecount));
just writes the raw memory of a node.
Ask yourself - what should the text file look like? What do you expect it to look like in an editor. THen you have to write code to do that.
YOu need to do
listfile << temp->info
How do you want to save the next and prior. Maybe it is implicit in the ordering. SO this is all you need. Maybe you need line numbers ans to say next=4, prior=14

Your problem will be solved after doing these steps:
Right click on the project name, go to properties
In general -> project defaults -> character set
Choose not set

Related

I keep getting an error on the opening bracket of my main function with the message obj\Debug\main.o||In function `ZN11linked_listC1Ev':|

I've tried compiling in Visual Studio and CodeBlocks and I've received different error messages from both. I've been working at trying to solve this one issue for several hours and would greatly appreciate the help. I'm just trying to write a simple linked list program.
This is my Header file:
#ifndef LINKED_LIST_H_INCLUDED
#define LINKED_LIST_H_INCLUDED
#include<iostream>
#include<cstdio>
#include<cstdlib>
using namespace std;
/*
* Node Declaration
*/
struct node
{
int info;
struct node *next;
}*start;
/*
* Class Declaration
*/
class linked_list
{
public:
node* create_node(int);
void insert_begin();
void insert_last();
void insert_pos();
void delete_pos();
void delete_begin();
void delete_last();
void display();
linked_list()
{
start = NULL;
}
};
#endif // LINKED_LIST_H_INCLUDED
Here is my implementation file:
#include <iostream>
#include<cstdio>
#include<cstdlib>
#include "linked_list.h"
using namespace std;
/*
* Create Node
*/
node *linked_list::create_node(int value)
{
struct node *temp, *s;
temp = new(struct node);
if (temp == NULL)
{
cout<<"Memory not allocated "<<endl;
return 0;
}
else
{
temp->info = value;
temp->next = NULL;
return temp;
}
}
/*
* Display all the elements of the linked list
*/
void linked_list::display()
{
struct node *temp;
if (start == NULL)
{
cout<<"The List is Empty"<<endl;
return;
}
temp = start;
cout<<"Elements of list are: "<<endl;
while (temp != NULL)
{
cout<<temp->info<<"->";
temp = temp->next;
}
cout<<"NULL"<<endl;
}
/*
* Inserting at the beginning of the list
*/
void linked_list::insert_begin()
{
int value;
cout<<"Enter the value to be inserted: ";
cin>>value;
struct node *temp, *p;
temp = create_node(value);
if (start == NULL)
{
start = temp;
start->next = NULL;
}
else
{
p = start;
start = temp;
start->next = p;
}
cout<<"Element Inserted at beginning"<<endl;
}
/*
* Inserting Node at the end of the list
*/
void linked_list::insert_last()
{
int value;
cout<<"Enter the value to be inserted: ";
cin>>value;
struct node *temp, *s;
temp = create_node(value);
s = start;
while (s->next != NULL)
{
s = s->next;
}
temp->next = NULL;
s->next = temp;
cout<<"Element Inserted at last position"<<endl;
}
/*
* Insertion of node at the specified position
*/
void linked_list::insert_pos()
{
int value, pos, counter = 0;
cout<<"Enter the value to be inserted: ";
cin>>value;
struct node *temp, *s, *ptr;
temp = create_node(value);
cout<<"Enter the position at which node to be inserted: ";
cin>>pos;
int i;
s = start;
while (s != NULL)
{
s = s->next;
counter++;
}
if (pos == 1)
{
if (start == NULL)
{
start = temp;
start->next = NULL;
}
else
{
ptr = start;
start = temp;
start->next = ptr;
}
}
else if (pos > 1 && pos <= counter)
{
s = start;
for (i = 1; i < pos; i++)
{
ptr = s;
s = s->next;
}
ptr->next = temp;
temp->next = s;
}
else
{
cout<<"Position out of range"<<endl;
}
}
/*
* Deletion element at a given position
*/
void linked_list::delete_pos()
{
int pos, i, counter = 0;
if (start == NULL)
{
cout<<"List is empty"<<endl;
return;
}
cout<<"Enter the position of value to be deleted: ";
cin>>pos;
struct node *s, *ptr;
s = start;
if (pos == 1)
{
start = s->next;
}
else
{
while (s != NULL)
{
s = s->next;
counter++;
}
if (pos > 0 && pos <= counter)
{
s = start;
for (i = 1;i < pos;i++)
{
ptr = s;
s = s->next;
}
ptr->next = s->next;
}
else
{
cout<<"Position out of range"<<endl;
}
free(s);
cout<<"Element Deleted"<<endl;
}
}
/*
* Deletion of element at the beginning of the list
*/
void linked_list::delete_begin()
{
struct node *temp, *p;
temp = start;
if (start == NULL)
{
cout<<"List is empty"<<endl;
return;
}
else
{
p = start;
start = temp;
p=start->next;
delete temp;
}
cout<<"Element deleted at beginning"<<endl;
}
/*
* Deletion of element at the end of the list
*/
void linked_list::delete_last()
{
struct node *p, *s;
s = start;
while (s->next != NULL)
{
p = s;
s = s->next;
}
p->next = NULL;
delete s;
cout<<"Element deleted at last position"<<endl;
}
And Here is my driver file:
#include <iostream>
#include<cstdio>
#include<cstdlib>
#include "linked_list.h"
using namespace std;
main()
{
int choice, nodes, element, position, i;
linked_list linlist;
start = NULL;
while (1)
{
cout<<endl<<"---------------------------------"<<endl;
cout<<endl<<"Linked List Homework Menu"<<endl;
cout<<endl<<"---------------------------------"<<endl;
cout<<"1.Insert Node at the Beginning of the List"<<endl;
cout<<"2.Insert Node at the Last Position in the List"<<endl;
cout<<"3.Insert Node at Specified Position"<<endl;
cout<<"4.Delete Node at Specified Position"<<endl;
cout<<"5.Delete Node at the Last Position in the List"<<endl;
cout<<"6.Delete Node at the Beginning of the List"<<endl;
cout<<"7.Display Linked List"<<endl;
cout<<"8.Exit "<<endl;
cout<<"Please enter a selection : ";
cin>>choice;
switch(choice)
{
case 1:
cout<<"Inserting Node at the Beginning: "<<endl;
linlist.insert_begin();
cout<<endl;
break;
case 2:
cout<<"Inserting Node at the Last Position: "<<endl;
linlist.insert_last();
cout<<endl;
break;
case 3:
cout<<"Inserting Node at a Specific Position:"<<endl;
linlist.insert_pos();
cout<<endl;
break;
case 4:
cout<<"Deleting Node at a Specific Position: "<<endl;
linlist.delete_pos();
break;
case 5:
cout<<"Deleting Node at the Last Position: "<<endl;
linlist.delete_last();
break;
case 6:
cout<<"Deleting Node at the Beginning: "<<endl;
linlist.delete_begin();
break;
case 7:
cout<<"Display the linked list"<<endl;
linlist.display();
cout<<endl;
break;
case 8:
cout<<"Exiting Program... Goodbye!"<<endl;
exit(1);
break;
default:
cout<<"Option not viable"<<endl;
}
}
}
The issue is encountered when the compiler gets to line 10 in the driver file. I'll put both error lists from Visual Studio and CodeBlocks below. I'm still grasping C++ so thanks in advance to anyone who decides to help!
Error Log
Other Error Log
The first error:
struct node
{
int info;
struct node *next;
}*start;
You created non-const variable in heaader file. Then this header was included in two source files.
Eventually, you have two variables called 'start' in two object files. That`s why linker throws an error "multiple definition of start".
As was mentioned in the comments, 'start' variable must be moved to linked_list class.
The second error:
main()
should be
int main()

I am getting a breakpoint and i do not know why

I am trying to implement a priority Queue by using a linked list in c++. However, when I run the program it triggers a breakpoint within "priorityQLinkedList::dequeue()" method. Can someone tell why this is the case and give me suggestions on how to fix it?
Code:
#include <iostream>
#include <cstring>
#include <iomanip>
using namespace std;
struct DAT
{
int id;
char fullname[50];
double savings;
};
struct NODE
{
DAT data;
NODE *N;
NODE *P;
NODE(const int i, const char *f, const double s)
{
data.id = i;
strcpy_s(data.fullname, f);
data.savings = s;
N = NULL;
P = NULL;
}
};
class priorityQLinkedList
{
private:
NODE *front;
NODE *back;
public:
priorityQLinkedList() { front = NULL; back = NULL; }
~priorityQLinkedList() { destroyList(); }
void enqueue(NODE *);
NODE* dequeue();
void destroyList();
};
void priorityQLinkedList::enqueue(NODE *n)
{
if (front == NULL) {
front = n;
back = n;
}
else {
NODE *temp = front;
if (n->data.id > temp->data.id)
{
front->P = n;
n->N = front;
front = n;
}
else
{
//search for the posistion for the new node.
while (n->data.id < temp->data.id)
{
if (temp->N == NULL) {
break;
}
temp = temp->N;
}
//New node id's smallest then all others
if (temp->N == NULL && n->data.id < temp->data.id)
{
back->N = n;
n->P = back;
back = n;
}
//New node id's is in the medium range.
else {
temp->P->N = n;
n->P = temp->P;
n->N = temp;
temp->P = n;
}
}
}
}
NODE* priorityQLinkedList::dequeue()
{
NODE *temp;
//no nodes
if (back == NULL) {
return NULL;
}
//there is only one node
else if (back->P == NULL) {
NODE *temp2 = back;
temp = temp2;
front = NULL;
back = NULL;
delete temp2;
return temp;
}
//there are more than one node
else {
NODE *temp2 = back;
temp = temp2;
back = back->P;
back->N = NULL;
delete temp2;
return temp;
}
}
void priorityQLinkedList::destroyList()
{
while (front != NULL) {
NODE *temp = front;
front = front->N;
delete temp;
}
}
void disp(NODE *m) {
if (m == NULL) {
cout << "\nQueue is Empty!!!" << endl;
}
else {
cout << "\nID No. : " << m->data.id;
cout << "\nFull Name : " << m->data.fullname;
cout << "\nSalary : " << setprecision(15) << m->data.savings << endl;
}
}
int main() {
priorityQLinkedList *Queue = new priorityQLinkedList();
NODE No1(101, "Qasim Imtiaz", 567000.0000);
NODE No2(102, "Hamad Ahmed", 360200.0000);
NODE No3(103, "Fahad Ahmed", 726000.0000);
NODE No4(104, "Usmaan Arif", 689000.0000);
Queue->enqueue(&No4);
Queue->enqueue(&No3);
Queue->enqueue(&No1);
Queue->enqueue(&No2);
disp(Queue->dequeue());
disp(Queue->dequeue());
disp(Queue->dequeue());
disp(Queue->dequeue());
disp(Queue->dequeue());
delete Queue;
return 0;
}
One problem which stands out in your dequeue() method is that you are calling delete on a NODE pointer, and then attempting to return this deleted pointer to the caller. This could cause an error either in dequeue() itself, or certainly in the caller who thinks he is getting back a pointer to an actual live NODE object.
One potential fix would be to create a copy of the NODE being dequeued. You would still remove the target from your list, but the caller would then be returned a valid pointer, which he could free later.
NODE* priorityQLinkedList::dequeue()
{
NODE *temp;
// no nodes
if (back == NULL) {
return NULL;
}
NODE *temp2 = back;
temp = new NODE(temp2->data.id, temp2->data.fullname, temp2->data.savings);
// there is only one node
else if (back->P == NULL) {
front = NULL;
back = NULL;
delete temp2;
return temp;
}
// there are more than one node
else {
back = back->P;
back->N = NULL;
delete temp2;
return temp;
}
}
You're deleting pointers in dequeue that priorityQLinkedList does not own, so you don't know if it is safe to delete them.
In this case, they are not since the node pointers passed to enqueue are addresses of local, stacked based variables and have not been allocated by new. (There's also the already mentioned problem of deleting a pointer then returning it, which is Undefined Behavior.)
The fix for the code as shown is to remove the calls to delete in dequeue. However, if changes are made so that the nodes passed to enqueue are dynamically allocated, you'll need to add something to handle that.
1.First change strcpy_s to strcpy is struct NODE.
2.Instead of Delete(temp2) use temp2--.
//no nodes
if (back == NULL) {
return NULL;
}
//there is only one node
else if (back->P == NULL) {
NODE *temp2 = back;
temp = temp2;
front = NULL;
back = NULL;
temp2--;
return temp;
}
//there are more than one node
else {
NODE *temp2 = back;
temp = temp2;
back = back->P;
back->N = NULL;
temp2--;
return temp;
}
I hope this will resolve the problem.

Array getting passed incorrectly to a function in C++

I'm working a project for class that requires creating a binary search tree of criminal names with up to 8 attributes per criminal.
I set up a string array att[] that will read in the attributes for each criminal, and then be passed to my BSTInsert class function. Through debugging I can see that the array is correct when it's just in the setupTree function. Once it's passed to BSTInsert, instead of having each string it only has one string, and on top of that nothing is copied from the array to the node in the tree.
Can anyone tell me what I'm doing wrong?
Here's my code for setting up the tree:
void setupTree(BST& criminals)
{
ifstream fin("criminals.txt");
string temp;
fin >> temp;
//FINISHED means it has all the criminals
while (temp != "FINISHED")
{
//SUSPECT lets it know to read in a new name and new attributes
if (temp == "SUSPECT")
{
string name;
string att[8];
int count = 0;
fin >> temp;
//if there is a false "suspect" line, quit
if (temp == "FINISHED") return;
name = temp;
fin >> temp;
while (temp != "SUSPECT" && temp != "FINISHED")
{
att[count] = temp;
count++;
fin >> temp;
}
criminals.BSTInsert(name, att, count);
}
}
}
Here's my class function for inserting a node:
bool BST::BSTInsert(treetype name, treetype att[], int count)
{
//gets the memory for the node. If unable, returns fail.
node* newNode = new node;
if (newNode == NULL)
{
return false;
}
newNode->count = 0;
//initializes the node with the given information to place
for (int i = 0; i < count; i++)
{
newNode->att[newNode->count] = att[count];
newNode->count++;
}
newNode->name = name;
newNode->left = newNode->right = NULL;
//if the tree is empty, creates this node as the root
if (root == NULL)
{
root = newNode;
root->parent = NULL;
}
else
{
//the tree is not empty, so it will use the parent to insert the node
node* current = root;
node* parent = NULL;
//finds the insertion spot
while (current != NULL)
{
parent = current;
if (name <= current->name)
{
current = current->left;
}
else
{
current = current->right;
}
}
//inserts the new node onto the correct side of the parent
if (name <= parent->name)
{
parent->left = newNode;
}
else
{
parent->right = newNode;
}
newNode->parent = parent;
}
return true;
treetype att[] doesn't pass an array, it passes a pointer to an array - it decays to treetype att*.
That said, your problem is here:
for (int i = 0; i < count; i++)
{
newNode->att[newNode->count] = att[count];
newNode->count++;
}
This copies the wrong element of att (beyond the end of the array) into every att in newNode. What you meant was
for (int i = 0; i < count; i++)
{
newNode->att[newNode->count] = att[newNode->count];
newNode->count++;
}

Access violation reading location 0xCCCCCCCC error in linklist

Why does the above error occur when calling showNode()?
#include<iostream>
#define NULL 0
using namespace std;
class myNode{
private:
int data;
myNode* link;
myNode* first;
public:
myNode(){
data=0;
link=NULL;
first=NULL;
}
void insertNode(int value, int iposition){
myNode n;
if (iposition==1)
{
first=&n;
cout<<first<<endl;
n.data=value;
n.link=NULL;
}
if (iposition>1)
{
int nodeCounter=1;
myNode* temp=first;
while (temp->link != NULL)
{
nodeCounter++;
}// this while counts the number of inserted nodes.
if (iposition>nodeCounter)//if the position of the new node is greater than number of inserted node,
//it will be inserted at the end.
{
cout<<"Node will be inserted at end."<<endl;
myNode* ieTemp=first;
while (ieTemp->link != NULL)
{
ieTemp=ieTemp->link;
cout<<ieTemp->data<<endl;
}
ieTemp->link=&n;
n.data=value;
n.link=NULL;
cout<<&n<<" ";
}
else
{
myNode* imTemp=first;
while (iposition-1)
{
imTemp=imTemp->link;
iposition--;
}
n.link=imTemp->link;
n.data=value;
imTemp->link=&n;
}
}
}//end insertNode
void showNode(){
myNode* sTemp=first;
while (sTemp != NULL)
{
cout<<sTemp->data<<" ";
sTemp=sTemp->link;
}
}//end showNode
};
int main(){
myNode a;
a.insertNode(10,1);
a.insertNode(20,2);
a.insertNode(25,3);
a.insertNode(30,4);
a.insertNode(40,5);
a.showNode();
system("pause");
}
First you must declare myNode *n = new myNode(); because you use it outside of insertNode function. Second you may want to check if first node exist to avoid error on inserting first node on any other position than 1 (in your case if your first insert will be like inserNode(x, y != 1) will throw an error because you try to access first node (here: while (temp->link != NULL))) but this node don't exist.
This is what I think you want:
void insertNode(int value, int iposition){
myNode *n = new myNode();
myNode *cur = first;
//insert first node or on first position
if (cur == NULL || iposition <= 1) {
n->data = value;
if (cur == NULL) { //first node
n->link = NULL;
}
else { //first position
n->link = first;
}
first = n;
return;
}
for (int i = 1; i < iposition - 1; i++) { //find given position
if (cur->link == NULL) { //if end
n->data = value;
n->link = NULL;
cur->link = n;
return;
}
cur = cur->link;
}
//here we are on position = iposition-1
n->data = value;
n->link = cur->link;
cur->link = n;
}//end insertNode

Add method not returning any values

I am writing an add method for a Linked List class in C++. The add method is written to handle a variety of situations that may occur based on the input of the method. I have added "cout" statements in order to try and track which loops/if-statements the method is going into, but nothing is being printed from the method. The input for the method are the index of the node and the data that is held in the node.
void linkedList::add(int pos, string item)
{
Node *temp = new Node;
Node *nextTemp = new Node;
if(pos == 0)
{
cout<< "hey";
if(head != NULL)
{
cout<< "hey1";
temp->setData((head->getPosition()+1),
head->getItem(), head->getNextNode());
head->setData(pos, item, temp);
currentNode = head;
size++;
}
else
{
cout<< "hey2";
head->setData(pos, item, temp);
currentNode = head;
size++;
}
}
else if(pos == size)
{
cout<< "hey3";
while(currentNode != NULL)
{
cout<< "hey4";
currentNode = currentNode->nextNode;
}
temp->setData(pos, item, nextTemp);
currentNode->nextNode = temp;
size++;
}
else
{
cout<< "hey5";
for(int i = 0; i<size; i++)
{
cout<< "hey6";
if(i == currentNode->getPosition())
{
cout<< "hey7";
temp->setData(currentNode->getPosition(),
currentNode->getItem(), currentNode->getNextNode());
currentNode->setData(pos, item, temp);
size++;
}
currentNode = currentNode->nextNode;
while(currentNode->getPosition() < (size+1))
{
cout<< "hey8";
currentNode->setPosition(i+1);
currentNode = currentNode->nextNode;
}
}
}
}
Any help would be appreciated. Thank you.