I am writing a C++ program. I have an array of char array trans[20][100]. Actually each string of trans is a transition of a grammar(Programming language translators). I want to check for each string in trans whether there is a Non-terminal after a '.' i.e. i want to check if in the strings there is a '.' followed by any capital letter. Can anyone please tell me how to do it??
-Thanks in advance
You can use any RegExp library (e.g. this one). The test regular expression is /\.[A-Z]/.
Or for ASCII string you can use:
int strHasDotCap(const char *s)
{
while (*s) {
if (*s++ == '.') {
if (*s >= 'A' && *s <= 'Z') return 1;
}
}
return 0;
}
You can use the functions in ctype.h isAlpha(), isUpper() etc. if the characters are ASCII type.
If you operate on ASCII char, then you could test if the int value of the char is between 65 and 90. See the ASCII table.
Related
Problem Solved: StringVariable[position] (in this case Word[e]) outputs a value that is defined as a char variable type rather than the string variable type I had expected it to. Thank you all for your help!
When I run my Hangman game I get the following error:
Error 2 error C2678: binary '!=' : no operator found which takes a left-hand operand of type 'std::string' (or there is no acceptable conversion)
Error 1 error C2678: binary '==' : no operator found which takes a left-hand operand of type 'std::string' (or there is no acceptable conversion)
4 IntelliSense: no operator "!=" matches these operands
3 IntelliSense: no operator "==" matches these operands
I commented in the code where this error points to and copied in the functions related to the problem. The functions were then run in the main() function to simplify the code.
This section of the code is meant to check if the guess is equal to the letter in the word. Let me know if I need to provide further explanation.
Related Code:
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
//Functions
void GrabWord();
void DiscoverLet();
void guess();
//Variables
int NumL, Fl, F, count[10];
string G, Word;
//Grab Word from .txt and define NumL
void GrabWord()
{
//Grab Random Line from .txt
//Random Line >> Larray
Word = "short";
NumL = Word.size();
}
//Checks if Guess matches any letters
void DiscoverLet()
{
for(int e = 0; e < NumL; e++)
{
//Error Points to the following two comparisons
if(G == Word[e])
{
count[e] = 1;
}
else if(G != Word[e])
{
Fl++;
}
else
{
cout << "Error: DiscoverLet(), G to Word[]\n";
}
}
if(Fl == NumL)
{
F = F + 1;
}
Fl = 0;
}
The proper string comparison that you are looking for is called find:
if(Word.find(G) > std::string::npos)
{
count[e] = 1;
}
else
{
Fl++;
}
The reason why your comparison does not work was that you Word[e] was grabbing a character of the string and it was being compared to a string variable.
Judging by your code it looks like you wanted to count the number of times the letter appears in the string. If you wanted to count the number of times the letter appears in the string then you can use the find function like this:
int count = 0;
int foundIdx = 0;
for(int i = 0; i < NumL; i++)
{
foundIdx = Word.find(G, foundIdx+1);
if (foundIdx == std::string::npos)
{
break;
}
count++;
}
if(G == Word[e])
...
else if(G != Word[e])
In these comparisons, G is a string and Word[e] is a character in a string. There is no operator to perform the respective comparisons.
G is a variable of type string. Word is also a type of string. So as you might already know that strings are nothing but array of chars. So Word[e] points to a character of the Word string. So
if(G == Word[e])
Here, you are comparing a string with a character. But C++ has no idea how to do that! I mean C++ does not know how to evaluate the expression. Because the operator == for comparing a string and a char is not overloaded inside string class. Same goes for the line
if(G != Word[e])
If you're trying to find out if Word[e] character appears in the G string, you should run another loop searching character by character of the string G. Or you can use find function.
The reason of the error is because you are comparing string to a character. You can use ==, !=, >, <, etc on character, but certainly not strings. And also, the string G appears to be empty. Hope this helps and correct me if I'm wrong! Happy coding!
G is string type but Word[e] is char type. You should convert Word[e] to String to compare with G by std::to_string or use method string::find with G to find content Word[e] in G.
The comparison won't work that way. You need to understand what is the difference between a char and a std::string. A variable of type char represent a single letter. A char cannot be multiple character, and cannot be empty. Is strictly one, single letter. Nothing less, nothing more.
A std::string can be seen as a managed array of char. It's size can be 0 to very big. This type expose the array access operator, the [n], and that operator returns a character from the string at position n. It's return type is char.
Since G is supposed to be an input letter from the user, I'd suggest you to declare G as a char. In fact, it will solve your problem.
The reason for that a string cannot be compared to a single character. A string is designed to be comparable to another whole string. And a character can be compared with another integral, or put it simpler, another char. So if you change the type of G to char, your comparison will work as expected.
Well currently I am re creating my own version of enigma as a little project but if you understand how the enigma machine works it has rotors which connect a character to a completely different character for example A might be connected to F or U may be connected to C and this is done three times. Currently I am getting the char for the rotor by using this function:
char getRotorOne(char i) {
if(i == 'a') {
return 'g';
}if(i == 'b') {
return 'A';
}if(i == 'c') {
return 'o';
}
The main problem with this is it takes a long time to write and it seems inefficient and I think there must be a better way. The other problem with this is on the original enigma machine there were only the 26 letters of the alphabet on this there are the 94 tapeable characters of ascii (32-126) is there any other simpler way that this can be done? If you think this question is unclear or you don't understand please tell me instead of just flagging my post, then you can help me improve my question.
Use tables! Conveniently, C string literals are arrays of characters. So you can do this:
// abc
const char* lower_mapping = "gAo";
// ABC
const char* upper_mapping = "xyz";
char getRotorOne(char i) {
if (i >= 'a' && i <= 'z') return lower_mapping[i - 'a'];
if (i >= 'A' && i <= 'Z') return upper_mapping[i - 'A'];
assert(false && "Unknown character cannot be mapped!");
}
Since chars are really just small integers, and ASCII guarantees contiguous ranges for a-z and A-Z (and 0-9) you can subtract from a given character the first one in its range (so, 'a' or 'A') to get an index into that range. That index can then be used to look up the corresponding character via a table, which in this case is just a simple hardcoded string literal.
This is an improvement on Cameron's answer. You should use a simple char array for each rotor, but as you said you want to process ASCII characters in the range 32-126, you should build each mapping as an array of 95 characters:
char rotor1[95] ="aXc;-0..."; // the 95 non control ascii characters in arbitrary order
Then you write your rotor function that way:
char getRotorOne(char i) {
if ((i < 32) || (i > 126)) return i; // do not change non processed characters
return rotor1[i - 32]; // i - 32 is in range 0 - 94: rotor1[i - 32] is defined
}
This question already has answers here:
How to strip all non alphanumeric characters from a string in c++?
(12 answers)
Closed 6 years ago.
I'm trying to remove all non alphabet characters from an inputed string in c++ and don't know how to. I know it probably involves ascii numbers because that's what we're learning about. I can't figure out how to remove them. We only learned up to loops and haven't started arrays yet. Not sure what to do.
If the string is Hello 1234 World&*
It would print HelloWorld
If you use std::string and STL, you can:
string s("Hello 1234 World&*");
s.erase(remove_if(s.begin(), s.end(), [](char c) { return !isalpha(c); } ), s.end());
http://ideone.com/OIsJmb
Note: If you want to be able to handle strings holding text in just about any language except English, or where programs use a locale other than the default, you can use isalpha(std::locale).
PS: If you use a c-style string such as char *, you can convert it to std::string by its constructor, and convert back by its member function c_str().
If you're working with C-style strings (e.g. char* str = "foobar") then you can't "remove" characters from a string trivially (as a string is just a sequence of characters stored sequentially in memory - removing a character means copying bytes forward to fill the empty space used by the deleted character.
You'd have to allocate space for a new string and copy characters into it as-needed. The problem is, you have to allocate memory before you fill it, so you'd over-allocate memory unless you do an initial pass to get a count of the number of characters remaining in the string.
Like so:
void BlatentlyObviousHomeworkExercise() {
char* str = "someString";
size_t strLength = ... // how `strLength` is set depends on how `str` gets its value, if it's a literal then using the `sizeof` operator is fine, otherwise use `strlen` (assuming it's a null-terminated string).
size_t finalLength = 0;
for(size_t i = 0; i < strLength; i++ ) {
char c = str[i]; // get the ith element of the `str` array.
if( IsAlphabetical(c) ) finalLength++;
}
char* filteredString = new char[ finalLength + 1 ]; // note I use `new[]` instead of `malloc` as this is C++, not C. Use the right idioms :) The +1 is for the null-terminator.
size_t filteredStringI = 0;
for(size_t i = 0; i < strLength; i++ ) {
char c = str[i];
if( IsAlphabetical(c) ) filteredString[ filteredStringI++ ] = c;
}
filteredString[ filteredStringI ] = '\0'; // set the null terminator
}
bool IsAlphabet(char c) { // `IsAlphabet` rather than `IsNonAlphabet` to avoid negatives in function names/behaviors for simplicity
return (c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z');
}
I do not want to spoil the solution so I will not type out the code, only describe the solution. For your problem think of iterating through your string. Start with that. Then you need to decide if the currently selected character is part of the alphabet or not. You can do this numerous different ways. Checking ASCII values? Comparing against a string of the alphabet? Once you decide if it is a letter, then you need to rebuild the new string with that letter plus the valid letters before and after that you found or will find. Finally you need to display your new string.
If you look at an ascii table, you can see that A-Z is between 65-90 and a-z is between 97-122.
So, assuming that you only need to remove those characters (not accentuated), and not other characters from other languages for example, not represented in ascii, all you would need to do is loop the string, verify if each char is in these values and remove it.
I thought I would try and write some encryption program that converts input to numbers in a file.
I made a table, giving each letter its own number. The code itself went a little like this for each letter:
if (Letter = "P")
{
FILEO.open("Encrypted.txt", ios::app);
FILEO << " 259";
FILEO.close();
}
It came up with "cannot convert from 'const char [2]' to 'char'"
Can anyone suggest how I would go about actually getting a number from a letter?
If Letter is a char, use a char literal:
if (Letter == 'P')
...
Your conditional checking is wrong. It should be ==, not =. A single = means assignment whereas a == means conditional checking.
I am assuming Letter is a character array. In that case, you can use strcmp to compare it with P.
if(strcmp(Letter, "P") == 0)
{
// rest of the code
}
Take a look at the strcmp function reference here, if necessary.
If Letter is simply a char, then you need to compare it with P like this -
if(Letter == 'P')
{
// rest of the code
}
A single quote around a character makes it a character literal, which then can be compared against another character using ==.
You can not compare C++ char to C++ string! You should use single quote for chars, not double quotes. Also, the C++ equals operator is not =, it is ==. the single = is the assignment operator.
You should write the condition like this :
if (Letter == 'P')
{
FILEO.open("Encrypted.txt", ios::app);
FILEO << " 259";
FILEO.close();
}
(Letter = "P")
This is an assignment, not comparison.
You probably meant (Letter == "P") which would also be wrong, you need strcmp.
you need to use strcmp to compare....as = is an assignment operator....
I would recommend that when you give us an error message as you did, you give us the full message - including line numbers so that we know where the error occurred (or tell us what line it occurred at). Paying attention to those line numbers can greatly help finding the true problem.
Given the error message I'm assuming Letter is of type char - you need to understand the difference between literal strings (enclosed in double quotes) and literal characters (enclosed in single quotes).
As Luchian also mentioned, you have an assignment rather than an equality test - unlike Visual Basic, if that is where you're coming from, the two have different symbols.
That should thus be:
if (Letter == 'P')
I have an array of characters populated by cin, but im trying to find a way to check each character individually to make sure its only one of a set number of characters (a-z,A-Z,0-9,[space]).
The easiest way I thought this could be done is to check if the code of the character fell within a certain range. But not sure how to get it.
Alternatively if anyone knows any other ways of doing it, that would be great.
The easiest way is to use isalpha(), isdigit() or isalnum():
char ch = ... // The character
// Original solution
if (isalpha(ch) || isdigit(ch)){
}
// Better solution by fefe (see comments)
if (isalnum(ch)){
}
These are defined in ctype.h: http://www.cplusplus.com/reference/clibrary/cctype/
Otherwise you can also use comparisons:
if ('a' <= ch && ch <= 'z' ||
'A' <= ch && ch <= 'Z' ||
'0' <= ch && ch <= '9'
){
}
This latter approach using comparisons will generalize to arbitrary ranges.
You can easily access a specific character code by using the character you want in single quotes, for example, 'A'. Therefore, if you wanted to check if a character is in a certain range:
char c = //some character
if ( c >= 'A' && c <= 'Z' ) {
//do something
}
should work as you would expect. Additionally, if you are concerned about alpha-numerics specifically, there is a helper function called isalnum, defined in <ctype.h> that checks if a character is an alphanumeric character.
You can determine if the number falls within the range you are looking for within an ASCII table: http://www.asciitable.com/index/asciifull.gif. So >= 48 && < 123.