Working with GPS Output using C++ - c++

Hi I'm working with GPS output. To be more accurate I'm working using the $GPRMC output. Now the output that I get is in the following form:
$GPRMC,225446,A,4916.45 N,12311.12 W,000.5,054.7,191194,020.3 E,*68"
This output constitutes of time, lats, longs, speed in knots, info about course, date, magnetic variation and mandatory checksum.
The image that I have attached shows the current result I'm getting as I'm taking out the sub strings from the string.
Now I'm getting the time in the hhmmss format. I want it in hh:mm:ss format.
Plus I'm getting the longitude as 4916.45 N. I want to get it as 49 degrees 16' 45".
And the latitude as 123 degrees 11' 12". I'm a beginner so I really don't know how to convert the format. I have also attached my code below.
#include<iostream>
#include<string>
#include<sstream>
#include<stdio.h>
#include<conio.h>
using namespace std;
int main()
{
std::string input = "$GPRMC,225446,A,4916.45 N,12311.12 W,000.5,054.7,191194,020.3 E,*68";
std::istringstream ss(input);
std::string token;
string a[10];
int n = 0;
while (std::getline(ss, token, ','))
{
//std::cout << token << '\n';
a[n] = token;
n++;
}
cout << a[0] << endl << endl;
cout << "Time=" << a[1] << endl << endl;
cout << "Navigation receiver status:" << a[2] << endl << endl;
cout << "Latitude=" << a[3] << endl << endl;
cout << "Longitude=" << a[4] << endl << endl;
cout << "Speed over ground knots:" << a[5] << endl << endl;
cout << "Course made good,True:" << a[6] << endl << endl;
cout << "Date of Fix:" << a[7] << endl << endl;
cout << "Magnetic variation:" << a[8] << endl << endl;
cout << "Mandatory Checksum:" << a[9] << endl << endl;
_getch();
return 0;
}

First thing is that your NMEA sentence is wrong, there should be commas ',' before N and W, so you will actually have to parse "12311.12" and not "12311.12 W". You can check it on this site: http://aprs.gids.nl/nmea/#rmc, you should also always check checksum of sentence - for online checks use: http://www.hhhh.org/wiml/proj/nmeaxor.html.
To parse longitude and latitude I suggest regexps, I am notsaying this is regexp is correct - it only parses data you have provided:
#include <iostream>
#include <string>
#include <regex>
#include <iostream>
std::tuple<int,int,int> parseLonLat(const std::string& s) {
std::regex pattern("(\\d{2,3})(\\d+{2})\\.(\\d+{2})" );
// Matching single string
std::smatch sm;
if (std::regex_match(s, sm, pattern)) {
return std::make_tuple(std::stoi(sm[1]), std::stoi(sm[2]), std::stoi(sm[3]));
}
return std::make_tuple(-1,-1,-1);
}
int main (int argc, char** argv) {
auto loc1 = parseLonLat("4916.45");
std::cout << std::get<0>(loc1) << ", " << std::get<1>(loc1) << ", " << std::get<2>(loc1) << "\n";
// output: 49, 16, 45
auto loc2 = parseLonLat("12311.12");
std::cout << std::get<0>(loc2) << ", " << std::get<1>(loc2) << ", " << std::get<2>(loc2) << "\n";
// output: 123, 11, 12
}
http://coliru.stacked-crooked.com/a/ce6bdb1e551df8b5

You'll have to parse that yourself; there's no GPS parsing in standard C++.
You may want to write your own Angle class in order to have 49 degrees 16' 45" as possible output. You'll want to overload operator<< for that.

Related

In C ,we use %x.ys for string manipulation. What it will be in C++?

How can I replace printf() with cout?
My Code In C++:
#include<iostream>
#include<cstdio>
using namespace std;
int main ()
{
char st[15]="United Kingdom";
printf("%5s\n",st);
printf("%15.6s\n",st);
printf("%-15.6s\n",st);
printf("%.3s\n",st); // prints "Uni"
return 0;
}
The Code Prints:
United Kingdom
United
United
Uni
How can I manipulate like this in C++?
The std::setw() I/O manipulator is the direct equivalent of printf()'s minimum width for strings, and the std::left and std::right I/O manipulators are the direct equivalent for justification within the output width. But there is no direct equivilent of printf()'s precision (max length) for strings, you have to truncate the string data manually.
Try this:
#include <iostream>
#include <iomanip>
using namespace std;
int main ()
{
char st[15] = "United Kingdom";
cout << setw(15) << st << '\n'; // prints " United Kingdom"
cout << setw(5) << st << '\n'; // prints "United Kingdom"
cout << setw(15) << string(st, 6) << '\n'; // prints " United"
cout << left << setw(15) << string(st, 6) << '\n'; // prints "United "
cout << setw(15) << string(st, 0) << '\n'; // prints " "
cout << string(st, 3) << '\n'; // prints "Uni"
cout << st << '\n; // prints "United Kingdom"
return 0;
}
Live demo
The std::setw() iomanip will set the field width for insertions, that is, even if the isinsertions shorter than the specified lenth it will get padded to that amount, std::setfill() sets the padding character.
For example:
std::cout << std::setw(20) << std::setfil('0') << "hey you!" << std::endl;
would print "Hey you!000000000000\n" (possibly \r\n instead of just \n if you're using Windows). There is also std::left which would cause the padding to precede rather than follow the insert.
You are looking for Boost.Format.
#include <iostream>
#include <string>
#include <boost/format.hpp>
int main()
{
std::string st = "United Kingdom";
std::cout << boost::format("%15s\n") % st;
std::cout << boost::format("%5s\n") % st;
std::cout << boost::format("%15.6s\n") % st;
std::cout << boost::format("%-15.6s\n") % st;
std::cout << boost::format("%15.0s\n") % st;
std::cout << boost::format("%.3s\n") % st; // prints "Uni"
std::cout << boost::format("%s\n") % st;
}
Live example

Compilation errors when using cout

I have compilation errors to just simply output a cout message. Below is my code:
#include <iostream>
#include <iomanip>
#include <string>
using namespace std;
int main()
{
char letter = 'a';
short age = 10;
int cout = 575;
long numStars = 985632145;
float pi = 3.1;
double price = 89.65;
string season = "summer";
cout << "Letter: "<< letter << endl;
std::cout << "Age: " << age<< endl;
std::cout << "Cout: " << cout << endl;
std::cout << "Number Stars: " << numStars << endl;
std::cout << "Pi: " << pi << endl;
std::cout << "Price: " << price << endl;
std::cout << "Season: " << season;
system("pause");
return 0;
}
The errors I get are on the line:
cout << "Letter: "<< letter << endl;
I have tried reinstalling VS2015 but that didn't help.
You have a variable of type int called cout - this is not allowed given that you are using namespace std. Change this variable name to something else, and avoid the statement using namespace std.
std::cout is a "reserved type/keyword" so you cannot use it as a variable name.

Change length of dashed line to match input string length?

#include <iostream>
#include <string>
using namespace std;
int main()
{
string name;
int income;
int tax;
cout << "What is your full name? ";
getline(cin,name);
cout << "What is your annual income? ";
cin >> income;
if (income < 50000)
{
tax = income*0.33;
}
else { tax = income*0.38; }
cout << "\t\t\t" << name << ": Tax Report" << endl;
cout << "\t\t\t" << "-------------------------" << endl;
cout << "Income =$" << income << endl;
cout << "Tax =$" << tax << endl;
system("pause");
return 0;
}
I would like the line of hyphens to match the length of the name string regardless of its length. I am in an introductory c++ class and I am sure there is a simple way to do this. Could anyone help?
cout << "\t\t\t" << string(name.length() + 12, '-') << endl;
just put in this line, instead of your current dash line
cout << "\t\t\t" << std::string(name.length(), '-') << endl;
for further information see http://en.cppreference.com/w/cpp/string/basic_string/basic_string
You can do it the following way
#include <iostream>
#include <iomanip>
int main()
{
std::string name( "01234567890" );
std::cout << "\t\t\t" << name << ": Tax Report" << std::endl;
std::cout << "\t\t\t" << std::setfill( '-' ) << std::setw( name.size() )
<< '-' << std::endl;
return 0;
}
The program output is
01234567890: Tax Report
-----------
If you want that all preceding line would be underlined then you need tp add the size of string ": Tax Report" to the argument of std:;setw For example
#include <iostream>
#include <iomanip>
int main()
{
std::string name( "01234567890" );
std::cout << "\t\t\t" << name << ": Tax Report" << std::endl;
std::cout << "\t\t\t" << std::setfill( '-' ) << std::setw( name.size() + 12 )
<< '-' << std::endl;
return 0;
}
In this case the porgram output is
01234567890: Tax Report
-----------------------
Thus all you need is to use functions std::setfill and std::setw declared in header <iomanip>. There is no need to a create a temporary object of type std::string because it is inefficient..
You can make a string of hyphens of a certain length. Get the length by first building a string for the name line and then calling its length method. Here is an example:
std::string hyphens;
hyphens.assign(length, '-');
check out thislink for more details on using strings:
http://www.cplusplus.com/reference/string/string/

(C++) Goto statement not working. Beginner [closed]

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 8 years ago.
Improve this question
I'm making a USD to MXN converter and I want to have it work both ways. The if statement works (tryed cout << "test"; and it worked) but it wont work when I replace it with the goto statement.
#include "stdafx.h"
#include <cstdlib>
#include <iostream>
using namespace std;
int main(int argc, char *argv[])
{
int user;
int u, m;
cout << "US/MXN Converter" << endl;
cout << "1 US = 12.99 MXN (6/12/2014)" << endl;
cout << endl;
cout << "What Way to convert" << endl;
cout << "[1] US to MXN" << endl;
cout << "[2] MXN to US" << endl;
cout << "Selection: ";
cin >> user;
if (user == 1)
{
goto USTMXN;
}
else
{
goto MXNTUS;
}
USTMXN:
cout << "Enter the amount of US Dollars to Convert" << endl;
cout << "Amount: ";
cin >> u;
m = u * 12.99;
cout << endl;
cout << "MXN Pesos: " << m << endl;
goto END;
MXNTUS:
int mm, uu;
cout << "Enter the amount of Pesos to Convert" << endl;
cout << "Amount: ";
cin >> mm;
uu = mm / 12.99;
cout << endl;
cout << "US Dollars: " << m << endl;
goto END;
END:
system("PAUSE");
return EXIT_SUCCESS;
}
One of the most fundamental things we have to do as programmers is to learn to break problems into smaller problems. You are actually running into a whole series of problems.
I'm going to show you how to solve your problem. You may want to book mark this answer, because I'm pre-empting some problems you're going to run into a few steps down the line and preparing you - if you pay attention - to solve them on your own ;)
Let's start by stripping down your code.
Live demo here: http://ideone.com/aUCtmM
#include <iostream>
int main()
{
std::cout << "Enter a number: ";
int i;
std::cin >> i;
std::cout << "Enter a second number: ";
int j;
std::cin >> j;
std::cout << "i = '" << i << "', j = '" << j << "'\n";
}
What are we checking here? We're checking that we can ask the user two questions. That works fine.
Next is your use of goto, which I strongly recommend you do not use. It would be better to use a function. I'll demonstrate with your goto case here first:
#include <iostream>
int main()
{
int choice;
std::cout << "Enter choice 1 or 2: ";
std::cin >> choice;
if ( choice == 1 )
goto CHOSE1;
else if ( choice == 2 )
goto CHOSE2;
else {
std::cout << "It was a simple enough question!\n";
goto END;
}
CHOSE1:
std::cout << "Chose 1\n";
goto END;
CHOSE2:
std::cout << "Chose 2\n";
goto END;
END:
std::cout << "Here we are at end\n";
}
live demo: http://ideone.com/1ElcV8
So goto isn't the problem.
That leaves your use of variables. You've really mixed things up nastily by having a second set of variables (mm, uu). Not only do you not need to have these, you're doing something very naughty in that these variables only exist inside one scope and not the other. You can "get away" with this but it will come back to haunt you later on.
The difference in your two main streams of code is the variable names. The second conversion case looks like this:
MXNTUS:
int mm, uu;
cout << "Enter the amount of Pesos to Convert" << endl;
cout << "Amount: ";
cin >> mm;
uu = mm / 12.99;
cout << endl;
cout << "US Dollars: " << m << endl;
goto END;
The problem here is that you have - accidentally - used the variable "m" in your output. It's what we call uninitialized.
cout << "US Dollars: " << m << endl;
That m in the middle should be mm.
Your compiler should actually be warning you about this. If it's not, and you're just setting out learning, you should figure out how to increase the compiler warning level.
It would be better to make a function to do the conversions; you could make one function for each direction, but I've made a function that handles both cases:
#include <iostream>
static const double US_TO_MXN = 12.99;
static const char DATA_DATE[] = "6/12/2014";
void convert(const char* from, const char* to, double exchange)
{
std::cout << "Enter the number of " << from << " to convert to " << to << ".\n"
"Amount: ";
int original;
std::cin >> original;
std::cout << to << ": " << (original * exchange) << '\n';
}
int main() // this is valid since C++2003
{
std::cout << "US/MXN Converter\n"
"1 US = " << US_TO_MXN << " MXN (" << DATA_DATE << ")\n"
"\n";
int choice = 0;
// Here's a better demonstration of goto
GET_CHOICE:
std::cout << "Which conversion do you want to perform?\n"
"[1] US to MXN\n"
"[2] MXN to US\n"
"Selection: ";
std::cin >> choice;
if (choice == 1)
convert("US Dollars", "Pesos", US_TO_MXN);
else if (choice == 2)
convert("Pesos", "US Dollars", 1 / US_TO_MXN);
else {
std::cerr << "Invalid choice. Please try again.\n";
goto GET_CHOICE;
}
// this also serves to demonstrate that goto is bad because
// it's not obvious from the above that you have a loop.
}
ideone live demo: http://ideone.com/qwpRtQ
With this, we could go on to clean things up a whole bunch and extend it:
#include <iostream>
using std::cin;
using std::cout;
static const double USD_TO_MXN = 12.99;
static const double GBP_TO_MXN = 22.03;
static const char DATA_DATE[] = "6/12/2014";
void convert(const char* from, const char* to, double exchange)
{
cout << "Enter the number of " << from << " to convert to " << to << ".\n"
"Amount: ";
int original;
cin >> original;
cout << '\n' << original << ' ' << from << " gives " << int(original * exchange) << ' ' << to << ".\n";
}
int main() // this is valid since C++2003
{
cout << "Foreign Currency Converter\n"
"1 USD = " << USD_TO_MXN << " MXN (" << DATA_DATE << ")\n"
"1 GBP = " << GBP_TO_MXN << " MXN (" << DATA_DATE << ")\n"
"\n";
for ( ; ; ) { // continuous loop
cout << "Which conversion do you want to perform?\n"
"[1] USD to MXN\n"
"[2] MXN to USD\n"
"[3] GBP to MXN\n"
"[4] MXN to GBP\n"
"[0] Quit\n"
"Selection: ";
int choice = -1;
cin >> choice;
cout << '\n';
switch (choice) {
case 0:
return 0; // return from main
case 1:
convert("US Dollars", "Pesos", USD_TO_MXN);
break;
case 2:
convert("Pesos", "US Dollars", 1 / USD_TO_MXN);
break;
case 3:
convert("British Pounds", "Pesos", GBP_TO_MXN);
break;
case 4:
convert("Pesos", "British Pounds", 1 / GBP_TO_MXN);
break;
default:
cout << "Invalid selection. Try again.\n";
}
}
}
http://ideone.com/iCXrpU
There is a lot more room for improvement with this, but I hope it helps you on your way.
---- EDIT ----
A late tip: It appears you're using visual studio, based on the system("PAUSE"). Instead of having to add to your code, just use Debug -> Start Without Debugging or press Ctrl-F5. It'll do the pause for you automatically :)
---- EDIT 2 ----
Some "how did you do that" points.
cout << '\n' << original << ' ' << from << " gives " << int(original * exchange) << ' ' << to << ".\n";
I very carefully didn't do the using namespace std;, when you start using more C++ that directive will become the bane of your existence. It's best not to get used to it, and only let yourself start using it later on when you're a lot more comfortable with C++ programming and more importantly debugging odd compile errors.
But by adding using std::cout and using std::cin I saved myself a lot of typing without creating a minefield of function/variable names that I have to avoid.,
What does the line do then:
cout << '\n' << original << ' ' << from << " gives " << int(original * exchange) << ' ' << to << ".\n";
The '\n' is a single character, a carriage return. It's more efficient to do this than std::endl because std::endl has to go poke the output system and force a write; it's not just the end-of-line character, it actually terminates the line, if you will.
int(original * exchange)
This is a C++ feature that confuses C programmers. I'm actually creating a "temporary" integer with the result of original * exchange as parameters.
int i = 0;
int i(0);
both are equivalent, and some programmers suggest it is better to get into the habit of using the second mechanism so that you understand what happens when you later run into something called the "most vexing parse" :)
convert("Pesos", "British Pounds", 1 / GBP_TO_MXN)
The 1 / x "invert"s the value.
cout << "Foreign Currency Converter\n"
"1 USD = " << USD_TO_MXN << " MXN (" << DATA_DATE << ")\n"
"1 GBP = " << GBP_TO_MXN << " MXN (" << DATA_DATE << ")\n"
"\n";
This is likely to be confusing. I'm mixing metaphors with this and I'm a little ashamed of it, but it reads nicely. Again, employ the concept of breaking problems up into smaller problems.
cout << "Hello " "world" << '\n';
(note: "\n" and '\n' are different: "\n" is actually a string whereas '\n' is literally just the carriage return character)
This would print
Hello world
When C++ sees two string literals separated by whitespace (or comments) like this, it concatenates them, so it actually passes "Hello world" to cout.
So you could rewrite this chunk of code as
cout << "Foreign Currency Converter\n1 USD = ";
cout << USD_TO_MXN;
cout << " MXN (";
cout << DATA_DATE;
cout << ")\n1 GBP = ";
cout << GBP_TO_MXN;
cout << " MXN (";
cout << DATA_DATE;
cout << ")\n\n";
The << is what we call "semantic sugar". When you write
cout << i;
the compiler is translating this into
cout.operator<<(i);
This odd-looking function call returns cout. So when you write
cout << i << j;
it's actually translating it to
(cout.operator<<(i)).operator<<(j);
the expression in parenthesis (cout.operator<<(i)) returns cout, so it becomes
cout.operator<<(i); // get cout back to use on next line
cout.operator<<(j);
Main's fingerprint
int main()
int main(int argc, const char* argv[])
Both are legal. The first is perfectly acceptable C or C++. The second is only useful when you plan to capture "command line arguments".
Lastly, in main
return 0;
Remember that main is specified as returning int. The C and C++ standards make a special case for main that say its the only function where it's not an error not to return anything, in which case the program's "exit code" could be anything.
Usually its best to return something. In C and C++ "0" is considered "false" while anything else (anything that is not-zero) is "true". So C and C++ programs have a convention of returning an error code of 0 (false, no error) to indicate the program was successful or exited without problems, or anything else to indicate (e.g. 1, 2 ... 255) as an error.
Using a "return" from main will end the program.
Try to change youre code for sth like this. Using goto label is not recommended.
Main idea of switch statement :
int option;
cin >> option
switch(option)
{
case 1: // executed if option == 1
{
... code to be executed ...
break;
}
case 99: //executed id option == 99
{
... code to be executed
break;
}
default: // if non of above value was passed to option
{
// ...code...
break;
}
}
Its only example.
int main(int argc, char *argv[])
{
int user;
int u, m;
cout << "US/MXN Converter" << endl;
cout << "1 US = 12.99 MXN (6/12/2014)" << endl;
cout << endl;
cout << "What Way to convert" << endl;
cout << "[1] US to MXN" << endl;
cout << "[2] MXN to US" << endl;
cout << "Selection: ";
cin >> user;
switch(user )
{
case 1 :
{
//USTMXN:
cout << "Enter the amount of US Dollars to Convert" << endl;
cout << "Amount: ";
cin >> u;
m = u * 12.99;
cout << endl;
cout << "MXN Pesos: " << m << endl;
break;
}
}
default :
{
//MXNTUS:
int mm, uu;
cout << "Enter the amount of Pesos to Convert" << endl;
cout << "Amount: ";
cin >> mm;
uu = mm / 12.99;
cout << endl;
cout << "US Dollars: " << m << endl;
break;
}
}
system("PAUSE");
return EXIT_SUCCESS;
}

file setprecision c++ code

I had this code in C++ that is working just fine, first it ask the user for a
file name, and then saves some number in that file.
But what I am trying to do is to save numbers with two decimal places, e.g the
user types 2 and I want to save the number 2, but with two decimal places
2.00.
Any ideas of how to do that?
#include <iostream>
#include <fstream>
#include <iomanip>
using namespace std;
int main() {
double num;
double data;
string fileName = " ";
cout << "File name: " << endl;
getline(cin, fileName);
cout << "How many numbers do you want to insert? ";
cin >> num;
for (int i = 1; i <= num; i++) {
ofstream myfile;
myfile.open(fileName.c_str(), ios::app);
cout << "Num " << i << ": ";
cin >> data;
myfile << data << setprecision(3) << endl;
myfile.close();
}
return 0;
}
Ok, you need to use setprecision before the data is written.
I would also move the open and close of the file out of the loop (and the declaration of myfile, of course, as it's generally a fairly "heavy" operation to open and close a file inside a loop like this.
Here's a little demo that works:
#include <iostream>
#include <fstream>
#include <iomanip>
int main()
{
std::ofstream f("a.txt", std::ios::app);
double d = 3.1415926;
f << "Test 1 " << std::setprecision(5) << d << std::endl;
f << "Test 2 " << d << std::endl;
f << std::setprecision(7);
f << "Test 3 " << d << std::endl;
f.precision(3);
f << "Test 3 " << d << std::endl;
f.close();
}
Note however that if your number is for example 3.0, then you also need std::fixed. E.g. if we do this:
f << "Test 1 " << std::fixed << std::setprecision(5) << d << std::endl;
it will show 3.00000