Hello. I've written this program which reads a preformatted text file with a list of countries and then sorts them, adds/modifies/deletes records and exports the modified list to another file.
I've got two problems with it. The first one is a more serious one, while the other one is a minor issue.
So, the bigger problem is with the output I get. When I display the sorted list, the fields overlap like this (in case you're wondering ─ the list of countries is in Polish): Imageshack - countries.png - Uploaded by lordmorgul
I have absolutely no idea how to fix this thing.
The other issue is with the function for exporting the list to another text file. I would like to automatically add the .txt extension to the filename, but when I do I get this error:
menu.cpp: In function ‘void Menu(std::vector<COUNTRY, std::allocator<COUNTRY> >&)’:
menu.cpp:131: error: invalid operands of types ‘char [30]’ and ‘const char [5]’ to binary ‘operator+’
And when I change the outfile to a string, I get the following:
menu.cpp: In function ‘void Menu(std::vector<COUNTRY, std::allocator<COUNTRY> >&)’:
menu.cpp:131: error: no matching function for call to ‘std::basic_fstream<char, std::char_traits<char> >:
pen(std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::_Ios_Openmode)’
/usr/include/c++/4.4/fstream:865: note: candidates are: void std::basic_fstream<_CharT, _Traits>:
pen(const char*, std::_Ios_Openmode) [with _CharT = char, _Traits = std::char_traits<char>]
Here's the program:
panstwa.hpp
Code:
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <fstream>
#include <vector>
#include <string>
#include <cstring>
using namespace std;
struct COUNTRY
{
string Name, Cont, Lang;
int Population, Area;
float Density;
};
fstream filein, fileout;
int Menu(vector<COUNTRY> &);
void Print(vector<COUNTRY> &);
char DisplayData();
char DisplayData_sub(char);
char Search();
void Search_sub(vector<COUNTRY> &, char);
void DeleteData(vector<COUNTRY> &);
void ModifyData(vector<COUNTRY> &);
void BubbleSortName(vector<COUNTRY> &, char);
void BubbleSortPopulation(vector<COUNTRY> &, char);
void BubbleSortArea(vector<COUNTRY> &, char);
void BubbleSortDensity(vector<COUNTRY> &, char);
void Help();
main.cpp
Code:
#include "panstwa.hpp"
#include "funkcje.cpp"
#include "menu.cpp"
#include "sort.cpp"
int main(int argc, char* argv[])
{
if (argc < 2)
{
cout << "Incorrectly run program" << endl
<< "Run it this way:" << endl
<< "\tcountries.out <file>" << endl
<< "(where <file> is a text file" << endl;
exit(1);
}
else
{
filein.open(argv[1], ios::in);
if(!filein.good())
{
cout << "Couldn't open the file." << endl;
exit(1);
}
short lines=0;
char c;
while(!filein.eof())
{
filein.get(c);
if(c=='\n') lines++;
}
lines++;
if(filein.eof()) filein.clear();
filein.seekg(ios::beg);
vector<COUNTRY> Country(lines);
char znak;
for(int i=0; !filein.eof(); i++)
{
getline( filein, Country[i].Name, filein.widen(';'));
filein >> Country[i].Population >> znak;
filein >> Country[i].Area >> znak;
getline( filein, Country[i].Cont, filein.widen(';'));
getline( filein, Country[i].Lang, filein.widen('\n'));
float population = static_cast<float>(Country[i].Population);
float Area = static_cast<float>(Country[i].Area);
Country[i].Density = population/Area;
}
filein.close();
Menu(Country);
return 0;
}
}
menu.cpp
Code:
int Menu(vector<COUNTRY> &Country)
{
char choice;
float a, b;
cout << "Countries." << endl
<< "What would you like to do?" << endl << endl
<< "\t[d]isplay the list of countries." << endl
<< "\t[s]earch for a country." << endl
<< "\t[r]emove a record." << endl
<< "\t[a]dd a record." << endl
<< "\t[m]odify a record." << endl
<< "\t[e]xport the base to a text file." << endl
<< "\t[h]elp." << endl
<< "\t[q]uit." << endl << endl
<< "Choice: ";
do
{
cin >> choice;
if( (choice!='d') && (choice!='s') && (choice!='r') &&
(choice!='a') && (choice!='m') && (choice!='e') && (choice!='h') && (choice!='q'))
cout << endl << "Illegal option. Choose again:: ";
}
while( (choice!='d') && (choice!='s') && (choice!='r') &&
(choice!='a') && (choice!='m') && (choice!='e') && (choice!='h') && (choice!='q'));
char Option;
COUNTRY temp;
short in;
char outfile[30];
//string outfile;
switch(choice)
{
case 'd':
Option = DisplayData();
switch(Option)
{
case '1':
BubbleSortName(Country, DisplayData_sub(Option));
Print(Country);
break;
case '2':
BubbleSortPopulation(Country, DisplayData_sub(Option));
Print(Country);
break;
case '3':
BubbleSortArea(Country, DisplayData_sub(Option));
Print(Country);
break;
case '4':
BubbleSortDensity(Country, DisplayData_sub(Option));
Print(Country);
break;
default:
break;
}
cin.ignore();
getchar();
Menu(Country);
break;
case 's':
Option = Search();
Search_sub(Country, Option);
cin.ignore();
getchar();
Menu(Country);
break;
case 'r':
DeleteData(Country);
cin.ignore();
getchar();
Menu(Country);
break;
case 'a':
cout << "You want to add a country. Type in the following:" << endl
<< "Name (uppercase, eg. JAPAN): ";
cin.ignore();
getline(cin, temp.Name);
cout << "Population (integer): ";
cin >> temp.Population;
cout << "Area (integer): ";
cin.ignore();
cin >> temp.Area;
cout << "Continent (first uppercase, eg. Australia): ";
cin.ignore();
getline(cin, temp.Cont);
cout << "Language (all lowercase, eg. spanish): ";
getline(cin, temp.Lang);
a = static_cast<float>(temp.Population);
b = static_cast<float>(temp.Area);
temp.Density = a/b;
Country.push_back(temp);
in = Country.size() - 1;
cout << endl << "Here's the country's data: " << temp.Name << ": " << endl;
cout << "#" << in+1 << ": ";
cout << Country[in].Name << " | ";
cout << Country[in].Population << " | ";
cout << Country[in].Area << " | ";
cout << Country[in].Cont << " | ";
cout << Country[in].Lang << " | ";
cout << Country[in].Density;
cin.ignore();
getchar();
Menu(Country);
break;
case 'm':
ModifyData(Country);
cin.ignore();
getchar();
Menu(Country);
break;
case 'e':
cout << "Type in the name of the file to export: ";
cin >> outfile;
fileout.open(outfile, ios::out|ios::trunc);
if(fileout.good())
{
cout << endl << "Opened the file successfully.";
}
else
{
cout << endl << "Couldn't open the file" << endl;
return 1;
}
for(unsigned short i=0; i < Country.size(); i++)
{
fileout << Country[i].Name <<';'<<Country[i].Population <<';'<<Country[i].Area <<';'<<Country[i].Cont <<';'<< Country[i].Lang <<
';'<< Country[i].Density << endl;
}
fileout << '\0';
fileout.close();
cout << endl << "File export successful.";
cin.ignore();
getchar();
Menu(Country);
break;
case 'h':
Help();
cin.ignore();
getchar();
Menu(Country);
cout << "Press [return] to get back to the menu" << endl;
break;
case 'q':
cout << "Finished." << endl;
exit(0);
default:
break;
}
}
funkcje.cpp
Code:
void Print(vector<COUNTRY> &Country)
{
int length = Country.size();
for(int i=0; i < length; i++)
{
cout << "#" << i+1 << ": ";
cout << Country[i].Name << " | ";
cout << Country[i].Population << " | ";
cout << Country[i].Area << " | ";
cout << Country[i].Cont << " | ";
cout << Country[i].Lang << " | ";
cout << Country[i].Density;
cout << endl;
//if ((i+1)%15==0) //getchar();
}
}
char DisplayData()
{
char choice;
cout << "How do you want to sort the countries?" <<endl;
cout << "\t1) By name." <<endl;
cout << "\t2) By population." <<endl;
cout << "\t3) By area." <<endl;
cout << "\t4) By population density." <<endl;
cout << "Option: ";
do
{
cin >> choice;
if((choice!='1') && (choice!='2') && (choice!='3') && (choice!='4'))
cout << endl << "Illegal option. Choose again:";
}
while((choice!='1') && (choice!='2') && (choice!='3') && (choice!='4'));
return choice;
}
char DisplayData_sub(char Option)
{
char choice;
switch(Option)
{
case '1':
cout << "How do you want to sort the names?" << endl;
cout << "\tm) descending order." << endl;
cout << "\tr) ascending order." << endl;
cout << "Choice: ";
do
{
cin >> choice;
if((choice!='m') && (choice!='r'))
cout << endl << "Illegal option. Choose again:";
}
while((choice!='m') && (choice!='r'));
break;
case '2':
cout << "You want to sort the list by population:" << endl;
cout << "\tm) in descending order." << endl;
cout << "\tr) in ascending order." << endl;
cout << "Choice: ";
do
{
cin >> choice;
if((choice!='m') && (choice!='r'))
cout << endl << "Illegal option. Choose again:";
}
while((choice!='m') && (choice!='r'));
break;
case '3':
cout << "You want to sort the list by area:" << endl;
cout << "\tm) in descending order." << endl;
cout << "\tr) in ascending order." << endl;
cout << "Wybor: ";
do
{
cin >> choice;
if((choice!='m') && (choice!='r'))
cout << endl << "Illegal option. Choose again:";
}
while((choice!='r') && (choice!='m'));
break;
case '4':
cout << "You want to sort the list by population density:" << endl;
cout << "\tm) in descending order." << endl;
cout << "\tr) in ascending order." << endl;
cout << "Wybor: ";
do
{
cin >> choice;
if((choice!='m') && (choice!='r'))
cout << endl << "Illegal option. Choose again:";
}
while((choice!='m') && (choice!='r'));
break;
default:
break;
}
return choice;
}
char Search()
{
char choice;
cout << "How do you want to search the country:" << endl
<< "\t1) By name." << endl
<< "\t2) By continent." << endl
<< "\t3) By language." << endl << "Wybor: ";
do
{
cin >> choice;
if((choice!='1') && (choice!='2') && (choice!='3'))
cout << endl << "Illegal option. Choose again:: ";
}
while((choice!='1') && (choice!='2') && (choice!='3'));
return choice;
}
void Search_sub(vector<COUNTRY> &Country, char Option)
{
unsigned short i=0;
bool flag = false;
string temp;
unsigned int result;
switch(Option)
{
case '1':
cout << "Type in the country's name (in capitals, eg. CANADA): ";
cin.ignore();
getline(cin, temp);
while(i != Country.size())
{
result = Country[i].Name.find(temp);
if(result!=string::npos)
{
cout << "#" << i << ": " << Country[i].Name << " | " << Country[i].Population << " | " << Country[i].Area << " | " << Country[i].Cont << " | " << Country[i].Lang << " | " << Country[i].Density << endl;
flag = true;
}
i++;
}
if( flag == false ) cout << endl << "The country couldn't be found.";
break;
case '2':
cout << "Type in the country's continent (first capital letter, eg. Africa): ";
cin.ignore();
getline(cin, temp);
//result = strstr( Country[i].Cont, temp );
while(i != Country.size())
{
result = Country[i].Cont.find(temp);
if(result!=string::npos)
{
cout << "#" << i << ": " << Country[i].Name << " | " << Country[i].Population << " | " << Country[i].Area << " | " << Country[i].Cont << " | " << Country[i].Lang << " | " << Country[i].Density;
flag = true;
cout << endl;
}
i++;
}
if( flag == false ) cout << endl << "Unknown n ame.";
break;
case '3':
cout << "Type in the language (lowercase, eg. norwegian): ";
cin.ignore();
getline(cin, temp);
while(i != Country.size())
{
result = Country[i].Lang.find(temp);
if(result!=string::npos)
{
cout << "#" << i << ": " << Country[i].Name << " | " << Country[i].Population << " | " << Country[i].Area << " | " << Country[i].Cont << " | " << Country[i].Lang << " | " << Country[i].Density;
flag = true;
cout << endl;
}
i++;
}
if( flag == false ) cout << endl << "Unknown name.";
break;
default:
break;
}
}
void ModifyData(vector<COUNTRY> &Country)
{
string temp;
unsigned short i=0, tmp;
bool flag = false;
char choice;
cout << "Type in the name of the country you wish to modify (uppercase, eg. ZIMBABWE):" << endl << "Nazwa: ";
cin.ignore();
getline(cin, temp);
while(i != Country.size())
{
if(temp == Country[i].Name)
{
cout << endl << "Here's the country's current data: " << temp << ": " << endl << "#" << i << ": " << Country[i].Name << " | " << Country[i].Population << " | " << Country[i].Area << " | " << Country[i].Cont << " | " << Country[i].Lang << " | " << Country[i].Density << endl;
tmp = i;
flag = true;
}
i++;
}
if( flag == false ) cout << endl << "Couldn't find the country.";
else if(flag == true)
{
cout << endl << "Rename the country?" << endl << "\t1) Yes." << endl << "\t2) No." << endl << "Wybor: ";
do
{
cin >> choice;
if( (choice!='1') && (choice!='2'))
cout << endl << "Illegal option. Choose again:";
}
while( (choice!='1') && (choice!='2'));
if(choice == '1')
{
cout << endl << "New name: ";
cin.ignore();
getline(cin, Country[tmp].Name);
}
cout << endl << "Change the population?"
<< endl << "\t1) Yes."
<< endl << "\t2) No."
<< endl << "Choice: ";
do
{
cin >> choice;
if( (choice!='1') && (choice!='2'))
cout << endl << "Illegal option. Choose again:";
}
while( (choice!='1') && (choice!='2'));
if(choice == '1')
{
cout << "New population (integer, eg. 23000000): ";
cin >> Country[tmp].Population;
}
cout << endl << "Change the area?" << endl
<< "\t1) Yes." << endl
<< "\t2) No." << endl
<< "Option: ";
do
{
cin >> choice;
if( (choice!='1') && (choice!='2'))
cout << endl << "Illegal option. Choose again:";
}
while( (choice!='1') && (choice!='2'));
if(choice == '1')
{
cout << "New area: ";
cin >> Country[tmp].Area;
}
cout << endl << "Change the continent? " << endl
<< "\t1) Yes." << endl
<< "\t2) No." << endl
<< "Option: ";
do
{
cin >> choice;
if( (choice!='1') && (choice!='2'))
cout << endl << "Illegal option. Choose again:";
}
while( (choice!='1') && (choice!='2'));
if(choice == '1')
{
cout << "New continent (first uppercase, rest lowercase, eg. Asia): ";
cin.ignore();
getline(cin, Country[tmp].Cont);
}
cout << endl << "Change the language?" << endl
<< "\t1) Yes." << endl
<< "\t2) No." << endl
<< "Option: ";
do
{
cin >> choice;
if( (choice!='1') && (choice!='2'))
cout << endl << "Illegal option. Choose again:: ";
}
while( (choice!='1') && (choice!='2'));
if(choice == '1')
{
cout << "New language (lowercase, eg. german): ";
cin.ignore();
getline(cin, Country[tmp].Lang);
}
cout << endl << "Here's the updated data: " << temp << ": " << endl << "#" << tmp << ": " << Country[tmp].Name << " | " << Country[tmp].Population << " | " << Country[tmp].Area << " | " << Country[tmp].Cont << " | " << Country[tmp].Lang << " | ";
float a = static_cast<float>(Country[tmp].Population);
float b = static_cast<float>(Country[tmp].Area);
float c = a/b;
Country[tmp].Density = c;
cout << Country[tmp].Density;
}
}
void DeleteData(vector<COUNTRY> &Country)
{
string temp;
unsigned short i=0, tmp;
bool flag = false;
char choice;
cout << "Type in the name of the country you wish to delete: ";
cin.ignore();
getline(cin, temp);
while(i != Country.size())
{
if(temp == Country[i].Name)
{
tmp = i;
flag = true;
}
i++;
}
if( flag == false ) cout << endl << "Unknown name.";
else
{
cout << endl << "Here's the current data of the country: " << temp << ": " << endl << "#" << tmp << ": " << Country[tmp].Name << " | " << Country[tmp].Population << " | " << Country[tmp].Area << " | " << Country[tmp].Cont << " | " << Country[tmp].Lang << " | " << Country[tmp].Density << endl
<< "Are you sure you want to delete it?: " << endl
<< "1. Tak." << endl << "2. Nie." << endl << "Option: ";
do
{
cin >> choice;
if( (choice!='1') && (choice!='2'))
cout << endl << "Illegal option. Choose again::";
}
while( (choice!='1') && (choice!='2'));
if(choice == '1')
{
Country.erase(Country.begin() + tmp);
cout << endl << "Country deleted.";
}
else if (choice == '2') cout << endl << "OK. Country left untouched.";
}
}
void Help()
{
cout << endl << "TODO: create help." << endl;
}
sort.cpp
Code:
void BubbleSortName(vector<COUNTRY> &Country, char choice)
{
int i, j, flag = 1;
COUNTRY temp;
int length = Country.size( );
for(i = 1; (i <= length) && flag; i++)
{
flag = 0;
for (j=0; j < (length -1); j++)
{
switch(choice)
{
case 'm':
if (Country[j+1].Name > Country[j].Name)
{
temp = Country[j];
Country[j] = Country[j+1];
Country[j+1] = temp;
flag = 1;
}
break;
case 'r':
if (Country[j+1].Name < Country[j].Name)
{
temp = Country[j];
Country[j] = Country[j+1];
Country[j+1] = temp;
flag = 1;
}
break;
}
}
}
}
void BubbleSortPopulation(vector<COUNTRY> &Country, char choice)
{
int i, j, flag = 1;
COUNTRY temp;
int length = Country.size( );
for(i = 1; (i <= length) && flag; i++)
{
flag = 0;
for (j=0; j < (length -1); j++)
{
switch(choice)
{
case 'm':
if (Country[j+1].Population > Country[j].Population)
{
temp = Country[j];
Country[j] = Country[j+1];
Country[j+1] = temp;
flag = 1;
}
break;
case 'r':
if (Country[j+1].Population < Country[j].Population)
{
temp = Country[j];
Country[j] = Country[j+1];
Country[j+1] = temp;
flag = 1;
}
break;
}
}
}
}
void BubbleSortArea(vector<COUNTRY> &Country, char choice)
{
int i, j, flag = 1;
COUNTRY temp;
int length = Country.size( );
for(i = 1; (i <= length) && flag; i++)
{
flag = 0;
for (j=0; j < (length -1); j++)
{
switch(choice)
{
case 'm':
if (Country[j+1].Area > Country[j].Area)
{
temp = Country[j];
Country[j] = Country[j+1];
Country[j+1] = temp;
flag = 1;
}
break;
case 'r':
if (Country[j+1].Area < Country[j].Area)
{
temp = Country[j];
Country[j] = Country[j+1];
Country[j+1] = temp;
flag = 1;
}
break;
}
}
}
}
void BubbleSortDensity(vector<COUNTRY> &Country, char choice)
{
int i, j, flag = 1;
COUNTRY temp;
int length = Country.size( );
for(i = 1; (i <= length) && flag; i++)
{
flag = 0;
for (j=0; j < (length -1); j++)
{
switch(choice)
{
case 'm':
if (Country[j+1].Density > Country[j].Density)
{
temp = Country[j];
Country[j] = Country[j+1];
Country[j+1] = temp;
flag = 1;
}
break;
case 'r':
if (Country[j+1].Density < Country[j].Density)
{
temp = Country[j];
Country[j] = Country[j+1];
Country[j+1] = temp;
flag = 1;
}
break;
}
}
}
}
edit: I also attached the file I'm working on with this program.