Why is this string changed? - c++

I have the following code, so far, I want to check if a file name is already in the linked list fileList (or flist). according to the output, the string saved in the first Node was changed somewhere in Node* getFileName(Node *&flist) How did this happen? Also, is there anything else that I'm doing is wrong or not safe regarding pointers of Node and strings?
output:
in main: file4.txt
start of process: file4.txt
file4.txt
mid of process: file4.txt"
in contains, fileName in node: file4.txt"
in contains, target file name: file4.txt
end of process: file4.txt"
0
no recursive call
code:
struct Node {
string fileName;
Node *link;
};
/*
*
*/
bool contains (Node *&flist, string &name) {
Node *tempNode = *&flist;
while (tempNode != 0) {
cout << "in contains, fileName in node: " << flist->fileName << endl;
cout << "in contains, target file name: " << name << endl;
if ((tempNode->fileName) == name) {
return true;
}
else {
tempNode = tempNode->link;
}
}
return false;
}
/*
*
*/
Node* getLastNode (Node *&flist) {
Node *tempNode = *&flist;
while (tempNode != 0) {
tempNode = tempNode->link;
}
return tempNode;
}
/*
*
*/
string getFileName(string oneLine) {
char doubleQuote;
doubleQuote = oneLine[9];
if (doubleQuote == '\"') {
string sub = oneLine.substr(10); //getting the file name
string::size_type n = sub.size();
sub = sub.substr(0,n-1);
cout << sub << endl;
return sub;
}
return NULL;
}
/*
*
*/
void process( istream &in, ostream &out, Node *&flist ) {
cout << "start of process: " << flist->fileName << endl;
string oneLine; //temp line holder
while (getline(in, oneLine)) {
// cout << oneLine << endl;
string::size_type loc = oneLine.find("#include",0);
if (loc != string::npos) {
//found one line starting with "#include"
string name;
name = getFileName(oneLine);
cout << "mid of process: " << flist->fileName << endl;
bool recursive;
recursive = contains(flist, name);
cout << "end of process: " << flist->fileName << endl;
cout << recursive << endl;
if (recursive) {
//contains recursive include
cerr << "recursive include of file " << name << endl;
exit(-1);
}
else {
//valid include
cout << "no recursive call" << endl;
}//else
}//if
}//while
}//process
/*
*
*/
int main( int argc, char *argv[] ) {
istream *infile = &cin; // default value
ostream *outfile = &cout; // default value
Node* fileList;
switch ( argc ) {
case 3:
outfile = new ofstream( argv[2] ); // open the outfile file
if ( outfile->fail() ) {
cerr << "Can't open output file " << argv[2] << endl;
exit( -1 );
}
// FALL THROUGH to handle input file
case 2:
infile = new ifstream( argv[1] ); // open the input file
if ( infile->fail() ) {
cerr << "Can't open input file " << argv[1] << endl;
exit( -1 );
}
else {
Node aFile = {argv[1], 0};
fileList = &aFile;
cout << "in main: " << fileList->fileName << endl;
}
// FALL THROUGH
case 1: // use cin and cout
break;
default: // too many arguments
cerr << "Usage: " << argv[0] << " [ input-file [ output-file ] ]" << endl;
exit( -1 ); // TERMINATE!
}
processOneFile (*infile, *outfile, fileList);
// do something
if ( infile != &cin ) delete infile; // close file, do not delete cin!
if ( outfile != &cout ) delete outfile; // close file, do not delete cout!
}

Could you post the original code? The code you posted doesn't even compile.
Errors I've noticed, in order:
processOneFile (*infile, *outfile, fileList);
There is no processOneFile() procedure.
istream *infile = &cin; // default value
ostream *outfile = &cout; // default value
Node* fileList;
case 1: // use cin and cout
break;
processOneFile (*infile, *outfile, fileList);
This will call processOneFile() with an uninitialized file list, which will crash when you try to print the file name.
else {
Node aFile = {argv[1], 0};
fileList = &aFile;
cout << "in main: " << fileList->fileName << endl;
}
aFile is only in scope within that else, so trying to use a pointer to it later will fail.
string getFileName(string oneLine) {
///
return NULL;
}
You can't construct a std::string from NULL -- this will crash the program.
After fixing these errors so your code wouldn't crash, I couldn't reproduce the error.
If you're building in Linux, try increasing the warning level (with g++ -Wall -Wextra -ansi -pedantic) and running your code through valgrind, to check for memory errors.

Ok, the code does now seem like it works as expected:
#include <iostream>
#include <fstream>
using namespace::std;
struct Node
{
string fileName;
Node *link;
};
bool contains (Node *&flist, string &name)
{
Node *tempNode = *&flist;
while (tempNode != 0)
{
cout << "Searching in \"" << flist->fileName;
cout << "\" for \"" << name << "\"" << endl;
if ( tempNode->fileName == name)
{
return true;
}
else
{
tempNode = tempNode->link;
}
}
return false;
}
Node* getLastNode (Node *&flist)
{
Node *tempNode = *&flist;
while (tempNode != 0)
{
tempNode = tempNode->link;
}
return tempNode;
}
string getFileName(string oneLine)
{
char doubleQuote;
doubleQuote = oneLine[9];
if (doubleQuote == '\"') {
string sub = oneLine.substr(10); //getting the file name
string::size_type n = sub.size();
sub = sub.substr(0,n-1);
return sub;
}
return "";
}
void process( istream &in, ostream &out, Node *&flist )
{
cout << "Start of process: " << flist->fileName << endl << endl;
string oneLine;
while (1)
{
cout << "Input include statement: ";
getline(in, oneLine);
if (oneLine == "STOP")
return;
string::size_type loc = oneLine.find("#include",0);
if (loc != string::npos)
{
//found one line starting with "#include"
string name;
name = getFileName(oneLine);
if (name == "")
{
cout << "Couldn't find filename, skipping line..." << endl;
continue;
}
if (contains(flist, name))
{
//contains recursive include
cerr << "Uh, oh! Recursive include of file " << name << endl;
exit(-1);
}
else
{
cerr << "No recursive include" << endl;
}
}//if
cout << endl;
}//while
}
int main( int argc, char *argv[] )
{
Node* fileList = new Node;
istream *infile = &cin; // default value
ostream *outfile = &cout; // default value
fileList->fileName = "Input"; // default value
switch ( argc )
{
case 3:
outfile = new ofstream( argv[2] ); // open the outfile file
if ( outfile->fail() ) {
cerr << "Can't open output file " << argv[2] << endl;
exit( -1 );
}
// FALL THROUGH to handle input file
case 2:
infile = new ifstream( argv[1] ); // open the input file
if ( infile->fail() ) {
cerr << "Can't open input file " << argv[1] << endl;
exit( -1 );
}
else {
fileList->fileName = argv[1];
cout << "in main: " << fileList->fileName << endl;
}
// FALL THROUGH
case 1: // use cin and cout
break;
default: // too many arguments
cerr << "Usage: " << argv[0] << " [ input-file [ output-file ] ]" << endl;
exit( -1 ); // TERMINATE!
}
process(*infile, *outfile, fileList);
// do something
if ( infile != &cin ) delete infile; // close file, do not delete cin!
if ( outfile != &cout ) delete outfile; // close file, do not delete cout!
}

Also, why are you wasting time writing your own linked list when the standard library already has a perfectly good one?

Related

Infinity Loop in Lexical Analyzer in C++

int main(int argc, char *argv[]) {
ifstream inFile;
int numOfLines = 0, numOfTokens = 0, numOfStrings = 0, maxStringLength = 0, l = 0, fileCount=0, mostCommonCount=0;
string inputFile, mostCommonList="", word;
for(int i = 1; i < argc; i++){
if(strpbrk(argv[i] , "-")){
if(flags.find(string(argv[i]))!=flags.end()) flags[string(argv[i])] = true;
else{
cerr << "INVALID FLAG " << argv[i] << endl;
exit(1);
}
}
else{
inFile.open(argv[i]);
fileCount++;
if(!inFile && fileCount==1){
cerr << "UNABLE TO OPEN " << argv[i] << endl;
exit(1);
}
else{
string line;
while(getline(inFile, line)) inputFile+=line+='\n';
if(fileCount>1){
cerr << "TOO MANY FILE NAMES" << endl;
exit(1);
}
}
}
}
int linenum = 0;
TType tt;
Token tok;
while((tok = getNextToken(&inFile, &linenum))!=DONE && tok != ERR){
tt = tok.GetTokenType();
word = tok.GetLexeme();
if(flags["-v"]==true){
(tt == ICONST||tt==SCONST||tt==IDENT) ? cout<<enumTypes[tok.GetTokenType()]<<"("<< tok.GetLexeme()<<")"<<endl : cout<< enumTypes[tok.GetTokenType()]<<endl;
}
if(flags["-mci"]==true){
if(tt==IDENT){
(identMap.find(word)!=identMap.end()) ? identMap[word]++ : identMap[word]=1;
if(identMap[word]>mostCommonCount) mostCommonCount = identMap[word];
}
}
if(flags["-sum"]==true){
numOfTokens++;
if(tt==SCONST){
numOfStrings++;
l = word.length();
if(l > maxStringLength) maxStringLength = l;
}
}
}
if(tok==ERR){
cout << "Error on line" << tok.GetLinenum()<<"("<<tok.GetLexeme()<<")"<<endl;
return 0;
}
if(flags["-mci"]==true){
cout << "Most Common Identifier: ";
if(!identMap.empty()){
word ="";
for(auto const& it : identMap){
if(it.second==mostCommonCount) word += it.first + ",";
}
word.pop_back();
cout << word << endl;
}
}
if(flags["-sum"]){
numOfLines = tok.GetLinenum();
numOfLines = tok.GetLinenum();
cout << "Total lines: " << numOfLines << endl;
cout << "Total tokens: " << numOfTokens << endl;
cout << "Total strings: " << numOfStrings << endl;
cout << "Length of longest string: " << maxStringLength << endl;
}
inFile.close();
return 0;
}
For some reason this code is running infinitely. I cannot figure out the source of error. I also do not know whether this file or the other linked file is causing this error so I posted the main program code. I think is one of the switch statements that causing this error but I am not sure. FYI: I am supposed to make a lexical analyzer so I had three files one lexigh.h (contains all the data types and all the functions), getToken.cpp(file that defines the functions from lexigh.h) and the main program which calls the methods and tests it.

Segmentation Fault 11 on return

I realize there are other answers like this one but seg faults are pretty general and none of them fit my situation exactly. I am creating a binary tree and storing data. In the printInOrder function, it recurses all the way to the furthest leftChild and then seg faults when it reaches the return statement. I am not sure why it is doing this. Thanks in advance for the help.
#include <string>
#include <cstdlib>
#include <iostream>
#include "BST.h"
using namespace std;
BST::BST(void) {
root = NULL;
cout << "Default object is being creating." << "\n";
};
/*
BST::BST(string word, int count) {
cout << "Default object is being creating." << "\n";
this->root->word = word;
this->root->count = count;
};
BST::BST(string word) {
cout << "Default object is being creating." << "\n";
this->root->word = word;
this->root->count = 1;
};
*/
bool BST::hasWord(string word) {
return true;
};
void BST::printInOrder() {
pio(this->root);
}
void BST::pio(struct node* node) {
cout << "root: " << root << endl;
cout << "node: " << node << endl;
cout << "leftChild: " << node->leftChild->leftChild << endl;
if (node != NULL){
/* first recur on left child */
pio(node->leftChild);
/* then print the data of node */
cout << "Word: " << node->word << endl;
cout << "Count: " << node->count << endl;
/* now recur on right child */
pio(node->rightChild);
}
if (node == NULL) {
return;
}
}
void BST::insert(string word)
{
if(this->root != NULL)
insert(word, this->root);
else
{
cout << "obj has been inserted " << endl;
this->root = new node;
cout << root << endl;
this->root->word = word;
this->root->count = 1;
this->root->leftChild = NULL;
this->root->rightChild = NULL;
}
}
void BST::insert(string word, struct node *leaf)
{
if(word< leaf->word)
{
if(leaf->leftChild != NULL)
insert(word, leaf->leftChild);
else
{
cout << "obj has been inserted " << endl;
leaf->leftChild = new node;
cout << leaf->leftChild << endl;
leaf->leftChild->word = word;
leaf->leftChild->count = 1;
leaf->leftChild->leftChild = NULL; //Sets the leftChild child of the child node to null
leaf->leftChild->rightChild = NULL; //Sets the rightChild child of the child node to null
}
}
else if(word>leaf->word)
{
if(leaf->rightChild != NULL)
insert(word, leaf->rightChild);
else
{
cout << "obj has been inserted " << endl;
leaf->rightChild = new node;
cout << leaf->rightChild << endl;
leaf->rightChild->word = word;
leaf->rightChild->count = 1;
leaf->rightChild->leftChild = NULL; //Sets the leftChild child of the child node to null
leaf->rightChild->rightChild = NULL; //Sets the rightChild child of the child node to null
}
}
//word is already in the tree so we increment counter
else leaf->count += 1;
}
Main file:
#include <string>
#include <vector>
#include <fstream>
#include <iostream>
#include <dirent.h>
#include <cstring>
#include <functional>
#include <algorithm>
#include <sstream>
#include "BST.h"
using namespace std;
void parseFile(string fullPath, BST bst) {
ifstream infile(fullPath); // Open it up!
std::string line;
char c;
string word = "";
while (std::getline(infile, line))
{
// Iterate through the string one letter at a time.
for (int i = 0; i < line.length(); i++) {
c = line.at(i); // Get a char from string
tolower(c);
// if it's NOT within these bounds, then it's not a character
if (! ( ( c >= 'a' && c <= 'z' ) || ( c >= 'A' && c <= 'Z' ) ) ) {
//if word is NOT an empty string, insert word into bst
if ( word != "" ) {
bst.insert(word);
//reset word string
word = "";
}
}
else {
word += string(1, c);
}
}
}
}
void getReqDirs(BST bst, const string path, vector<string> files,const bool showHiddenDirs = false){
DIR *dpdf;
struct dirent *epdf;
dpdf = opendir(path.c_str());
int count = 0;
if (dpdf != NULL){
while ((epdf = readdir(dpdf)) != NULL){
if(showHiddenDirs ? (epdf->d_type==DT_DIR && string(epdf->d_name) != ".." && string(epdf->d_name) != "." ) : (epdf->d_type==DT_DIR && strstr(epdf->d_name,"..") == NULL && strstr(epdf->d_name,".") == NULL ) ){
getReqDirs(bst,path+epdf->d_name+"/",files, showHiddenDirs);
}
if(epdf->d_type==DT_REG){
//files.push_back(path+epdf->d_name);
//parseFile(path+epdf->d_name, bst);
cout << path+epdf->d_name << " ";
}
}
}
closedir(dpdf);
}
int main()
{
vector <string> words; // Vector to hold our words we read in.
string str; // Temp string to
cout << "Read from a file!" << endl;
BST bst;
string path = "test/"; //name of directory that holds the data base
vector<string> files; //create vector for file names
/*
//collect all the file names in the data base
getReqDirs(bst,path,files,false);
for (int i = 0; i < files.size(); i++) {
cout << files[i] << " ";
}*/
bst.insert("gary");
bst.insert("Mil");
bst.insert("Taylor");
bst.insert("BrIaN");
bst.insert("fart");
bst.insert("Juan");
bst.insert("James");
bst.insert("Gary");
bst.printInOrder();
//parseFile(path, bst);
return 0;
}
Please let me know if any other info is required.
The following line is the only problematic line of code I found in pio:
cout << "leftChild: " << node->leftChild->leftChild << endl;
It is a problem since node is bound be NULL at some point.
Remove that line.
Also, you don't need the lines
if (node == NULL) {
return;
}
They don't do anything useful and can be removed. Here's an updated version of the function:
void BST::pio(struct node* node) {
cout << "root: " << root << endl;
cout << "node: " << node << endl;
if (node != NULL){
/* first recur on left child */
pio(node->leftChild);
/* then print the data of node */
cout << "Word: " << node->word << endl;
cout << "Count: " << node->count << endl;
/* now recur on right child */
pio(node->rightChild);
}
}

Using a print function to output to a new file

I have a program analyzing the number of distinct and total words in a text file and then writing it to a new output file. I've got the first part down, but I don't know how to get my print function to print onto the new text file. Printing the total words or distinct words onto the new file works but the Print2() function doesn't seem to work. Please take a look at the //POINT OF INTEREST// section, where i believe the problem stems.
#include <iostream>
#include <fstream>
#include <string>
#include <cctype>
int distinctWord = 0;
using namespace std;
typedef int ItemType;
struct Node {
string word;
int count = 1;
Node* left;
Node* right;
};
class TreeType {
private:
Node* root;
void Insert(Node*& root, string word);
void Destroy(Node*& root);
void PrintTree(Node* root);
void Print2File(Node* root, ofstream& fout);
public:
TreeType() {root = nullptr;}
~TreeType();
void PutItem(string word);
void Print();
void Print2(ofstream& fout);
};
void TreeType::Print() {
PrintTree(root);
cout << endl;
}
void TreeType::PrintTree(Node* root) {
if (root == nullptr)
return;
PrintTree(root->left);
cout << root->word << " " << root->count << endl;
PrintTree(root->right);
}
///////////////POINT OF INTEREST///////////////////////////
///////////////POINT OF INTEREST///////////////////////////
void TreeType::Print2File(Node* root, ofstream& fout){
if (root == nullptr)
return;
PrintTree(root->left);
fout << root->word << " " << root->count << endl;
PrintTree(root->right);
}
void TreeType::Print2(ofstream& fout) {
Print2File(root, fout);
cout << "Printed to another file" << endl;
}
///////////////POINT OF INTEREST///////////////////////////
///////////////POINT OF INTEREST///////////////////////////
void TreeType::PutItem(string word) {
Insert(root, word);
}
void TreeType::Insert(Node*& root, string word) {
if (root == nullptr) {
root = new Node;
distinctWord++;
root->word = word;
root->right = nullptr;
root->left = nullptr;
return;
}
if(root->word == word){
root->count++;
return;
}else if (word < root->word)
Insert(root->left, word);
else
Insert(root->right, word);
}
TreeType::~TreeType() {
Destroy(root);
}
int main(int argc, const char * argv[]) {
int totalwords = 0;
ifstream file;
string word;
char c;
ofstream fout;
ifstream file;
string filename;
cout << "Enter name of file with text to analyze: ";
cin >> filename;
fin.open(filename.c_str());
if (fin.fail()) {
cout << "Error opening file.\n";
exit(1);
}
cout << "\nAnalyzing " << filename << ".\n";
TreeType t;
while(!file.eof()){
file.get(c);
if(isalpha(c) || c == '\''){
word += c;
c = '\0';
}else if(c == ' ' || c == '\n' || c == '-' || c == '.'){
if(isalpha(word[0])){
transform(word.begin(), word.end(), word.begin(), ::tolower);
t.PutItem(word);
totalwords++;
word = "";
c = '\0';
}
}
}if(isalpha(word[0])){
transform(word.begin(), word.end(), word.begin(), ::tolower);
t.PutItem(word);
totalwords++;
}
file.close();
fout.open("results.txt");
cout << "\nWord counts:\n\n";
t.Print();
t.Print2(fout);
cout << "\nTotal number of words in text: " << totalwords << ".\n";
fout << "\nTotal number of words in text: " << totalwords << ".\n";
cout << "Number of distinct words appearing in text: "
<< distinctWord << ".\n";
fout << "Number of distinct words appearing in text: "
<< distinctWord << ".\n";
fout.close();
return 0;
}
You will have to pass your output file stream to your
PrintTree(root); too.
Right now you are printing to cout which will dump everything to whatever console your application is associated with.
The modified function after adding the ofstream parameter becomes:
void TreeType::PrintTree(Node* root, ofstream &fout) {
if (root == nullptr)
return;
PrintTree(root->left, fout);
fout << root->word << " " << root->count << endl;
PrintTree(root->right, fout);
}
You will need to pass the ofstream object throughout in all callers of PrintTree

Where can I use OpenMP in my C++ code

I am writing a C++ code to calculate the code coverage and I want to used the OpenMP to help enhance my code by minimizing the overall run time by making the functions work in parallel so I can get less run time.
Can someone please tell me how and where to use the OpenMP?
int _tmain(int argc, _TCHAR* argv[])
{
std::clock_t start;
start = std::clock();
char inputFilename[] = "Test-Case-3.cs"; // Test Case File
char outputFilename[] = "Result.txt"; // Result File
int totalNumberOfLines = 0;
int numberOfBranches = 0;
int statementsCovered = 0;
float statementCoveragePercentage = 0;
double overallRuntime = 0;
ifstream inFile; // object for reading from a file
ofstream outFile; // object for writing to a file
inFile.open(inputFilename, ios::in);
if (!inFile) {
cerr << "Can't open input file " << inputFilename << endl;
exit(1);
}
totalNumberOfLines = NoOfLines(inFile);
inFile.clear(); // reset
inFile.seekg(0, ios::beg);
numberOfBranches = NoOfBranches(inFile);
inFile.close();
statementsCovered = totalNumberOfLines - numberOfBranches;
statementCoveragePercentage = (float)statementsCovered * 100/ totalNumberOfLines;
outFile.open(outputFilename, ios::out);
if (!outFile) {
cerr << "Can't open output file " << outputFilename << endl;
exit(1);
}
outFile << "Total Number of Lines" << " : " << totalNumberOfLines << endl;
outFile << "Number of Branches" << " : " << numberOfBranches << endl;
outFile << "Statements Covered" << " : " << statementsCovered << endl;
outFile << "Statement Coverage Percentage" << " : " << statementCoveragePercentage <<"%"<< endl;
overallRuntime = (std::clock() - start) / (double)CLOCKS_PER_SEC;
outFile << "Overall Runtime" << " : " << overallRuntime << " Seconds"<< endl;
outFile.close();
}
i want to minimize the time taken to count the number of branches by allowing multiple threads to work in parallel to calculate the number faster? how can i edit the code so that i can use the open mp and here you can find my functions:bool is_only_ascii_whitespace(const std::string& str)
{
auto it = str.begin();
do {
if (it == str.end()) return true;
} while (*it >= 0 && *it <= 0x7f && std::isspace(*(it++)));
// one of these conditions will be optimized away by the compiler,
// which one depends on whether char is signed or not
return false;
}
// Function 1
int NoOfLines(ifstream& inFile)
{
//char line[1000];
string line;
int lines = 0;
while (!inFile.eof()) {
getline(inFile, line);
//cout << line << endl;
if ((line.find("//") == std::string::npos)) // Remove Comments
{
if (!is_only_ascii_whitespace(line)) // Remove Blank
{
lines++;
}
}
//cout << line << "~" <<endl;
}
return lines;
}
// Function 2
int NoOfBranches(ifstream& inFile)
{
//char line[1000];
string line;
int branches = 0;
while (!inFile.eof()) {
getline(inFile, line);
if ((line.find("if") != std::string::npos) || (line.find("else") != std::string::npos))
{
branches++;
}
}
return branches;
}

cardealership with dead end - Endless loop and no solution

I just can't seem to figure out why my code doesn't work.
My program is about reading two text files representing a cardealership, and putting the input into a linked list or an STL list depending on mode. Then the orders are read and depending on the availability an error log is created.
The thng is that it keeps on looping in the linked list mode and that is doesn't seem to write the error log.
I feel pretty stupid about this. I don't want you guys to solve the error but teach me how to do it. I'm thankful for any review of my code by more experienced people.
I've tried debugging in Eclipse in XCode and in VS2012(VM with Win8). In none of the IDEs the variables are shown in the debug editor which I just don't understand. I use the MacOSX GCC Compiler.
So here are the txt files:
input.txt
Brera 3
Golf 5
Punto 13
Fiesta 19
and orders.txt
323 Brera 1
324 Golf 6
354 Punto 3
337 Gobldibock 1
this is my main method:
// file main.cpp
#include "cardealership.hpp"
#include <fstream>
#include <iostream>
#include <sstream>
#include <string>
int main( int argc, char* argv[] ) {
std::cout << "argv[2]: " << argv[2] << "\n";
std::cout << "argv[3]: " << argv[3] <<"\n";
const unsigned int mode = atoi( argv[1]);
std::string arg2 = argv[2];
std::string arg3 = argv[2];
cardealership* dealer = new cardealership(arg2, arg3, mode);
std::cout << "dealership created" << "\n";
dealer->readInputFileToList();
std::cout << "still running" << "\n";
dealer->readOutputFileAndAlterInventory();
std::cout << "finishing" << "\n";
return 0;
}
Here are the header of the class containing the actual lists:
// file cardealership.hpp
#ifndef CARDEALERSHIP_HPP // prevent multiple inclusions
#define CARDEALERSHIP_HPP
#include <string>
#include <list>
#include <vector>
typedef struct linkedNode
{
char* data; // will store information
int amountOfCars;
linkedNode* next; // the reference to the next node.
};
class cardealership
{
public:
cardealership (std::string inputFile, std::string ordersFile, const unsigned int mode);
~cardealership();
void readInputFileToList();
void readOutputFileAndAlterInventory();
void printInventory (); //TODO
private:
const unsigned int mode;
std::string inputFile;
std::string ordersFile;
std::list<linkedNode*> listOfCars; //Using Linked Node without linking them...
std::vector<linkedNode*> linkedListOfCars;
};
#endif
and the footer:
// file cardealership.cpp
#include "cardealership.hpp"
#include <iostream>
#include <cstring>
#include <fstream>
#include <sstream>
cardealership::cardealership(std::string inputFile, std::string ordersFile, const unsigned int mode)
: inputFile(inputFile),
ordersFile(ordersFile),
mode(mode)
{}
cardealership::~cardealership()
{
listOfCars.clear();
linkedListOfCars.clear();
}
void cardealership::readInputFileToList(){
std::ifstream infile;
std::string line;
infile.open(inputFile.c_str(),
std::ifstream::in);
if (!infile.good()){
std::cout << "Na na na Input File" << "\n";
}
linkedNode* previousNode;
while(getline(infile, line)){
char* model;
int amountOfCars;
linkedNode* tmpNode;
std::stringstream helperStream;
getline(infile, line);
helperStream << line;
helperStream >> model;
helperStream >> amountOfCars;
//Test
std::cout << "Line: " << line << std::endl;
std::cout << model << ", " << amountOfCars << std::endl;
tmpNode->data = model;
tmpNode->amountOfCars = amountOfCars;
if (mode == 0) { //Use linked list
if(previousNode != NULL){
previousNode->next = tmpNode; //Link that shit
previousNode = tmpNode;
linkedListOfCars.push_back(tmpNode);
}
else{
linkedListOfCars.push_back(tmpNode);
}
}
else if (mode == 1){ //Use STL list
listOfCars.push_back(tmpNode);
}
else{
std::cout<< "invalid mode" << std::endl;
}
if (infile.eof()){
break; // Not too nice but necessary because of last line problem
}
}
infile.close();
}
void cardealership::readOutputFileAndAlterInventory(){
std::ifstream infile;
std::string line;
infile.open(ordersFile.c_str(), std::ifstream::in);
if (!infile.good()){
std::cout << "Na na na Orders File" << "\n";
}
int id;
char* model;
int amountNeeded;
std::ofstream log("errorLog.txt");
if (!log.good()){
std::cout << "Na na na Log File" << "\n";
}
while (getline(infile, line)){
getline(infile, line);
std::stringstream helperStream;
helperStream << line;
helperStream >> id;
helperStream >> model;
helperStream >> amountNeeded;
if (mode == 0) { //Use linked list
linkedNode* tmpNode;
linkedNode* previousNode;
if (!linkedListOfCars.empty()){
tmpNode = linkedListOfCars.front();
while(tmpNode){
if (tmpNode->data == model) {
std::cout<< "Model found!" << std::endl;
}
if (tmpNode->amountOfCars > amountNeeded){
std::cout<< "Enough cars available!" << std::endl;
tmpNode->amountOfCars -= amountNeeded;
}
if (tmpNode->amountOfCars <= amountNeeded){ //
if (previousNode != NULL) {
linkedNode tmp3Node = *previousNode;
tmp3Node.next = tmpNode->next;
}
linkedNode* tmp2Node;
tmp2Node = tmpNode->next;
tmpNode = NULL;
tmpNode = tmp2Node;
//write error to log
log << "ID: "<< id << ", Not enough items!";
previousNode = tmpNode;
tmpNode = tmpNode->next;
}
}
if (!tmpNode) {
std::cout<< "Model not found." << std::endl;
//write error to log.
log << "ID: "<< id << ", Model not available!";
}
}
else{
std::cout<< "No cars to sell." << std::endl;
}
}
else if (mode == 1){ //Use STL list
if (!listOfCars.empty()) {
//Iterator copied and adapted from: http://www.cplusplus.com/reference/stl/list/begin/
std::list<linkedNode*>::iterator it;
for ( it=listOfCars.begin() ; it != listOfCars.end(); it++ ){
linkedNode* tmpNode = *it;
if (tmpNode->data == model) {
std::cout<< "Model found!" << std::endl;
}
if (tmpNode->amountOfCars >= amountNeeded){
std::cout<< "Enough cars available!" << std::endl;
tmpNode->amountOfCars -= amountNeeded;
}
if (tmpNode->amountOfCars < amountNeeded){
//delete entry and write error to log
it = listOfCars.erase(it);
log << "ID: "<< id << ", Not enough items!";
}
if (it++ == listOfCars.end()) {
//Write error to log if end of list is reached
log << "ID: "<< id << ", Model not available!";
}
}
}
else{
std::cout<< "No cars to sell." << std::endl;
}
}
else{
std::cout<< "Invalid mode." << std::endl;
}
}
infile.close();
}
void cardealership::printInventory (){
if (mode == 0) { //Use linked list
}
}
The post seems pretty long to me now but I hope I can still get some help...
Thanks in advance,
L
When adding a new linkedNode you declare a pointer to a node:
linkedNode* tmpNode;
The next mention of tmpNode is the following:
tmpNode->data = model;
However, tmpNode isn't a linkedNode, it's just a pointer to one. You're basically trying to save some data into space that other parts of your program may use. You need to make a linkedNode for tmpNode to point to so that it has its own storage. You may want to look into the new keyword.