Making text output dynamic using ofstream - ofstream

I'm trying to create a program that outputs the vin, gallons, miles, and mpg of a car to a text file using ofstream.
outfile << setw(8) << "VIN" << setw(19) << "Miles" << setw(10) << "Gallons" << setw(6) << "MPG" << "\n" << "---------------------------------------------\n" << vin(0) << setw(10) << miles(0) << setw(6) << gallons(0) << setw(11) << fixed << showpoint << setprecision(1) << static_cast<double>(miles(0))/gallons(0)<< "\n" << vin(1) << setw(10) << miles(1) << setw(6) << gallons(1) << setw(11) << static_cast<double>(miles(1))/gallons(1) << "\n" << vin(2) << setw(10) << miles(2) << setw(6) << gallons(2) << setw(11) << static_cast<double>(miles(2))/gallons(2) << "\n" << vin(3) << setw(10) << miles(3) << setw(6) << gallons(3) << setw(11) << static_cast<double>(miles(3))/gallons(3) << "\n" << vin(4) << setw(10) << miles(4) << setw(6) << gallons(4) << setw(11) << static_cast<double>(miles(4))/gallons(4) << endl;
Is there a simpler way to accomplish this without having to repeat for each new row? Thanks.

First thing's first, you should object-orient your code to keep it concise. This means by preference keeping the vin, gallons, miles, and mpg as data members of a class.
struct Car
{
// ...
int vin, gallons, miles, mpg;
};
Then you can implement stream inserters/extractors for input and output. Create and put your Car elements in a std::vector<Car> and iterate through them to read or write them to standard input/output.
Ultimately, the line above should be transformed into:
for (const auto& c : cars)
{
std::cout << c << std::endl;
}

Related

Generate C++ string with space behind such that space is automatically adjusted

I am trying to create a text generator which shall generate following output:
localparam OR_CHANNEL_DATA_WIDTH = 2;
localparam RQ_CHANNEL_DATA_WIDTH = 18;
localparam RSP_CHANNEL_DATA_WIDTH = 8;
localparam VIN_CHANNEL_DATA_WIDTH = 43;
localparam VOUT_CHANNEL_DATA_WIDTH = 123;
I used std::stringstream to build the stream:
std::stringstream ss;
ss << "localparam OR_CHANNEL_DATA_WIDTH" << std::right << std::setw(80) << " = " << Sth::get() << ";\n";
ss << "localparam RQ_CHANNEL_DATA_WIDTH" << std::right << std::setw(80) << " = " << Sth::get() << ";\n";
ss << "localparam RSP_CHANNEL_DATA_WIDTH" << std::right << std::setw(80) << " = " << Sth::get() << ";\n";
Sth::get() will return number. There are many such lines that needs to be generated. But the text in the middle is not fixed. How can I achieve the above output
I am not sure you can do it in a simple streaming operation, but easily write a small function that does the job:
#include <iostream>
#include <sstream>
#include <iomanip>
const std::string adjust_width(const std::string& s, int width)
{
std::stringstream temp;
temp << std::left << std::setw(width) << s;
return temp.str();
}
int main()
{
std::stringstream ss;
ss << adjust_width("localparam OR_CHANNEL_DATA_WIDTH", 80) << " = " << 1 << ";\n";
ss << adjust_width("localparam RQ_CHANNEL_DATA_WIDTH", 80) << " = " << 12 << ";\n";
ss << adjust_width("localparam RSP_CHANNEL_DATA_WIDTH", 80) << " = " << 123 << ";\n";
ss << adjust_width("localparam VIN_CHANNEL_DATA_WIDTH", 80) << " = " << 1234 << ";\n";
std::cout << ss.str();
return 0;
}

problem with polygon_90_data and vertices

I create a boost polygon with 5 vertices, but when I display the vertices or
#include <boost/polygon/polygon.hpp>
.
.
.
void displayPolygon(boost::polygon::polygon_90_data<int> const& polygon, std::string name)
{
std::cout << std::endl << "polygon " << name << std::endl;
for (boost::polygon::polygon_90_data<int>::iterator_type it = polygon.begin(); it != polygon.end(); it++)
{
std::cout << (*it).x() << "/" << (*it).y() << "->";
}
std::cout << std::endl;
}
.
.
.
void testPolygon2()
{
//typedef
typedef boost::polygon::polygon_90_data<int> Polygon90Type;
typedef std::vector<Polygon90Type> Polygon90Set;
typedef boost::polygon::polygon_data<int> PolygonType;
typedef std::vector<PolygonType> PolygonSet;
typedef boost::polygon::point_data<int> PointType;
typedef std::vector<PointType> PointSet;
typedef boost::polygon::polygon_traits<Polygon90Type>::point_type Point;
Polygon90Type polygon_1;
Point pts_1[6] = { Point(0,0), Point(0,10), Point(5,12), Point(10,10), Point(10,0), Point(0,0)};
polygon_1.set(pts_1, pts_1 + 6);
std::cout << "polygon_1 area is " << boost::polygon::area(polygon_1) << std::endl;
std::cout << std::endl << __LINE__ << " :
Polygon90Set polygonSet;
polygonSet.push_back(polygon_1);
//an attempt to see result of bloating with 0
boost::polygon::bloat(polygonSet, 0, 0, 0, 0);
std::cout << "nb polygon bloated " << polygonSet.size() << std::endl;
for (auto polygon : polygonSet)
{
std::cout << std::endl << __LINE__ << "####################################" << std::endl;
displayPolygon(polygon, "2 - after being bloated");
std::cout << "area is " << boost::polygon::area(polygon) << std::endl;
}
}
the area it does not correspond to the polygon created.
the area should be 110 but is displayed as 100?
the vertices should be (0,0), (0,10), (5,12), (10,10), (10,0) but are (0/10), (5/10) ,(5/10), (10/10), (10/0), (0/0). It looks like the point (/5/12) is dismissed and replaced with point (5/10).
What am I doing wrong?
thanks.

How to compose and form the binary literals, for example through the conversion from decimal in C++11 / C++14?

int main() {
int x = 3613;
std::cout << "x= " << x << std::endl;
std::string xBin = std::bitset<16>(x).to_string();
std::cout << xBin << std::endl;
unsigned long xDecimal = std::bitset<16>(xBin).to_ulong();
std::cout << xDecimal << std::endl;
std::cout << std::endl << std::endl;
int b01 = 0b11001;
std::cout << "b01= " << b01 << std::endl;
int b02 = 0b1010;
std::cout << "b02= " << b02 << std::endl;
int b03 = b01 + b02;
std::cout << "int b03 = b01 + b02 = " << b03 << std::endl;
return 0;
}
Output:
x= 3613
0000111000011101
3613
b01= 25
b02= 10
int b03 = b01 + b02 = 35
With binary literals we can do normal arithmetic operations, while with the strings obtained with std::bitset<> this is not possible.
So...the question is: how to "compose" the binary literals, for example through the conversion from decimal to binary as obtained using std::bitset<> ?
Looking forward to your kind help. Marco
You shouldn't operate on bitsets by converting them to string and back - that's missing the point of bitsets... Instead you operate on them by using binary operators: &, |, ^, ... (just like you would on usual integers).
std::cout << std::bitset<3>(4) << " or "
<< std::bitset<3>(2) << " = "
<< (std::bitset<3>(4) | std::bitset<3>(2)) << std::endl;
Prints: 100 or 010 = 110
You can find all operators on wiki: http://en.cppreference.com/w/cpp/utility/bitset

C++ 11- scopes & global variables

How can I reach global variables from inner scopes, given the following code sample, how can I reach the global string X from the main function and from the most inner scope as well, also is the most inner scope is accessible once we quit it to the main scope or other scope?
#include <iostream>
#include <string>
std::string x = "global";
int counter = 1;
int main()
{
std::cout <<counter ++ << " " << x << std::endl;
std::string x = "main scope";
std::cout <<counter ++ << " " << x << std::endl;
{
std::cout <<counter ++ << " " << x << std::endl;
std::string x = "inner scope";
std::cout <<counter ++ << " " << x << std::endl;
}
std::cout <<counter++ << " " << x << std::endl;
}
the cout currently is:
1 global
2 main scope
3 main scope
4 inner scope
5 main scope
Global scope can be reached by using ::x, as per:
#include <iostream>
#include <string>
std::string x = "global";
int counter = 1;
int main()
{
std::cout << counter++ << " " << x << std::endl;
std::string x = "main scope";
std::cout << " " << ::x << std::endl;
std::cout << counter++ << " " << x << std::endl;
{
std::cout << " " << ::x << std::endl;
std::cout << counter++ << " " << x << std::endl;
std::string x = "inner scope";
std::cout << " " << ::x << std::endl;
std::cout << counter++ << " " << x << std::endl;
}
std::cout << " " << ::x << std::endl;
std::cout << counter++ << " " << x << std::endl;
}
which gives you:
1 global
global
2 main scope
global
3 main scope
global
4 inner scope
global
5 main scope
The hard bit is actually getting to the intermediate scopes, such as main scope when you're withing the inner scope.
One way to do that is with references:
#include <iostream>
#include <string>
std::string x = "outer";
int main()
{
std::cout << "1a " << x << "\n\n";
std::string x = "middle";
std::cout << "2a " << ::x << '\n';
std::cout << "2b " << x << "\n\n";
{
std::string &midx = x; // make ref to middle x.
std::string x = "inner"; // hides middle x.
std::cout << "3a " << ::x << '\n';
std::cout << "3b " << midx << '\n'; // get middle x via ref.
std::cout << "3c " << x << "\n\n";
}
}
which gives:
1a outer
2a outer
2b middle
3a outer
3b middle
3c inner
But, as good advice, you'll find you won't have anywhere near as many problems if you:
name your variables a little more intelligently so as to avoid clashes; and
avoid global variables like the plague :-)
And, as for the variables in inner scopes, they cease to be available once you leave that scope, even with a reference (you can copy them to a variable with an larger scope but that's not the same as accessing the inner-scoped variable).

I need help formatting code created in Microsoft Visual Studio to work in Xcode on Mac

I have a small bit of code I made on Microsoft Visual studio that is a simple program I used to teach someone the fundamentals of C++. I am moving to Xcode and it is new to me. I need help reformatting this code so it can be run on a mac. Please help!
#include <iostream>
#include <string>
#include <random> //this needs to be included for the rand() function
#include <time.h> //this needs to be included for the seed time
#include <windows.h>
#include <conio.h>
using namespace std;
//PAB
int random_in_range(int a, int b)//this function will generate a random number between specified range
{
return (a+rand()%(b-a+1));
}
void hangman(){
char guess;
string word="";
string hidden ="";
int strikesLeft= 0;
int random = random_in_range(1,15);
switch(random){
case 1:
word = "bacon";
hidden ="?????";
strikesLeft=5;
break;
case 2:
word = "computer";
hidden ="????????";
strikesLeft=7;
break;
case 3:
word = "human";
hidden = "?????";
strikesLeft=7;
break;
case 4:
word = "desk";
hidden = "????";
strikesLeft=7;
break;
case 5:
word = "card";
hidden = "????";
strikesLeft=7;
break;
case 6:
word="keyboard";
hidden = "????????";
strikesLeft=7;
break;
case 7:
word="phone";
hidden="?????";
strikesLeft=7;
break;
case 8:
word="mouse";
hidden="?????";
strikesLeft=7;
break;
case 9:
word="camp";
hidden="????";
strikesLeft=7;
break;
case 10:
word="captain";
hidden="???????";
strikesLeft=7;
break;
case 11:
word="brother";
hidden="???????";
strikesLeft=7;
break;
case 12:
word="beauty";
hidden="??????";
strikesLeft=7;
break;
case 13:
word="cave";
hidden="????";
strikesLeft=7;
break;
case 14:
word="children";
hidden="????????";
strikesLeft=7;
break;
case 15:
word="action";
hidden="??????";
strikesLeft=7;
break;
}
bool gameOver=false;
int pos;
//add strike counter
cout << " ***WELCOME TO HANGMAN***" << endl << endl;
cout << "Try to guess the word in question marks. But watch out, if you use too many letters not in the word, you will lose." << endl;
cout << "You start with " << strikesLeft << " strikes." << endl;
cout << "Good luck..." << endl;
do{
cout << "Word is " << hidden << endl << endl;
cout << "Enter guess: ";
cin >> guess;
pos = word.find_first_of(guess);
if(pos!=-1)
hidden[pos]=guess;
else{
strikesLeft--;
cout <<"Sorry, " << guess << " is not in this word." << endl;
cout <<"You have " << strikesLeft << " strikes left." << endl; //also tell them strikes remaining
}
if(hidden==word || strikesLeft==0)
gameOver=true;
}
while(gameOver==false);
if(strikesLeft==0)
cout << "Game Over! You failed..." << endl;
cout << "The word was " << word << "." << endl;
if(strikesLeft>0)
cout << "Congrats! You completed my game with " << strikesLeft << " strikes left." << endl;
system("PAUSE");
}
int main(){
cout << "" << endl << endl << endl << endl << endl << endl << endl;
cout << " *WELCOME*" << endl;
system("color 0c");
Sleep(500);
cout << " **TO**" << endl;
system("color 0f");
Sleep(500);
cout << " ***PAB***";
system("color 0a");
Sleep(3000);
system("cls");
cout << "" << endl << endl << endl << endl << endl << endl << endl;
cout << " P";
Sleep(100);
cout << "E";
Sleep(100);
cout << "R";
Sleep(100);
cout << "S";
Sleep(100);
cout << "O";
Sleep(100);
cout << "N";
Sleep(100);
cout << "A";
Sleep(100);
cout << "L";
Sleep(1000);
cout << " A";
Sleep(100);
cout << "W";
Sleep(100);
cout << "E";
Sleep(100);
cout << "S";
Sleep(100);
cout << "O";
Sleep(100);
cout << "M";
Sleep(100);
cout << "E";
Sleep(1000);
cout << " B";
Sleep(150);
cout << "O";
Sleep(150);
cout << "T";
Sleep(2000);
system("cls");
system("color 08");
cout << "Program loading.";
Sleep(500);
system("cls");
cout << "Program loading..";
Sleep(500);
system("cls");
cout << "Program loading...";
Sleep(500);
system("cls");
cout << "Program loading.";
Sleep(500);
system("cls");
cout << "Program loading..";
Sleep(500);
system("cls");
cout << "Program loading...";
Sleep(500);
system("cls");
cout << "Program loading.";
Sleep(500);
system("cls");
cout << "Program loading..";
Sleep(500);
system("cls");
srand(time(NULL));//seeds the random number generator. Do this before calling the randomInRange function
string name;
int friends;
int DecimalArray[] = {1,2,3,4,5,22,555,85,18,741}; //Create an array of decimal numbers.
system ("color 0f");
cout << "Enter name: ";
cin >> name;
cout << "Hi " << name << "." << " My name is PAB, your personal awesome bot." << endl;
cout << "Now tell me, how many friends do you have? " << endl;
cin >> friends;
if(friends >=75 && friends <300)
cout << "Gee, " << friends << " friends is a lot. But you could always have one more...ME!!" << endl;
if(friends >300)
cout << "Yeah, maybe on Facebook...But we should still be friends!" << endl;
if(friends <75)
cout << "Man, you totally need more friends. I can be one of them!" << endl;
int randomNum=random_in_range(1,50);
int numGuess;
cout << "Now that we're friends, I want to play a game. Now, pick a number between 1 and 50. " << endl;
do{ //dowhile loop using "getting closer" for when your getting closer to the number
cin >> numGuess;
if(numGuess >50)
cout << "Can you read? It clearly says between 1 and 50. " << endl;
if(numGuess >randomNum)
cout << "That's too high guess again. " << endl;
if(numGuess <randomNum)
cout << "That's too low please guess again. " << endl;
}while(numGuess !=randomNum);
system("cls");
cout << "Congratulations! You found out my number." << endl;
cout << "Okay, I agree that was stupid. But, I have another game!" << endl << endl << endl;
hangman();
system("cls");
cout << "Thanks for playing with me today! I hope you had fun." << endl;
cout << "In the future I will have new games and jokes." << endl << endl << endl << endl << endl << endl;
cout << " THE END" << endl;
Sleep(5000);
system("cls");
system("color 08");
cout << "v1.7" << endl;
cout << "[copyright]" << endl;
cout << "Ethan MacCumber 2012" << endl;
system("PAUSE");
return 0;
}
Your major problem is that your code isn't entirely standard C++. You used C++ code that is only available on Windows, the functions in the windows.h and conio.h header files. Any functions in those header files won't work on a Mac.
If you want your code to run on Mac OS X, comment out the includes of windows.h and conio.h. Commenting out the includes of the Windows-specific headers will generate a ton of compiler errors, which should show you where the Windows-specific code is. Get rid of that code and stick with code that is standard C++, like cin and cout. From a quick glance at your code, the calls to Sleep() and System("cls") won't work on a Mac.

Resources