GPS COORDS READING - c++

I am trying to make a program that to which a used will enter this "$GPGGA,004536.289,9876.5375,N,06540.9373,E,1,04,3.2,2550.2,M,,,,0000*0E"
and the program will show only what's before before "N" and "E" like in this case it will be "9876.5375" and "06540.9373"
At first I thought I could make it read the entire thing as different variables chain like:
cin>>a>>b>>c>>d>>e>>f>>g>>h>>l; and then show only the variables I want but it works so weird and the variables it shows have nothing to do with my entry
This is the program https://prnt.sc/oS5aElQoUC65
This is what it shows after I enter the gps code https://prnt.sc/jRyLhD_ik2G2

Your data types are NOT int. They are actually float or double or char/string.
Fix the data types and enter them WITHOUT ",". Just a space between them or [enter]
UPDATE
change the line with the declarations (line 15) for this one:
std::string a, b, c, d, e, f, g, h, l;
Run it and it will be easier for your to understand your code.

Related

Regarding char arrays, I'm trying to assign each character in my array to another value

Thanks for taking the time to look at my post. I'm relatively new to programming and have a question regarding character array(s)
The idea is a very basic encrypt / decrypt
Say I have an array called "key"
char key​ [26​]={​'B'​,'A'​,'D'​,'C'​,'F'​,'E'​,'H'​,'G'​,'J'​,'I'​,'L'​,'K'​,'N'​,'M'​,'P'​,'O'​,'R'​,'Q'​,'T'​,'S'​,'V'​,'U'​,'X'​,'W'​,'Z'​,'Y'​};
Once I pass the key value into a method that is supposed to alter the value of each individual ASCII value to:
A = B, B = A, D = C, C = D, etc.
Can you point me in the right direction as far as the approach I would need to take to return the decrypted value.
Thanks~
Here's a hint to get you started. Start with a simple C function that takes an array of characters and it's length:
void encode_characters(char* key, int length)
{
// your code goes here
}
Your code within that function will do the swapping of items in the array passed in. Then you can invoke it from within your program as follows:
char key​[26​] = {​'B'​,'A'​,'D'​,'C'​,'F'​,'E'​,'H'​,'G'​,'J'​,'I'​,'L'​,'K'​,'N'​,'M'​,'P'​,'O'​,'R'​,'Q'​,'T'​,'S'​,'V'​,'U'​,'X'​,'W'​,'Z'​,'Y'​};
encode_characters(key, 26);

Is extracting formatted input from std::cin with a single line of code possible?

Say I have a function compute_number(float k); and in my program, I need to call this function once with some user input as the argument. The intuitive way to achieve formatted input, would be:
int main()
{
...
float input_numbr;
std::cin >> input_numbr;
compute_number(input_numbr);
...
}
The problem with this, though, is that I've declared and used an extra variable float input_numbr which I'll never use again. I think that's a waste.
So my question is if there's any way to reduce these three lines into one. There must be some way to circumvent the need of creating an additional variable to get one-time formatted keyboard input from an input stream. I'm thinking of something like:
compute_number(cin.get());
The problem with that, however, is that cin.get() does not format the input; it simply returns the ASCII value of whichever character happens to be next in the stream.
So is there a way to call compute_number(cin.next_formatted_input()) like so? Or must one create an additional variable for temporarily holding the formatted cin value.
The problem with this, though, is that I've declared and used an extra variable float input_numbr which I'll never use again. I think that's a waste.
Well, I disagree (advocating for code readability), but here you go:
template<typename T>
T getinput(std::istream& is) {
T result;
is >> result;
return result;
}
should do what you want. You can just write
compute_number(getinput<float>(std::cin));
then. Though a variable is still involved (and needed).

Reading from a file into a List using C++

I'm a little new to using file input/output so bear with me.
I've got a function called RunList(filename), that takes the name of the file as input and returns nothing. The file will have the format of having one line that is useless and I plan on using ignore() on and then the next line which is important has the format
"i 1 2 3 4 5 ...."
where the numbers go on for a very long way, about 250000 or so.
So what I want to do is to open this file, ignore the first line, and then for each number in the file I want to use the function void insert(x, p) which is a function I have defined to insert x after the current iterator position p. The end result is that I want to have my list contain all of the numbers in the file after the "i" and be in the same order. I have also defined the functions ListItr find(x) and ListItr first() which will return the iterator to the position that views x and to the first potion respectively.
Could anyone provide me with a means of doing this? I was thinking of using a for() loop and taking in each word at a time from the file and using my function to insert each element, but I'm a little lost as to how to do this, as I said I'm very new to using file input/output.
So, my RunList function currently looks something like this, although obviously its not finished nor does it really work, hence me needing some help on it.
void Runlist(filename){
ifstream in;
in.open(filename);
in.ignore(1000, '\n'); //this is me trying to ignore the first line
for (int i, i < 250000, i++){
int number;
in >> number
void insert(number, i)
}
}
But the plan was, I select the file, ignore the first line, then set up a for loop where i can use my void insert(number, i) to insert each number, but then i don't really understand how to read in each word at a time, or to preserve the order because if I just kept using the function on each number over and over then the list would have the numbers in the reverse order I believe.
There are several issues in your code:
You do not specify void for the return type of the function.
Instead of ignore, you could just drop the first line when reading by using getline once.
Your for loop usage is also pretty invalid: commas instead of semi-colons
No initialization of i, and so on.
insert is not shown, but you could probably use append anyway since that is what you seem to be doing.
i is not an "iterator" either, so probably you meant index.
You are having a function declaration in the middle of the function rather than calling it.
This pseudo code should get you going about understanding the input file stream class and its usage for this in C++:
void Runlist(filename)
{
ifstream in(filename, ifstream::in);
in.getline(0, 1024);
int number;
while (in >> number)
append(number);
in.close();
}
Disclaimer: this pseudo code is missing proper error checking, and so on.

how to declare variable before you know what data type it is?

I'm new to c++ coming from a python background.
If I want input from a user and then I want to check what data type the input is (e.g. integer or float), how is it possible for me to declare the variable that I want to assign the user's input to?
Short answer: You can't.
Long answer: You can't. C++ is a statically typed language, meaning that you have to define the type at compile time. Python is dynamically typed, so the type of an object can change from line to line.
If you want to get some input from the user though, you can just use a string though.
For example, if you want to get integer input from the user:
int n;
std::cin >> n;
Float input:
float x;
std::cin >> x;
And so forth. Do note in those two cases, if the user inputs something other than an integer or float, you'll have to check the flags of std::cin to see if there was an error.
But you need to tell the user "Input integer now" or "Input float now". You can't just accept some arbitrary type. Instead, design your code so you have alternative code paths for either integer or floating point input. Or force one or the other, and print an error when they give the wrong type of input.
Don't write your code like you're in Python. Idiomatic Python code is not idiomatic C++ code, and the way you accomplish things will not look the same.
In C++ the way to get arbitrary input would look like:
std::string input;
std::cin >> input;
if (IsInteger(input))
{
// do stuff with integer
}
else if (IsFloat(input))
{
// do stuff with float
}
else
{
std::cout << "Bad Input!" << std::endl;
}
Edit: As MSalters pointed out in a comment, You can actually use boost::lexical_cast<T>(expr) to cast a string representation to some type T (Where T is usually something like int, float, double, etc). Do note, you'll probably still have to do some checking to see if expr is actually an integer, float, or otherwise.
When you get input from the user, it will arrive as a string. For example:
std::string inp;
std::cin >> inp;
Then, you take the contents of inp (which is whatever the user typed), and look inside it to see what characters it contains. At that point you could make decisions based on whether it contains (a) all digits, (b) digits and a decimal point, or (c) something else entirely.
Much better to collect a string from the user and then parse it.
This question is the place to look for an answer:
How to parse an int from a string
C++ is a statically typed language. All the variable types must be known at compilation time.
Python is dynamically typed language and on the contrary, c/c++ are statically typed languages. It is not possible to find the the type and declare at run time.

c++ isalnum endless loop

Greetings!
Lets cut the excessive intro this time and get straight to the point.
I have a problem in C++ using the isalnum method.
the code:
int playAgainst = 0;
do
{
cout << "Who do you want to play against?(1/2)\n";
cout << "1: Human player\n";
cout << "2: Computer player\n";
cin >> playAgainst
} while(!isalnum(playAgainst) && playAgainst != 0);
As seen in the code, I'm providing the user with a choice. Play against human or play against a computer.
What I want is, as long as the user enters anything else then an integer value(cin >> playAgainst) to repeat the question. However, If i enter a char, or string value, it keeps looping endlessly. I am not 100% sure, but it would be obvious, if the problem is, that the non int value is already saved as the value for playAgainst.. How can I check in this bit of code if the input value is int before saving it?
Or is the only possibility to save as a char/string and then check?
If the latter is the case, a new problem arises. isalnum only accepts int as parameter, atleast from what I know. How will I check if that string or char is an int?
Thank you for taking the time to read. And hopefully Ill be accepting a reply as answer soon ^^
Thanks everyone for the answers.
I have gotten what I wanted, and everything has been solved.
The reason I chose for the accepted answer, is well... because initially, it made my code work the way I want it to. I want to accept multiple answers though..
Make playAgainst a char and compare against '0', not 0. Right now, the user has to enter the ASCII (or whatever your character set is) code for the character '1' or '2'.
isalnum won't work on ints outside the valid range of char, except for EOF. (The fact that it takes an int argument is a leftover from C, which has different integer promotions rules than C++. to accomodate for EOF.)
Remove the isalnum() check. cin >> playAgainst will convert anything except a number to zero, which will be caught by the second check. Note that this is only an option because zero is not a valid input.
isalnum() is useful if you're interpreting the characters yourself, but in this case the stream has already done that for you.
This is how the compiler will implement isalnum:
int isalnum (int ch)
{
return (ch >= 'a' && ch <= 'z') ||
(ch >= 'A' && ch <= 'Z') ||
(ch >= '0' && ch <= '9');
}
So you might as well write that code snippet in your own code, and it will be equivalent with an inlined version of isalnum.
It's because you don't clear the buffer. When the input is invalid, you need to clear it from the buffer, and then you can move on to the next input, else you're trying to extract the same input every time (which fails, because it's the same bad input), and thus enter an infinite loop.
The problem is that you're inputing an int, and not a char. And if the
text in the input isn't an int, then the input fails. In which case,
playAgainst isn't modified, and the failure is memorized in std::cin
until you explicitly clear the error. And inputting from a stream in an
error state is a no-op. What you probably want to do is
Input a single character: if you don't want to skip spaces, using
`std::cin.get( ch )` or `ch = std::cin.get()`. (In the latter
case, `ch` should be an `int`, since it must also handle `EOF`.
On the other hand, you can use `::isalnum` on it directly, which
you can't do if `ch` is a `char`.
Fully check for valid input: not just `::isalnum`, but rather
whether the input is a legal selector in your list. Something
along the lines of:
ch != EOF && std::find( legalChars.begin(), legalChars.end(), (char)ch ) != legalChars.end()
In case of error, clear any remaining input, say with:
std::cin.ignore(INT_MAX, '\n');
In practice, you'll probably want to treat EOF differently from
an erroneous command. (If you don't clear the input after EOF, you
won't be able to read anything else. But presumably, if you got EOF,
it's because the user gave up, and doesn't want to try any more.)
Finally, it's probably preferrable to keep all of the information in
a common location, using a table of:
struct Command
{
char op;
char const* prompt;
void (* func)();
};
You then loop over a table of these to output the prompt, search it to
see if the character was legal, and finally, call the function on the
entry you found. Or define an abstract base class, a concrete class
deriving from it for each command, and use an std::map<char,
AbstractBase*> for the mapping, etc. Very C++, but perhaps a bit
overkill for such a simple case.
Why not use isdigit().