C++ program crashing on exit, Access violation in memory [closed] - c++

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 6 years ago.
Improve this question
I have written a program to help me keep track of finances, I am using an array of structs to sore all the information and write it to a file. However, every time I select the option to close the program, it crashes with two separate errors.
Edit
This error occurs without running anything in the code. I open the program, select exit, and CRASH # return 0;
Output-Debug
Exception thrown at 0x0121A2D0 in USAA_C.exe: 0xC0000005: Access violation writing location 0x0052004F.
Stack Trace
USAA_C.exe!std::_Container_base12::_Orphan_all() Line 222 C++
USAA_C.exe!std::_String_alloc<std::_String_base_types<char,std::allocator<char> > >::_Orphan_all() Line 671 C++
USAA_C.exe!std::_String_alloc<std::_String_base_types<char,std::allocator<char> > >::_Free_proxy() Line 647 C++
USAA_C.exe!std::_String_alloc<std::_String_base_types<char,std::allocator<char> > >::~_String_alloc<std::_String_base_types<char,std::allocator<char> > >() Line 611 C++
USAA_C.exe!std::basic_string<char,std::char_traits<char>,std::allocator<char> >::~basic_string<char,std::char_traits<char>,std::allocator<char> >() Line 1007 C++
USAA_C.exe!Transaction::~Transaction() Line 10 C++
[External Code]
USAA_C.exe!main(int argc, char * * argv) Line 583 C++
[External Code]
[Frames below may be incorrect and/or missing, no symbols loaded for kernel32.dll]
Structure
struct Transaction {
Transaction(){}
~Transaction() {}
int day;
int month;
int year;
char status;
string name;
string method;
string cat;
double amount;
double balance;
};
Initialization
const int maxRecs = 1200;
Transaction record[maxRecs];
Transaction temp[maxRecs];
The only code that runs from explicitly opening and closing.
PS: I am using VS 2015
#include <iostream>
#include <string>
#include <iomanip>
#include <fstream>
using namespace std;
struct Transaction {
Transaction(){}
~Transaction() {}
int day;
int month;
int year;
char status;
string name;
string method;
string cat;
double amount;
double balance;
};
int main(int argc, char **argv) {
int sel = 0; // Integer option selections
int c = 0; // For loop iterator
int i = 1; // iterator
int count = 0; // Counter
int numRecsYr = 0; // Counts number of records in year array
int day = 0; // System day
int month = 0; // Sytem month
int year = 0; // System year
int fileSize = 0;
int bytesRead = 0;
string filename1 = "usaa_c.dat"; // default data file name
const int maxRecs = 10; // Maximum number of records to load
const int MENU = 7; // Number of menu items
Transaction record[maxRecs]; // Array for transaction records
Transaction temp[maxRecs]; // Temp array for resolving pending transactions
string mMenu[MENU] = {
"Add Transaction\n",
"View Account\n",
"Resolve Pending Transactions\n",
"Calculate Interest\n",
"Export to CSV File\n",
"Save Data\n",
"Exit\n\n" };
ifstream inFile; // file input stream
ofstream outFile; // file output stream
// Initialize the Transaction arrays
for (c = 0; c < maxRecs;c++) {
record[c].day = 0;
record[c].month = 0;
record[c].year = 0;
record[c].status = ' ';
record[c].name = " ";
record[c].method = " ";
record[c].cat = " ";
record[c].amount = 0.0;
record[c].balance = 0.0;
temp[c].day = 0;
temp[c].month = 0;
temp[c].year = 0;
temp[c].status = ' ';
temp[c].name = " ";
temp[c].method = " ";
temp[c].cat = " ";
temp[c].amount = 0.0;
temp[c].balance = 0.0;
}
// Get time info
time_t rawtime = time(NULL);
struct tm* timeinfo = new tm;
localtime_s(timeinfo, &rawtime);
day = timeinfo->tm_mday;
month = timeinfo->tm_mon + 1;
year = timeinfo->tm_year + 1900;
// Set precision for monetary values
cout << setprecision(2) << fixed << showpoint;
// If a .dat does not exist create a new one
// Else, read data into array
do {
inFile.open(filename1, ios::binary);
if (!inFile) {
cout << "File does not exist!\n\n";
system("PAUSE");
break;
}
else {
inFile.seekg(0, inFile.end);
fileSize = (int)inFile.tellg();
inFile.seekg(0, inFile.beg);
for (c = 0; bytesRead < fileSize, c < maxRecs;c++) {
inFile.read(reinterpret_cast<char *>(&record[c]), sizeof(Transaction));
bytesRead += (int)inFile.gcount();
}
inFile.close();
file = true;
break;
}
} while (file != true);
// Count how many records are in the array
for (c = 0; c < maxRecs;c++) {
if (record[c].amount != 0.0) {
count++;
}
}
numRecsYr = count;
// Main Program
do {
system("CLS");
cout << endl << endl;
// Main Menu
cout << "Main Menu\n\n";
i = 1;
for (c = 0; c < MENU;c++) {
cout << i++ << " " << mMenu[c];
}
cin >> sel;
if (sel <= 0 || sel >= 8) {
// Validate input
cout << " - " << sel << " - is not a valid selection! Please try again!\n\n";
system("PAUSE");
break;
}
else if (sel == 1) {
// Add Transaction
}
else if (sel == 2) {
// View Account
}
else if (sel == 3) {
// Resolve Pending Transactions
}
else if (sel == 4) {
// Calculate Interest Rate
}
else if (sel == 5) {
// Export Data to CSV File
}
else if (sel == 6) {
// Save Data to File
do {
system("CLS");
cout << "Saving Data to File...\n\n";
outFile.open(filename1, ios::binary);
if (!outFile) {
cout << "There was an error opening the file!\n\n";
system("PAUSE");
break;
}
else {
for (c = 0; c < numRecsYr;c++) {
outFile.write(reinterpret_cast<char *>(&record[c]), sizeof(Transaction));
}
}
outFile.close();
file = true;
break;
} while (file != true);
}
else if (sel == 7) {
// Exit
cout << "Goodbye!\n\n";
}
} while (sel != 7);
return 0;
}

Your Transaction class contains non-POD data (string variables) but then with
inFile.read(reinterpret_cast<char *>(&record[c]), sizeof(Transaction));
you're trying to read them in from a file as if Transaction instances are simple binary blocks of data. They're not so that doesn't work. And in doing so you happen to be corrupting the string objects which in this case happens to cause a crash during the Transaction destructors when you exit the program.
You'll need to use a more sophisticated way to write and read the data to and from file - something that accesses the member variables individually and correctly.

Related

c++ access error reading

#include<iostream>
using namespace std;
#include<conio.h>
#include<string>
#include <fstream>
#include <time.h>
#define KB_UP 72
#define KB_DOWN 80
#define KB_LEFT 75
#define KB_RIGHT 77
#define KB_ESCAPE 27
#define KB_ENTER 13
struct kimlik {
int id;
string TC;
string Ad;
string Soyad;
bool cinsiyet;
string dogumgunu;
string tel;
string eposta;
string girist;
string cıkıst;
int depozito;
int odenmis_k[12];
double endeks[12];
double fatura[12];
int oda_no;
};
struct kimlik kisi[20];
kisi is struct ^
I think error is under this row
void oku() {
cout << "okuma islemi yapiliyor";
ifstream file2;
file2.open("kisi.txt", ios::in | ios::binary );
file2.seekg(0L, ios::beg);
for (int i = 0; i < 20; i++) {
int i = 0;
cout << "suanda cursor " << file2.tellg() << endl;
file2.read((char *)&kisi[i], sizeof(kisi[i]));
}
I close the file
file2.close();
cout << "Islem tamamlandi";
getchar();
}
int main() {
if use don't use oku() there aren't any error
oku();
I am using oku
donus:
system("cls");
int i = 1;
int KB_code = 0;
string menu[7] = { " ","Kisi ekle","Kisi sil","Kisi duzenle","Listeleme
1","Listeme 2","Cikis" };
while ((KB_code != KB_ESCAPE) && (KB_code != KB_ENTER))
{
system("cls");
for (int c = 1; c <= 6; c++) {
if (c == i)
cout << ">> " << menu[c] << endl;
else
cout << " " << menu[c] << endl;
}
KB_code = _getch();
switch (KB_code)
{
case KB_DOWN:
i++;
if (i == 7)
i = 1;
cout << endl << i << endl;
break;
case KB_UP:
i = i - 1;
if (i == 0)
i = 6;
cout << endl << i << endl;
break;
}
}
if (KB_code == KB_ESCAPE)
goto bitir;
switch (i)
{
case 1:
system("cls");
kisi_ekle();
break;
case 2:
cout << "case2";
break;
case 3:
cout << "case3";
break;
case 4:
system("cls");
listeleme1();
break;
case 5:
cout << "case5";
break;
default:
goto bitir;
break;
}
_getch();
goto donus;
bitir:
system("pause");
program is working here and I push any key to close the console I take an error
}
I shared my project
error is at void oku() beacuse when I don't use it there aren't any error.
if I use oku(); when program finished, I take an access error reading error
_Pnext, 0xA3EF54
Your struct kimlik has members of type std::string. You cannot simply read data from a file into a struct holding std::string, because std::string manages it's data internally. Depending on the implementation an std::string has a pointer to some data and members for data size and string length. Your code simply writes into those values, thus creating corrupt std::strings with dangling pointers and invalid internal states. You need to write and read each string independently using the << and >> stream operators.
It's best to make your struct a class and create writeToStream() and readFromStream() methods in it:
class Kimlik {
public:
// constructor etc.
bool readFromStream(std::istream& s) {
// implement reading of each member here
// return true or false depending on whether reading succeeded or not
}
bool writeToStream(std::ostream& s) {
// implement writing of each member here
// return true or false depending on whether writing succeeded or not
}
private:
int id;
std::string TC;
std::string Ad;
std::string Soyad;
bool cinsiyet;
std::string dogumgunu;
std::string tel;
std::string eposta;
std::string girist;
std::string cıkıst;
int depozito;
int odenmis_k[12];
double endeks[12];
double fatura[12];
int oda_no;
};
Then use those methods where applicable:
kisi[i].readFromStream(file2);
Also see How to read and write a STL C++ string?

String to double conversion without sstream or boost lexical cast

Hey guys I have a question about my code. Here's what we have to do:
"Ask the user to read a file. The file will be in the same format as “items.txt” on the website. There will
always be a list of items with a name and price followed by some amount of recipes. If a recipe for an
item is not present, the only way to make the item is to buy it directly. Make a program that reads all
the items and recipes, then says how much profit can be made by making each item.
If an item has no recipe, you would buy that item then resell it for the same price and make a profit of
0. If an item does have a recipe, you would buy the materials to make this item and subtract this cost
from the price of the final product.
There will only be zero or one recipe per item. The items will always be listed first. The names of
items will always be a single word (using a _ to join names that are normally multiple words). You
may assume there will be less than 50 items and each recipe will use less than 50 other items to create a
final product."
This is the items1.txt we use
Item: Wood 2.5
Item: Metal 5.5
Item: Cat 900
Item: Spear 50.7
Recipe: Spear = Wood + Wood + Metal ;
I have what I think would work but I can't get a certain line to work. I'm trying to use stod but apparently my school's computers don't support it. I also tried boost lexical cast and that wouldn't work either.
It says "stod: was not declared in this scope.
Here's my code:
#include <iostream>
#include <fstream>
#include <cstdlib>
#include <string>
#include <algorithm>
#include <sstream>
using namespace std;
string nextstring(string str, int start_index);
int split(string str, string a[], int max_size);
int main()
{
ifstream in_stream;
string fileName;
cout << "Enter the file name : ";
cin >> fileName;
in_stream.open(fileName.c_str());
//error checking
if (in_stream.fail())
{
cout << "File could not be opened." << endl;
exit(1);
}
string items[50];
double items_value[50];
string recipe[50];
string rname = recipe[0];
double profit = 0;
int j = 0;
string lines;
int number_of_lines = 0;
while(getline(in_stream, lines))
{
if(lines.substr(0,5) == "Item:")
{
int beginning = lines.find_first_of(' ') + 1;
int next_space = lines.find(" ", beginning);
items_value[j] = stod(lines.substr(next_space));
items[j] = lines.substr(beginning,lines.find_first_of(' ', beginning) - beginning);
j++;
}
if(lines.substr(0,7) == "Recipe:")
{
int max_size = lines.length();
int cnt = split(lines,recipe,max_size);
double profit1 = 0;
double profit2 = 0;
for(int j = 3; j < cnt; j++)
{
for(int i = 0; i < 4; i++)
{
if((recipe[j] == items[i]) && (recipe[j] != "+")&& (recipe[j] != ";"))
{
cout << "Making " << items[i] << ", " << "profit = 0" << endl;
profit1 += items_value[i];
}
if(recipe[1] != items[i])
{
profit2 = 0;
}
}
}
for(int i = 0; i < cnt; i++)
{
if((recipe[1] == items[i]))
{
profit = items_value[i];
cout << "Making " << items[i] << ", " << "profit = ";
}
}
cout << profit - profit1 << endl;
}
}
in_stream.close();
return 0;
}
string nextstring(string str, int start_index)
{
int y =0;
y = str.find(' ',start_index);
y = y-start_index;
str = str.substr(start_index,y);
return str;
}
int split(string str, string a[], int max_size)
{
int i;
int num = 0;
for (i=0; i<max_size; i++)
{
a[i] = nextstring(str,num);
num = num + a[i].length() + 1;
if(num >= str.length())
{
i++;
break;
}
}
return i;
}
First step is get a decent compiler from this century ;) stod has been available since c++11, which really means that it was available probably a few years before that.
If stod isn't available to you then you can revert to the cstdlib function atof.

Frequency table in C++

This is what I have so far; I am trying to have an array with probability of all chars and space in a text file, but I have a problem with the data type.
int main()
{
float x[27];
unsigned sum = 0;
struct Count {
unsigned n;
void print(unsigned index, unsigned total) {
char c = (char)index;
if (isprint(c)) cout << "'" << c << "'";
else cout << "'\\" << index << "'";
cout << " occured " << n << "/" << total << " times";
cout << ", propability is " << (double)n / total << "\n";
}
Count() : n() {}
} count[256];
ifstream myfile("C:\\text.txt"); // one \ masks the other
while (!myfile.eof()) {
char c;
myfile.get(c);
if (!myfile) break;
sum++;
count[(unsigned char)c].n++;
}
for (unsigned i = 0; i<256; i++)
{
count[i].print(i, sum);
}
x[0] = count[33];
int j=68;
for(int i=1;i<27;i++)
{
x[i]=count[j];
j++;
}
return 0;
}
#include <iostream>
#include <fstream>
#include <cctype>
using namespace std;
double probabilities[256]; // now it can be accessed by Count
int main()
{
unsigned sum = 0;
struct Count {
unsigned n;
double prob;
void print ( unsigned index, unsigned total ) {
// if ( ! n ) return;
probabilities[index] = prob = (double)n/total;
char c = (char) index;
if ( isprint(c) ) cout << "'" << c << "'";
else cout << "'\\" << index << "'";
cout<<" seen "<<n<<"/"<<total<<" times, probability is "<<prob<<endl;
}
Count(): n(), prob() {}
operator double() const { return prob; }
operator float() const { return (float)prob; }
} count[256];
ifstream myfile("C:\\text.txt"); // one \ masks the other
while(!myfile.eof()) {
char c;
myfile.get(c);
if ( !myfile ) break;
sum++;
count[(unsigned char)c].n++;
}
for ( unsigned i=0; i<256; i++ ) count[i].print(i,sum);
return 0;
}
I incorporated various changes suggested - Thanks!
Now, who finds the 4 ways to access the actual probabilities?
you are allocating a buffer with size 1000000 1 million characters.
char file[1000000] = "C:\text.txt";
This is not good as the extra values in the buffer are not guaranteed to be zero, the can be anything.
For Windows to read a file you need something like this. I will not give you the solution, you need to learn using msdn and documentation to understand this fully::
you need to include the #include <windows.h> header from the SDK first.
Look at this example here: http://msdn.microsoft.com/en-us/library/windows/desktop/aa363778(v=vs.85).aspx
this example as appending a file to another. Your solution will be similar, instead of writing list to other file, process the buffer to increment your local variables and update the state of the table.
Do not set a large number you come up with for the buffer, as there will risk of not enough buffer space, and thus overflow. You should do like example:
read some bytes in buffer
process that buffer and increment the table
repeat until you reach end of file
while (ReadFile(hFile, buff, sizeof(buff), &dwBytesRead, NULL)
&& dwBytesRead > 0)
{
// write you logic here
}

Access violating writing location (visual studio 2008) Code based on pointers

The main problem is after sem->i = a; is used when yylex is called and c isalpha
sem->s[i] = c; doesn't work because sem->s[i] has an issue with the adress it points to.
more details:
So what i want to do is to open a txt and read what it is inside until the end of file.
If it's an alfanumeric (example: hello ,example2 hello45a) at the function yylex i put each of the characters into an array(sem->s[i]) until i find end of file or something not alfanumeric.
If it's a digit (example: 5234254 example2: 5) at the function yylex i put each of the characters into the array arithmoi[]. and after with attoi i put the number into the sem->i.
If i delete the else if(isdigit(c)) part at yylex it works(if every word in the txt doesn't start with a digit) .
Anyway the thing is that it works great when it finds only words that starts with characters. Then if it finds number(it uses the elseif(isdigit(c) part) it still works...until it finds a words starting with a character. when that happens there is an access violating writing location and the problem seems to be where i have an arrow. if you can help me i would be really thankfull.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <iostream>
using namespace std;
union SEMANTIC_INFO
{
int i;
char *s;
};
int yylex(FILE *fpointer, SEMANTIC_INFO *sem)
{
char c;
int i=0;
int j=0;
c = fgetc (fpointer);
while(c != EOF)
{
if(isalpha(c))
{
do
{
sem->s[i] = c;//the problem is here... <-------------------
c = fgetc(fpointer);
i++;
}while(isalnum(c));
return 1;
}
else if(isdigit(c))
{
char arithmoi[20];
do
{
arithmoi[j] = c;
j++;
c = fgetc(fpointer);
}while(isdigit(c));
sem->i = atoi(arithmoi); //when this is used the sem->s[i] in if(isalpha) doesn't work
return 2;
}
}
cout << "end of file" << endl;
return 0;
}
int main()
{
int i,k;
char c[20];
int counter1 = 0;
int counter2 = 0;
for(i=0; i < 20; i++)
{
c[i] = ' ';
}
SEMANTIC_INFO sematic;
SEMANTIC_INFO *sema = &sematic;
sematic.s = c;
FILE *pFile;
pFile = fopen ("piri.txt", "r");
do
{
k = yylex( pFile, sema);
if(k == 1)
{
counter1++;
cout << "it's type is alfanumeric and it's: ";
for(i=0; i<20; i++)
{
cout << sematic.s[i] << " " ;
}
cout <<endl;
for(i=0; i < 20; i++)
{
c[i] = ' ';
}
}
else if(k==2)
{
counter2++;
cout << "it's type is digit and it's: "<< sematic.i << endl;
}
}while(k != 0);
cout<<"the alfanumeric are : " << counter1 << endl;
cout<<"the digits are: " << counter2 << endl;
fclose (pFile);
system("pause");
return 0;
}
This line in main is creating an uninitialized SEMANTIC_INFO
SEMANTIC_INFO sematic;
The value of integer sematic.i is unknown.
The value of pointer sematic.s is unknown.
You then try to write to sematic.s[0]. You're hoping that sematic.s points to writable memory, large enough to hold the contents of that file, but you haven't made it point to anything.

C++ Alphabetical Insertion Sort

We are doing a project involving storing and comparing various cities. We have become stuck after adding a new city into the database, it goes to the bottom of the list - we want it to go into the database, sorted alphabetically. As only one value can be added at a time, all the other entries will already be alphabetical.
Below is the relevant code to this.
The problem area is the // Insertion Sort when adding // out bit.
The error codes are:
[BCC32 Error] File1.cpp(250): E2294 Structure required on left side of . or .*
[BCC32 Error] File1.cpp(250): E2108 Improper use of typedef 'node'
[BCC32 Error] File1.cpp(250): E2188 Expression syntax
All corresponding to the line
while (strcmp(cityTemp.fname, node[l]) < 0) && (l <= ct )
If you could point us in the right direction, that would be great. Thanks
// -------------------------------------------------------------------------- //
#include <stdlib.h>
#include <iostream>
#include <fstream>
#include <cstring>
#include <cmath>
#include <iomanip>
#define PI 3.14159265
using namespace std;
// -------------------------------------------------------------------------- //
class node
{
private:
char city[100];
char country[100];
float longitudeDegree;
float longitudeMinutes;
char eastWest[2];
float latitudeDegree;
float latitudeMinutes;
char northSouth[2];
//useful for link list!
node *next;
// -------------------------------------------------------------------------- //
public:
//Constructor for class node
// ctn = city node
// cyn = country node
// longD = longitude degree
// longM = longitude minutes
// ew = east / west
// latD = latitude distance
// latM = latitude minutes
// ns = north / south
node(char ctn[], char cyn[], float longD,
float longM, char ew[], float latD, float latM, char ns[])
{
//Copy char array ctn to class array city
//string copy is part of string header
strcpy(city, ctn); //copy to string city name
strcpy(country, cyn); //copy to string country name
longitudeDegree = longD;
longitudeMinutes = longM;
strcpy(eastWest, ew);
latitudeDegree = latD;
latitudeMinutes = latM;
strcpy(northSouth, ns);
cout << "Hello from node with name: " << city << endl;
}
// -------------------------------------------------------------------------- //
// Get function to return city stored in class //
char* getCity()
{
return city;
}
char* getCountry()
{
return country;
}
float getLongDe()
{
return longitudeDegree;
}
float getLongMin()
{
return longitudeMinutes;
}
char* getEastWest()
{
return eastWest;
}
float getLatDe()
{
return latitudeDegree;
}
float getLatMin()
{
return latitudeMinutes;
}
char* getNorthSouth()
{
return northSouth;
}
};
// -------------------------------------------------------------------------- //
class menu
{
private:
int fnum, mnum, ct, xx, fg, ans, ans2;
float longitudeDegree;
float longitudeMinutes;
float latitudeDegree;
float latitudeMinutes;
char country[100];
char eastWest[2];
char northSouth[2];
//array of pointers of type class node
node *db[200]; //denotes how many pointers to use for the amount of cities in database
char fname[200];
char pt[200];
char sfnum[200];
char yn[2]; //yes/no
public:
//constructor
menu()
{
//Read the serialized data file
ct= Readit();
}
// -------------------------------------------------------------------------- //
void start()
{
// Add a city //
case 1:
cout << "Enter the name of the city:";
cin.getline(fname,100);
fg=Findit(ct,fname);
if(fg>0)
{
cout << "This entry is already in the database: " << fname <<endl;
}
else
{
cout << "Enter the Country of " << fname << endl;
cin >> country;
//ans2 = '-1';
do
{
cout << "Enter the Longitude Degrees (0 - 180) of " << fname <<endl ;
cout << "Enter degrees between 0 - 180 \n";
cin >> ans2;
}
while(!((ans2 >=0)&&(ans2 <=180)));
longitudeDegree = ans2;
//ans2 = '-1';
do
{
cout << "Enter the Longitude Minutes (0 - 60) of " << fname << endl;
cout << "Enter minutes between 0 - 60 \n";
cin >> ans2;
}
while(!((ans2 >=0)&&(ans2 <=60)));
longitudeMinutes = ans2;
ans = 'Z'; //default to an answer not in while loop
do
{
cout << "East or West?\n";
cout << "You must type a capital 'E' or a capital 'W'.\n";
cin >> ans;
}
while((ans !='E')&&(ans !='W'));
eastWest[0] = ans;
eastWest[1] = '\0';
//ans2 = '-1';
do
{
cout << "Enter the Latitude Degree (0 - 90) of " << fname << endl;
cout << "Enter degrees between 0 - 90 \n";
cin >> ans2;
}
while(!((ans2 >=0)&&(ans2 <=180)));
latitudeDegree = ans2;
//ans2 = '-1';
do
{
cout << "Enter the Latitude Minutes (0 - 60) of " << fname << endl;
cout << "Enter minutes between 0 - 60 \n";
cin >> ans2;
}
while(!((ans2 >=0)&&(ans2 <=60)));
latitudeMinutes = ans2;
ans = 'Z'; //default to an answer not in while loop
do
{
cout << "North or South?\n";
cout << "You must type a capital 'N' or a capital 'S'.\n";
cin >> ans;
}
while((ans !='N')&&(ans !='S'));
northSouth[0] = ans;
northSouth[1] = '\0';
ct++;
db[ct]=new node(fname,country,longitudeDegree,longitudeMinutes,
eastWest,latitudeDegree,latitudeMinutes,northSouth);
/* // Insertion Sort when adding //
node *cityTemp;
cityTemp=db[ct];
//cityTemp = new node (fname, country, longitudeDegree, longitudeMinutes, eastWest, latitudeDegree, latitudeMinutes, northSouth);
int j, l;
// Find place to insert the new city //
// All other cities will already be in alphabetical order
l=0;
while (strcmp(cityTemp.fname, node[l]) < 0) && (l <= ct )
//strcmp(cityTemp.fname, node[l].fname)<0) && (l<=ct)
{
l++;
}
// Move down rest
for (j = l, j <= ct);
{
j++;
}
db[j+1] = db[j];
db[j] = cityTemp; */
}
break;
}
// -------------------------------------------------------------------------- //
// Function to convert string to lower case ascii //
char *strLower( char *str )
{
char *temp;
for ( temp = str; *temp; temp++ )
{
*temp = tolower( *temp );
}
return str;
}
// -------------------------------------------------------------------------- //
// Function to search through the names stored in nodes //
int Findit(int ctt,char fnamef[])
{
int nn=0;
int xx;
for(int k=1;k<=ctt;k++)
{
xx=strcmp(strLower(db[k]->getCity()),strLower(fnamef));
//xx is zero if names are the same
if(xx==0)
nn=k;
}
return nn;
}
// -------------------------------------------------------------------------- //
// Function to do serialization of nodes and store in a file //
void Storeit(int ctt)
{
fstream outfile;
outfile.open("cityList.txt",ios::out);
outfile<<ctt<<endl;
for(int k=1;k<=ctt;k++)
{
//outfile<<db[k]->getName()<<endl;
outfile<<db[k]->getCity()<<endl;
outfile<<db[k]->getCountry()<<endl;
outfile<<db[k]->getLongDe()<<endl;
outfile<<db[k]->getLongMin()<<endl;
outfile<<db[k]->getEastWest()<<endl;
outfile<<db[k]->getLatDe()<<endl;
outfile<<db[k]->getLatMin()<<endl;
outfile<<db[k]->getNorthSouth()<<endl;
}
outfile.close();
}
// -------------------------------------------------------------------------- //
int Readit()
// Function to open the file, read in the data and create the nodes
{
int ctx=0;
fstream infile;
infile.open("cityList.txt",ios::in);
//infile>>ctx;
infile.getline(sfnum,200);
ctx=atoi(sfnum);
/*
for(int k=1;k<=ctx;k++)
{
//infile>>fname;
infile.getline(fname,200);
//infile>>weight;
infile.getline(sfnum,200);
weight=atof(sfnum);
//infile>>height;
infile.getline(sfnum,200);
height=atof(sfnum);
db[k]=new node(fname,height,weight);
}
*/
// Read in file to variables i.e. longitudeDegree = atof(sfnum)
for(int k=1;k<=ctx;k++)
{
//infile>>fname;
infile.getline(fname,100);
//infile>>country ;
infile.getline(sfnum,100);
strcpy(country,sfnum);
//infile>>longitudeDegree;
infile.getline(sfnum,100);
longitudeDegree=atof(sfnum);
//infile>>longitudeMinutes;
infile.getline(sfnum,100);
longitudeMinutes=atof(sfnum);
//infile>>eastWest ;
infile.getline(sfnum,100);
strcpy(eastWest,sfnum);
//infile>>latitudeDegree;
infile.getline(sfnum,100);
latitudeDegree=atof(sfnum);
//infile>>latitudeMinutes;
infile.getline(sfnum,100);
latitudeMinutes=atof(sfnum);
//infile>>northSouth ;
infile.getline(sfnum,100);
strcpy(northSouth,sfnum);
db[k]=new node(fname,country, longitudeDegree,
longitudeMinutes, eastWest, latitudeDegree, latitudeMinutes, northSouth);
}
infile.close();
return ctx;
}
};
// End of class menu
Don't you mean to use db[l] - the variable - rather than node - the type.
Azorath wrote:
(strcmp(cityTemp.fname, node[i]) < 0) && (l <= ct )
and after some give and take we've got, with some confusion between i, I and l....
(strcmp(cityTemp.fname, db[i]->getcity()) < 0) && (l??? <= ct )
yes? (how does Erik know that db[i] is in the code?)
I'm taking a guess that cityTemp is an instance of node, not a pointer to node, and that db[] is an array of pointers to nodes, yes?
One thing wrong is "cityTemp.fname" - there is no "fname" member in the class. Its looking for a structure containing a member "fname". Do you mean cityTemp.city?
Try that and trport what you get...