Flight destination check programm - C++ - c++

I am trying to solve the following question:
Write a program, which will get from the user
the Number of flights (N)
the destination of train (city)
the train number for certain destination (number)
the name of the wanted destination city, for which we are searching possible trains.
The program should find and display all numbers of trains, which go to wanted destination. If there is no such train, the program must display "Unreachable city!".
Now the problem is that I wrote a code which finds such train number, but not numbers of all trains, it cannot display all the train numbers going to wanted destination point.
I.e. if I input following data:
3
Chicago I-789
Chicago J-159
Chicago A-465
Chicago
It shows me only last train number A-465, whereas the right answer would be: I-789 J-159 A-465
#include <iostream>
#include <string>
using namespace std;
class MyClass {
public:
string city;
string number;
};
int main() {
int N;
cin >> N;
MyClass myObj;
for (int i=0; i<N; i++){
cin>>myObj.city;
cin>>myObj.number;
}
string destination;
cin >> destination;
if(myObj.city==destination){
cout << myObj.number;
}
else{
cout << "Unreachable city!";
}
return 0;
}

On your comment:
C++ is much harder than python.
Programming languages are just tools. You use them to solve a problem. If you don't know how to use a tool, you can't solve the problem. Your computer is a tool, if you don't know how to operate it, you can't do your homework. That doesn't mean computers are difficult to use. Similarly, C++ is a tool, if you don't know it, it doesn't mean it's difficult.
Let's get to the problem.
The problem
The program should find and display all numbers of trains, which go to wanted destination. If there is no such train, the program must display "Unreachable city!".
Let's break it down
Reading the problem carefully, we can see that there is not just "one" train but multiple 'trains'.
We have to take input from the user (wanted destination)
Then we have to find "all" the "trains" that go that city.
If no train was found, we print "Unreachable city!"
The problem with your code
The problem with your code is that there is only "one train":
MyClass myObj; //one object only
You keep overwriting it's values every time you take input from the user.
Learning the tool
So, What can you do to fix this? In programming when we want to store multiple values of the same object we usually create an array. An array is just a collection of values of one type. Example:
int myarray[5]; //can store 5 "int" values
//size is given inside the [] (square brackets)
Array indexes start from 0. We can store values in array like following:
cin >> myarray[0]; //take input from user and store it into the "first" place in our array
cin >> myarray[1]; //store in the "second" place
cin >> myarray[4]; //store in the "last" place
cin >> myarray[5]; //WRONG! Don't do this. It will result in errors and bugs!! (Undefined Behaviour)
You can also store values directly:
int myarray[5] = {1, 2, 3, 4, 5};
cout << myarray[3]; // prints "4"
That's all nice and fine however there is a small problem with arrays. We have to know the "size" of the array before we create it.
int N;
cin >> N;
int array[N]; //WRONG, even it works, this is wrong.
So, what should we do? We can't know the number of objects we want always. Worry not, because C++ provides us with a nice container: std::vector which can be used to solve this issue.
#include <vector> // you need this for vector
int N;
cin >> N;
std::vector <int> myvector(N); //vector of size N
//access the values as you would with the array
myvector[0] = 10;
myvector[5] = 9; //WRONG.
Solving your problem
Note, that I will not give you the solution directly, but I will show you the way and give you the tools. It's your problem, it's your challenge, and if you try, it's pretty easy to solve the problem.
So we learned about vectors and arrays. Next, you may be wondering how to create vector for your type. Simple:
//create a vector, with size = N
vector <MyClass> Trains (N);
//take input from user
for (int i=0; i<N; i++){
cin >> Trains[i].city;
cin >> Trains[i].number;
}
The last part, will be quite similar. You need a loop, then go over all the values in the vector to find the "destinations" you want.
Side note
You should start with naming your objects and variables in a way that it is easy and natural for you to think about your problem. For example:
class MyClass
This doesn't tell anyone, anything about your class or what you want to do with it. What could be a better name for it? Looking at the problem, I suggest the name Train:
class Train {};
The problem also tells us that each train has a "destination city" and a "train number". We can refactor our Train class to contain the following:
class Train {
public:
string destination;
string number;
};

First, myObj is not a good name, let's change it to an empty list of destinations.
#include <vector>
...
vector <MyClass> destinations;
Next, push each new value into the vector. For this it would be better to have a constructor that sets the values. Constructing a destination with no values is pointless.
MyClass(string _c, string _n) : city(_c), number(_n) {};
...
string city, number;
cin >> city;
cin >> number;
destinations.pushback(MyClass(city, number));
Now you can write your loops to go through the vector looking for the data you need.

#include <iostream>
#include <string>
using namespace std;
#include <vector> // you need this for vector
class Train {
public:
string city;
string number;
};
int main(){
int N;
cin >> N;
string dest;
vector <Train> Trains (N);
int i;
//take input from user
for (i=0; i<N; i++){
cin >> Trains[i].city;
cin >> Trains[i].number;
}
cin >> dest;
for(i=0; i<Trains.size(); i++){
if(Trains[i].city==dest){
cout << Trains[i].number <<" ";
}
else{
cout << "Unreachable city!";
}
}
}
Now it is always printing Unreachable city next to right results :(

Related

C++ File to Vector

I've got a file that looks like this:
C 0484758654 95
C 0428473483 121
T 0494569848
C 0494569848 121
//.. 30 or so more entries
I want to store each "person" (represented by their phone number) into an object. I know I'll need a structure to store this in so I used a Vector:
using namespace std;
int main()
{
ifstream fin;
fin.open("test.txt");
vector<MonthlyPhoneBill> bill;
MonthlyPhoneBill temp;
while (fin >> temp.code>> temp.phoneNumber >> temp.data)
{
bill.push_back(temp);
}
for (const auto& temp : bill) {
cout << temp.code << ' ' << temp.phoneNumber << ' ' << temp.data << endl;
}
return 0;
}
Class:
class MonthlyPhoneBill {
public:
MonthlyPhoneBill();
int data;
int phoneNumber;
std::string code;
int totalBill;
};
I have a couple of problems however, the first problem is when I'm printing the file contents out it only prints the first line.
My second problem is that I have no idea how to manipulate the data now that it's stored in the vector. For example I'm wanting to calculate a bill for each individual person. I'm not sure how to access the contents of the vector and do calculations accordingly. From the file an individual person could come up multiple times and I'm not sure how to add the total cost each time they were to come up.
struct MonthPhoneBill {
int data;
int phoneNumber;
std::string code;
int totalBill;
};
int main () {
std::vector<MonthPhoneBill> dataEntry;
....
....
MonthPhoneBill temp;
// After Putting data into vector, one can simply access the data by.
while (fin >> temp.code>> temp.phoneNumber >> temp.data >> temp.totalBill) {
bill.push_back(temp);
}
Please keep in mind the content of file should be also in that format like in while loop and you have to stream all the content of that structure. you cannot miss it, if happened all the other entry will be garbage or could lead to code crash
auto temp0 = dataEntry[1].data;
auto temp1 = dataEntry[1].phoneNumber;
auto temp2 = dataEntry[1].code;
....
}
you can simply manipulate the data and access it.
Like #Sam Varshavchik said, look what's different about the third line, because indeed it is different - it's missing the last value, the data member. This causes the while to exit as it encounters no data when executing the last part of while (fin >> temp.code>> temp.phoneNumber >> temp.data), i.e. the >> temp.data.
As for the second question, again like #Sam Varshvchik said - consult your C++ book. You can manipulate the vector of your class entries in any operation, just like you did when printing contents.
To compute the total bill for each person seems to me that your program would need to undergo some changes. Since your users are repeated in the main vector, one way would be to iterate through it and group the repetitions into a single class object per user with summed bills. The other way would be to sort the main vector by phone numbers, i.e. users. Once sorted you could use approaches similar to ones in Chapter 7 of Lippman's C++ Primer.

Wrong value in array which contains instances of a class (C++)

I use an array to create instances of a class.
I declared them in the Header file:
Figure *soldier;
Fight *weapon;
In the cpp I use the following code to create it:
std::cout << "How many soldier? ";
std::cin >> i_soldier;
std::cout << "How many weapon? ";
std::cin >> i_weapon;
soldier= new Figure[i_soldier];
weapon = new Fight[i_weapon];
The class Figure has this constructor:
Figure::Figure()
{
position = 0;
}
When I'm running the code it compiles fine, but when I look the position at the begin, the last array entry has a wrong value; I guess it points at a value from a memory address. All the other entries have the value 0.
This is how I say which instance I want to go.
for(int i = 0; i <= i_soldier; i++)
{
soldier[i].position();
}
Does anybody know where the error can come from?
Arrays are 0-indexed, the last position of the array is i_soldier-1, change your condition to a strict <.

Creating an array of pointers to struct

I am having trouble of understanding how to create an array of pointers to structures. I tried to look up similar examples and threads in the forum but I still cannot get my code to work! As a result, I believe I have written an ugly piece of code that I do not know where it is wrong and how to fix it.
Here is the code:
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
struct Movie
{
string name;
int numawards;
int nomination;
int year;
};
void *readfile(ifstream &infile, int &n);
int main()
{
ifstream infile;
int n = 0;
infile.open("old_movies.txt");
Movie *oldmovies;
oldmovies = readfile (infile, n);
return 0;
}
//*function documentation//
void *readfile (ifstream &infile, int &n)
{
infile >> n;
Movie *movies;
movies = new Movie[n];
for (int i = 0 ; i < n ; i++)
{
infile >> movies[i]->year >> movies[i]->numawards >> movies[i]->nomination;
infile.ignore();
infile.ignore();
getline(infile, movies[i]->name);
cout << movies[i]->year << " " << movies[i]->numawards << " " << movies[i]->nomination << " " << endl << movies[i]->name<< endl; //the cout here is to test and see if the code works.
}
return movies;
}
The purpose of this code is to read a txt file that contains the movie name, how many awards, how may nominations, and what year it is produced, and then print it out using pointers. Here is what the file looks like:
2
1935 1 3
The Dark Angel
1935 4 6
The Informer
1935 1 8
the first 4 digits represents the year, the second one represents number of awards it has gotten, and the last digit represents the number of times it has been nominated to an award.
Anyway, I am stuck at this part and I am really clueless about what to do here. I just hope that this code is not that bad to a point where there are numerous things to be changed. Any help or advice would be greatly appreciated.
Let's look at what you have here:
Movie *movies;
movies = new Movie[n];
This allocates an array of Movie instances. To allocate an array of pointers dynamically, you need to change this to
Movie** movies;
movies = new Movie*[n];
Now inside the for loop, you need to allocate each Movie instance:
movies[i] = new Movie();
You should also change the readfile() to return a Movie** rather than a void* so that you don't have to use any casts later.
But do you really need an array of pointers? Why not just use an array of structs. This would avoid the extra level of indirection and make your code a little simpler.

C++ Creating a variable sized array from ifstream

Just a heads up: My c++ programming skills and terminology is intermediate at best. So please be gentle ;).
I am working on a multi-sort algorithm for a college class. Originally, I built the program to take in an array of 20 integers, since that was as big as the .txt files were. The final lab is now asking to take in files that have 10, 100, 1000, 10000, 100000 and 1000000 different numbers. I originally used an ifstream inside a for loop to read in the ints. Now that I need to read a variable amount of ints from a file, I have run into issues with this code. I have extensively searched this site and Google to find an answer to this problem. I have tried dozens of different code snippets, to no avail. Here is the code I am currently running that works for 20 ints.
int i;
int A[20];
int length;
char unsortedFilename[200];
ifstream unsorted;
cout << "Please type the full name of the file you would like sorted.\n* ";
cin >> unsortedFilename;
unsorted.open(unsortedFilename);
length = (sizeof(A) / sizeof(*A));
for( i = 0; i < length; i++ )
{
unsorted >> A[i];
cout << A[i] << "\n";
}
insertionSort();
I do have other code mixed in there, but it's error checking, selection of duplicate number removal, etc. I would like it so that code like this would run "i" number of times, where "i" is actually the number of ints in the file. Also, as I mentioned earlier, I will need to input a file that has 1,000,000 numbers in it. I don't believe that an int array will be able to hold that many numbers. Is it going to be as easy as swapping all my ints over to longs?
Thanks for any help you could provide.
As suggested in the comments, use std::vector<int> instead of an array.
Instead of a for loop, use a while loop. Break out of the while loop when there are no numbers to read.
The while loop:
std::vector<int> A;
int item;
while ( unsorted >> item )
{
A.push_back(item);
}
You can sort the std::vector by using std::vector::iterator or simply access the data through the int* returned by A.data().
You can simply read all the numbers into a vector. Then use the vector as you would have used the array.
#include <iostream>
#include <fstream>
#include <vector>
#include <string>
int main()
{
std::string unsortedFilename;
std::cout << "Please type the full name of the file you would like sorted.\n";
std::cin >> unsortedFilename;
std::ifstream is(unsortedFilename);
std::istream_iterator<int> start(is), end;
std::vector<int> A(start, end);
std::cout << "Read " << A.size() << " numbers" << std::endl;
}
What you want is a vector.
try this,
int i;
vector<int> A;
int length;
string unsortedFilename;
ifstream unsorted;
cout << "Please type the full name of the file you would like sorted.\n* ";
cin >> unsortedFilename;
unsorted.open(unsortedFilename);
int temp;
for( i = 0; unsorted >> temp; i++ )
{
A.push_back(temp);
cout << A[i] << "\n";
}
insertionSort();
A vector is basically a dynamic array. It automatically grows as more space is needed. That way it doesn't matter if you have 10, 100, or even 100000 items, it'll automatically grow for you.
Also use a string for your file name, some file names are longer than 200 characters.
Good Luck!
will need to input a file that has 1,000,000 numbers in it. I don't believe that an int array will be able to hold that many numbers.
Sure it can. 1 Million ints is ~4Mb of memory, which is a trivial amount. You can even declare it static just as you do now int A[1000000];.
But real problem is that you're assuming a fixed length in your code, rather than determine the length from the input. I guess this is what your assignment is trying to teach you, so I won't show you the solution. But consider using ifstream::eof and make your sort accept the length as an argument...

Getting multiple lines of input in C++

The first line contains an integer n (1 ≤ n ≤ 100). Each of the following n lines contains one word. All the words consist of lowercase Latin letters and possess the lengths of from 1 to 100 characters.
(Source: http://codeforces.com/problemset/problem/71/A)
How would you get input from the user given n? I tried using a while loop but it doesn't work:
#include <iostream>
using namespace std;
int main()
{
int n;
cin>>n;
int i;
while (i<=n) {
cin>>i ;
i++;
}
}
You probably meant to have something like:
#include <iostream>
int main() {
int n;
cin>>n;
int theInputNumbers[n];
for(int i = 0; i<n; ++i) {
cin >> theInputNumbers[i];
}
}
Your loop is really quite far off of what you need. What you wrote is extremely wrong such that I cannot provide advice other than to learn the basics of loops, variables, and input. The assistance you need is beyond the scope of a simple question/answer, you should consider buying a book and working through it cover to cover. Consider reading Programming Principles and Practice Using C++
Here is a working example of something approximating your question's requirements. I leave file input and output as an exercise up to you. I also make use of C++11's front and back std::string members. You would have to access via array index in older versions.
#include <iostream>
#include <string>
#include <sstream>
using namespace std;
int main(){
int totalWords;
cin >> totalWords;
stringstream finalOutput;
for (int i = 0; i < totalWords; ++i){
string word;
cin >> word;
if (word.length() > 10){
finalOutput << word.front() << (word.length() - 2) << word.back();
}else{
finalOutput << word;
}
finalOutput << endl;
}
cout << endl << "_____________" << endl << "Output:" << endl;
cout << finalOutput.str() << endl;
}
With that said, let me give you some advice:
Name your variables meaningfully. "int i" in a for loop like I have above is a common idiom, the "i" stands for index. But typically you want to avoid using i for anything else. Instead of n, call it totalWords or something similar.
Also, ensure all variables are initialized before accessing them. When you first enter your while loop i has no defined value. This means it could contain anything, and, indeed, your program could do anything as it is undefined behavior.
And as an aside: Why are you reading into an integer i in your example? Why are you then incrementing it? What is the purpose of that? If you read in input from the user, they could type 0, then you increment by 1 setting it to 1... The next iteration maybe they'll type -1 and you'll increment it by 1 and set it to 0... Then they could type in 10001451 and you increment by 1 and set it to 10001452... Do you see the problem with the logic here?
It seems like you are trying to use i as a counter for the total number of iterations. If you are doing this, do not also read input into i from the user. That completely undermines the purpose. Use a separate variable as in my example.