Validate characters are less than specified letter in alphabet c++ - c++

I am making a function that validates a user input is a grid reference, between A0 and J9 (a 10 x 10 grid).
I can validate the integer part fine, but am wondering how to validate the alphabetical part, without saying for example:
if(Column == 'A' || Column == 'a' || Column == 'B' ....)
In a similar fashion to saying if int Row < 10.
Also, is there a way to convert to a single character, such as stoi for string to integer?
Here is my functions code, thank you.
void InputLocation(){
bool still_prompt = true;
while (still_prompt)
{
std::string answer;
std::cout << "Enter a grid location from A0 to J9" << std::endl;
std::getline(std::cin, answer);
std::string Column = answer.substr(0, 1);
std::string Row = answer.substr(1, 1);
if (answer.length() > 2 || answer.length() < 2){
std::cerr << "Location input must be of length 2 characters.\n";
continue;
}
else{ // If input has length 2, then get to this stage
try{
int intRow = std::stoi(Row);
if (intRow < 0 || intRow > 9){
std::cerr << "Row number must be between 0 and 9. \n";
continue;
}
}
catch (...){
std::cerr << "Second character of location input must be integer. \n";
continue;
}
}still_prompt = false;
}
}

Individual characters can be treated as numbers, so this is pretty simple to do! For example:
bool test(char character) {
return 'a' <= character && character <= 'j';
}
This function tests if a character is between 'a' and 'j'. This works because under the hood, 'a' and 'j' are just numbers. You can even see what numbers they are just by printing out the value:
int a_value = 'a'; // chars can be implictly converted to int
int j_value = 'j';
std::cout << "value of 'a'": << a_value << '\n';
std::cout << "value of j'j": << j_value << '\n';
Putting it all together. We can check if something is in the correct range just by doing a comparison. The following function will check if a character is within the range a through j.
bool testInRange(char c) {
return ('a' <= c && c <= 'j') || ('A' <= c && c <= 'J');
}
We can also write a function to convert it into an index on the grid:
int charToGridIndex(char c) {
if('A' <= c && c <= 'J')
{
return c - 'A';
}
else if('a' <= c && c <= 'j')
{
return c - 'a';
}
else
{
// Return -1 to indicate an invalid character
return -1;
}
}
Here,
charToGridIndex('a') == 0
charToGridIndex('b') == 1
charToGridIndex('c') == 2
charToGridIndex('d') == 3
charToGridIndex('e') == 4
charToGridIndex('f') == 5
charToGridIndex('g') == 6
charToGridIndex('h') == 7
charToGridIndex('i') == 8
charToGridIndex('j') == 9

Related

How to cyclically increment and decrement 26 latin characters in a loop

I want to increment or decrement characters, but have them cycle back to a when going beyond z and to z when going before a.
For example incrementing 'w' by 2 gives 'y' and decrementing 'w' by 2 gives 'u'.
Another example decrementing 'w' by 28 gives 'u' and decrementing 'a' by 256 gives 'e'.
I've figure out how to increment: char(int(A[i]+B-97)%26 +97) where B is the shift amount and A[i] is current character.
Don't overcomplicate. Use modulo to keep the increment or decrement amount in a range of 26 characters, then simply do a range check:
char cyclicIncrementDecrement(char ch, int amount)
{
int newValue = int(ch) + (amount % 26);
if (newValue < 'a') newValue += 26;
if (newValue > 'z') newValue -= 26;
return char(newValue);
}
This method of course assumes ch already is in range of 'a' to 'z'. If not, you need to handle that (put it in range or throw an exception or whatever is appropriate for your application).
Running this:
int main()
{
std::cout << cyclicIncrementDecrement('w', -2) << std::endl;
std::cout << cyclicIncrementDecrement('w', 2) << std::endl;
std::cout << cyclicIncrementDecrement('w', -28) << std::endl;
std::cout << cyclicIncrementDecrement('a', -256) << std::endl;
std::cout << cyclicIncrementDecrement('z', -256) << std::endl;
std::cout << cyclicIncrementDecrement('z', -51) << std::endl;
std::cout << cyclicIncrementDecrement('z', -52) << std::endl;
}
gives:
u
y
u
e
d
a
z
Using modular arithmetic, calculate your answer as modulo 26 and then add 'a' (ASCII 97) to your result.
char cyclic_increment(char ch, int n) {
int tmp = ((ch - 97) + n) % 26;
if (tmp < 0 )
tmp += 26;
return (char)(tmp + 97);
}
Alternatively, you could write the above (without an if) as:
char cyclic_increment(char ch, int n) {
return (((ch - 'a') + n) % 26 + 26) % 26 + 'a';
}
This handles both positive and negative offsets:
unsigned char az_cyclic(int in_ch)
{
constexpr int mod = 26; // There are 26 letters in the English alphabet
int offset = (in_ch - 'a') % mod; // (ASCII To zero-based offset) Mod_26 remainder
if (offset < 0) // If negative offset,
offset += mod; // normalize to positive. For example: -1 to 25
return 'a' + offset; // Normalize to ASCII
}
Use-cases:
int main()
{
unsigned char out_ch = '\0';
out_ch = az_cyclic('a' - 1); // 'z'
out_ch = az_cyclic('a' - 1 - 26); // 'z'
out_ch = az_cyclic('a' - 2); // 'y'
out_ch = az_cyclic('a' + 4); // 'e'
out_ch = az_cyclic('a' + 4 + 26); // 'e'
out_ch = az_cyclic('a' + 2); // 'c'
return 0;
}

Recursive path finding until result of division is 1

I am trying to solve an exercise in recursion that goes like this.
Say you have a matrix of nxm with integers like this(just an example):
1 1 1 5 2
2 3 5 2 1
3 1 1 1 5
1 1 5 1 1
I want to find a path (starting from anywhere) that, given a number n, every step n changes by n/(number_at_that_position) and the path stops when n = 1.
I am not looking for all paths, I am just looking for a path.
So if you use symbols to map the path, you would end up with a matrix
> > V - *
- - V > ^
- - V ^ -
- - > ^ -
Where '>' means a step right, '<' means a step left, '^' is a step up and 'V 'is a step down. Once n becomes 1, we insert '*' to say the path ended.
Most important: The path has to be continuous and you cannot visit a place you have visited before.
Even more important: The function that finds the path MUST be recursive.
If no path is found, the code exits with a message saying that no path was found.
Up to now I've come up with the following code for the path finding. I've used ideas from different places, but one of them is this one Recursively finding a path through a maze c++
bool path_print(vector<vector<int> > &P, size_t line, size_t col, vector<vector<char> > &A, int n) {
if (line < 0 || line > P.size() || col < 0 || col > P[0].size()) {
return false;
}
if (A[line][col] != '-') {
return false;
}
if (n == 1) {
A[line][col] = '*';
return false;
}
printf("n = %d, line = %zu, col = %zu\n", n, line, col);
n = n/P[line][col];
if (path_print(P, line, col+1, A, n) == true){
A[line][col] = '>';
return true;
} else if (path_print(P, line-1, col, A, n) == true) {
A[line][col] = '^';
return true;
} else if (path_print(P, line+1, col, A, n) == true){
A[line][col] = 'V';
return true;
} else if (path_print(P, line, col-1, A, n) == true){
A[line][col] = '<';
return true;
}
return true;
}
P is the vector containing the values
A is the char vector that stores the path
n is the actual number you are probing
I've been working on this for a while and I am stuck. This code does not work properly. Any suggestions or help would be greatly appreciated.
Thank you in advance
In your code :
if (line < 0 || line > P.size() || col < 0 || col > P[0].size())
is wrong because :
that allows to use the indexes P.size() and P[0].size(), in the original code of the link the comparisons are made with size - 1
line is a size_t so to do line < 0 has no sense, same for col
can be :
bool path_print(vector<vector<int> > &P, int line, int col, vector<vector<char> > &A, int n) {
if (line < 0 || line >= (int) P.size() || col < 0 || col >= (int) P[0].size())
or to check col and line before to do + 1 or -1 on them in a recursive call to avoid any problem including overflow.
But this is not enough to solve your problem, because your other changes from the code of the link are wrong :
you modify A cell after the recursive calls rather than before
you do not reset A cell to '-' after
when you find the exit (in your case n is 1) you return false rather than true, so you continue to search, and you check the value of n too late after an other move
at the end of the function you return true rather than false
Note that is is useless to continue to search while n is 0 after the division
To write if (f() == true) is redundant, if (f()) is enough
A solution modifying your code is :
#include <iostream>
#include <vector>
using namespace std;
bool searchPath(const vector<vector<int> > & P,
size_t line, size_t col,
vector<vector<char> > &A,
int n) {
if (A[line][col] != '-') {
return false;
}
n = n/P[line][col];
if (n == 1) {
A[line][col] = '*';
return true;
}
if (n == 0)
return false;
A[line][col] = '>';
if ((col != (P[0].size() - 1)) && searchPath(P, line, col+1, A, n)) {
return true;
}
A[line][col] = '^';
if ((line != 0) && searchPath(P, line-1, col, A, n)) {
return true;
}
A[line][col] = 'V';
if ((line != (P.size() - 1)) && searchPath(P, line+1, col, A, n)){
return true;
}
A[line][col] = '<';
if ((col != 0) && searchPath(P, line, col-1, A, n)){
return true;
}
A[line][col] = '-';
return false;
}
int main(int argc, char ** argv)
{
vector<vector<int> > P;
vector<vector<char> > A;
// fill vectors
int lines, columns;
cout << "number of lines and columns : ";
if (!((cin >> lines) && (cin >> columns) && (lines > 0) && (columns > 0))) {
cout << "invalid sizes" << endl;
return -1;
}
P.resize(lines);
A.resize(lines);
cout << "enter maze" << endl;
for (int i = 0; i != lines; ++i) {
P[i].resize(columns);
A[i].resize(columns);
for (int j = 0; j != columns; ++j) {
int v;
if (!(cin >> v) || (v < 1)) {
cout << "invalid input : " << v << endl;
return -1;
}
P[i][j] = v;
A[i][j] = '-';
}
}
int n;
cout << "enter n : ";
if (!(cin >> n) || (n <= 0)) {
cout << "invalid value of n" << endl;
return -1;
}
// search a way from all cells
for (size_t l = 0; l != (size_t) lines; ++l) {
for (size_t c = 0; c != (size_t) columns; ++c) {
if (searchPath(P, l, c, A, n)) {
// found
cout << "found from cell line " << l << " column " << c << endl;
for (l = 0; l != (size_t) lines; ++l) {
for (c = 0; c != (size_t) columns; ++c) {
cout << A[l][c] << ' ';
}
cout << endl;
}
return 0;
}
}
}
cout << "no solution" << endl;
return 0;
}
Examples :
number of lines and columns : 4 5
enter maze
1 1 1 5 2
2 3 5 2 1
3 1 1 1 5
1 1 5 1 1
enter n : 200
found from cell line 0 column 0
> > > > V
- * - - V
- ^ < < V
- - - ^ <
number of lines and columns : 4 5
enter maze
1 1 1 5 2
2 3 5 2 1
3 1 1 1 5
1 1 5 1 1
enter n : 999999
no solution

prefix notation c++, segmentation fault (stack and queue)

I am trying to figure out why I get segmentation fault, and my guess is that it is in my recursive function, which simplifies a prefix notation operation.
For example:
"m + 4 4" Returns: "+ m 8"
During testing I get a segmentation fault signal:
Exited with signal 11 (SIGSEGV)
I believe though that the problem lies in my recusive function "Operate"
string Operate(stack<string> &S, queue<string> &Q)
{
S.push(Q.front());
Q.pop();
std::string::size_type sz;
string result = "";
if (IsOperator(S.top()) == true)
{
S.push(Operate(S, Q));
}
if (Q.empty() == false)
{
S.push(Q.front());
Q.pop();
if (IsOperator(S.top()) == true)
{
S.push(Operate(S, Q));
}
if (S.size() < 3)
return "wrong input";
string arg1 = S.top();
S.pop();
string arg2 = S.top();
S.pop();
string oper = S.top();
S.pop();
if (StringIsDigit(arg1) && StringIsDigit(arg2))
{
int a = stoi(arg1, &sz);
int b = stoi(arg2, &sz);
char o = oper.at(0);
int c = 0;
if (o == '+')
c = b + a;
else if (o == '-')
c = b - a;
else if (o == '*')
c = b * a;
else
return "e";
result = to_string(c);
}
else
result = oper + " " + arg2 + " " + arg1;
}
else
{
result = S.top();
S.pop();
}
return result;
}
or in the function StringIsDigit:
bool StringIsDigit(string arg)
{
bool result = true;
for (int i = 0; i < arg.size() && result == true; i++)
{
if ((arg.size() != 1) && (arg.at(0) == '-') && (arg.at(i + 1) != ' '))
i++;
else
result = isdigit(arg.at(i));
}
return result;
}
Link to the whole program code:
https://pastebin.com/04pfE55N
The answer was quite simple, my error: SEGFAULT was as many pointed out for me error in reading from memory, segmentation fault, wiki.
When did the segfault occur?
It was when my function StringIsDigit() tried to figure out if negative values over 2 characters was an integer. In the "if statement, when checking if the string was indeed an integer, say -100", I continued to read the string until I reached the end of the arg string, but with arg.at(i + 1). Leading to the code trying to access memory outside the string array.Thanks Struthersneil for finding this flaw!
Please look at my old StringIsDigit() to find out the of by one value error I made:
bool StringIsDigit(string arg)
{
bool result = true;
for (int i = 0; i < arg.size() && result == true; i++)
{
if ((arg.size() != 1) && (arg.at(0) == '-') && (arg.at(i + 1) != ' '))
i++;
else
result = isdigit(arg.at(i));
}
return result;
}
The solution
The solution I want to make sure that the string was an integer since my algorithm supports expressions, such as x+3. This means that I need to iterate through the string is call isdigit() on every character in the string array. Though '-' is not an integer, '-' is needed obviously to express a negative integer, so I made a flawed check as you can see in my old StringIsDigit(). Instead of using that conditional if statement, I checked if the first character '-' and the second is not a whitespace ' ', and then I just let the isdigit() function do the rest of the work.
bool StringIsDigit(string arg)
{
bool result = true;
//I only need to check if the first is a '-' char and
//the next char is not ' '.
for (int i = 0; i < arg.size() && result == true; i++)
{
if ((arg.size() != 1) && (arg.at(0) == '-') && (arg.at(1) != ' '))
i++;
else
result = isdigit(arg.at(i));
}
return result;
}

How to Find All TRUE Conditions and Concatenate Corresponding Variables into New Variable?

a = 4
b = 5
c = 7
if (a >= 4){
text1 = “a is high”;
}
if (b >= 8){
text2 = “b is high”;
}
if (c >= 6){
text3 = “c is high”;
}
In C or C++, how would I find which of these statements are true (a & c) and create a new variable that concatenates their accompanying variables containing text to produce a result like “a is high and c is high”? The next time the code executes it may find that only a is high, or whatever the case may be. How would I go about doing this?
Use a single variable and keep on appending as you get the required information.
string text1;
if (a >= 4)
text1.append("a is high");
if (b >= 8)
{
if(text1.length()!=0)
text1.append(" and ");
text1.append("b is high");
}
if (c <= 6)
{
if(text1.length()!=0)
text1.append(" and ");
text1.append("c is high");
}
The answer of Gaurav Sehgal is elegant. Here is another way of writing it-
C++
string text = "";
if (a >= 4)
text += "a is high";
if (b >= 8)
{
if(text.size() > 0)
text += " and ";
text += "b is high";
}
if (c <= 6)
{
if(text.size() > 0)
text += " and ";
text += "c is high";
}
C
char text[buf_size] = {'\0'};
if (a >= 4)
strcat(text, "a is high");
if (b >= 8)
{
if(strlen(text) > 0)
strcat(text, " and ");
strcat(text, "b is high");
}
if (c <= 6)
{
if(strlen(text) > 0)
strcat(text, " and ");
strcat(text, "c is high");
}
create a temporary variable as result.
a = 4
b = 5
c = 7
result="";
if (a >= 4){
result += “a is high”;
}
if (b >= 8){
if(result==""){
result += “b is high”;
}else{
result += “and b is high”;
}
}
if (c <= 6){
if(result==""){
result += “c is high”;
}else{
result += “and c is high”;
}
}
text1=result
Using numeric comparison operators as well as logical AND ("&&"), the following C code finds all true conditions while obviating the need for a new variable as it efficiently uses text1, text2 and text3. Note, the result avoids any duplicate output:
#include <stdio.h>
#include <string.h>
int main(void) {
int a = 4;
int b = 5;
int c = 7;
char text1[] = "a is high";
char text2[] = "b is high";
char text3[] = "c is high";
if ( a >= 4 && c < 6){
puts(text1);
}
if (b >= 8){
puts(text2);
}
if (c >= 6 && a < 4) {
puts(text3);
}
if( ( a >= 4 ) && ( c >= 6 ) ) {
strcat(text1," and ");
strcat(text1,text3);
puts(text1);
}
return 0;
}
See demo

C++ Multiple Logical Operator

I'm rather new to C/C++. I have a segment of my application which doesn't seem to work as I'd want but I cannot understand why.
What I'm looking to do is when the 4 key is in the status of down, I'd like it to carry out the 'idle' function. I'd like the idle function to have 2 outcomes.
If the Up OR Down OR Left OR Right OR LMouse AND RButton then carry out the 'movement rotation operation' code else just carry out the standard idle function.
However within my code, it'll loop this while it's down but the moving() will only ever return 0
I've been messing with it for some time and trying to look on google for answers but I cannot understand why.
Here's my segment of code:
int moving()
{
int u = GetAsyncKeyState(VK_UP);
int d = GetAsyncKeyState(VK_DOWN);
int l = GetAsyncKeyState(VK_LEFT);
int r = GetAsyncKeyState(VK_RIGHT);
int mr = GetAsyncKeyState(VK_RBUTTON);
int ml = GetAsyncKeyState(VK_LBUTTON);
if(u == 1 || d == 1 || l == 1 || r == 1 || mr == 1 && ml == 1)
{
return 1;
}
}
void idle()
{
cout << "moving = " << moving() << endl;
if(moving() == 1)
{
cout << "Movement rotation operating." << endl;
}
else
{
cout << "This is the idle statement" << endl;
}
}
int main()
{
while(1)
{
if(GetAsyncKeyState('4'))
{
cout << "4 Pressed" << endl;
idle();
}
}
}
Thank you in advance.
Your logic to determine the button combination needs an extra set of parentheses.
if(u == 1 || d == 1 || l == 1 || r == 1 || (mr == 1 && ml == 1))
Also, 1 will evaluate to true so you can say
if(u || d || l || r || (mr && ml))
You could also make the function return a bool since that is really what you're after.
bool moving()
{
// ...
// code for getting button states
// ...
return (u || d || l || r || (mr && ml))
}