Why I cannot initialize string with "\x" - c++

Why I cannot initialize string with "\x"
string s = "\x"
It would be useful if I could later write:
int grade = 0;
while (cin >> grade)
if (grade < 60)
cout << "Your grade letter is F!";
else {
x = 50 - grade/10;
s = s + static_cast<string>(x);
cout << "Your grade letter is " << s << endl;
}
I prefer answer, that uses escape sequences computation for setting grade letter.

Because the syntax forbids it. The \x sequence in a string literal is a prefix that means "here comes the hexadecimal code for a character", but you're trying to omit the code part. That means it's not possible to parse the literal and figure out which character to put in the string.
Note that this is a compile-time thing, it has to be possible to compute the sequence of characters represented by a string literal, by just looking at the literal itself.

You misunderstand the way the escape sequences are processed. They are computed at compile-time, not at run time. On other words, when you write
"\x48"
it does not become a string of four characters at runtime; compiler converts it to a single-character string before the program is run.
You also misunderstand static_cast<...>: if x is not a std::string, static-casting it to string will result in an error; if it is a std::string, static-casting will have no effect.
You can create a single-character string at runtime and put a character code into its only character like this:
int grade = 83; // <<<=== 1..100
grade--;
int gradeLetter = g < 60 ? 'F' : ('A' + (100-grade)/10);
// At this point you can do the output:
cout << "Your grade is " << gradeLetter << endl;
// If you must have a string, do this:
string gradeStr(1,gradeLetter);
cout << "Your grade is " << gradeStr << endl;

Related

Trying to check entered text versus my own custom answers

here is what I attempted to throw together, unfortunately it's not doing what I want it to. What I want it to be doing is checking the entered text vs a few words that I consider correct. So, for example, if I want the only correct answers to be "thanks" or "please", how would I make the program check if the word the user entered is either "thanks" or "please"?
I have a feeling I can't just write B == 'funs etc.
help me out please:
#include <iostream>
using namespace std;
int main ()
{
string B;
for (;;)
{cout << "enter text here" << '\n' ;
cin >> B ;
if (B == 'fUNS'|| B == 'funs' || B == 'funzies')
{
cout << "correct!!!!!!" << endl;
break;
}
else
{
cout << "sorry, please try again" << endl;
continue;
}
}
return 0;
}
Unlike some languages using ' or " to enclose a sequence of characters produces very different results.
A single quote defines a single character literal e.g:
char a = 'A';
You can use multiple characters to define the value of an integer (although this is non-standard):
int a = 'ABCD';
A double quote defines a string literal which is a sequence of characters in an array:
const char str[5] = "ABCD";
Note the literal has a hidden null character at the end which is why it has 5 elements rather than 4. String literals are comparable and assignable with std::string:
std::string test( "ABCD" );
std::cout << test == "ABCD";
test = "EFGH";
std::cout << test == "ABCD";
I have a feeling I can't just write B == 'funs etc.
Yes, you can, since B is a std::string, which has an operator== defined. You just need to use " (which is used to define string literals) instead of ' (which is used to define character literals), eg:
if (B == "fUNS" || B == "funs" || B == "funzies")

C++ Counting character occurrence from a text file regardless of case

In C++, I am trying to take text from a file and count the occurrences of characters, ignoring differences in case. So far, I can do this without ignoring case.
map<char, size_t> char_count;
char character;
while (myfile >> character)
++char_count[character]; // fetch and increment the counter for word
for (const auto &w : char_count) // for each element in the map
// print the results
cout << w.first << " occurs " << w.second
<< ((w.second > 1) ? " times" : " time") << endl;
My solution for this was going to be:
character = tolower(character)
but tolower() will not take a char, only an int. Any ideas? Am I approaching this the wrong way?
that's true, you can use tolower to convert a character to lowercase, i've modified your code, i hope it can help you :
while (myfile >> character)
++char_count[tolower(character)];
Your solution is applicable.
Just use tolower and convert the char to an int.

Iterating through characters of a string stored in a vector to replace characters C++

So we got an optional assignment in our C++ class. The assignment is basically this:
Write a program that holds a string of at least 8 words.
Do the following:
1. Replace the letters of first word with '?'
2. Turn the letters of the last word to uppercase
We did not yet study vectors in our class.
When I first read the assignment, storing the strings to a vector seemed like a good idea so I went with it.
To replace the characters with a '?' I used a for loop. I know that this would not work if I only had to change only certain characters or every other character to a '?'.
My issue is with converting chars of a string to uppercase.
My thought process was: for loop iterates through all chars in the last word, if the char is lowercase it gets turned to uppercase, if it is already uppercase it does not change.
I believe that my approach could work for this problem, I just maybe did not express myself correctly or I made a silly error somewhere. Could anyone assist me or push me in the right direction?
What other options are there to iterate through all chars of a string stored in a vector? Is there another approach that might work better for this? Thank you for your time.
#include <vector>
#include <cctype>
#include <string>
#include <iostream>
using namespace std;
vector<string>words;
//stores words to vector words
void storeWords()
{
cout << "Input 8 words: " << endl;
string s = " ";
for(int i=0; i<=7; i++)
{
cin >> s;
words.push_back(s);
}
}
//prints our words
void printWords()
{
cout << "\n Words stored in vector: " << endl;
for (const string s : words)
cout << s << endl;
}
//replaces chars of the first word with a '?' sign
void replace1(vector<string>&v)
{
cout << "\nReplaced characters of the first word " << words[0] << " with '?'" << endl;
for (char c : words[0])
cout << "?";
}
void replace2(vector<string>&v)
{
for (char c : words[7])
{
if(islower(c))
c = toupper(c);
}
cout << endl;
cout << words[7]<<endl;
}
int main()
{
storeWords();
printWords();
replace1(words);
replace2(words);
return 0;
}
c = toupper(c) will assign c the uppercase value. However, changing c will not change what's inside words[7]. You can get around this by referencing the char directly (char &c).
void replace2(vector<string>&v)
{
for (char &c : words[7]) {
c = toUpper(c);
}
cout << endl;
cout << words[7]<<endl;
}
Also note that your requirements are to hold a string of at least 8 words. So words[7] will probably end up looking like words[words.size() - 1].
This
for (char c : words[7])
Should be:
for (char& c : words[7])
The first version modifies a local variable, while the second changes the actual characters in words[7].
The little ampersand (&) makes c a reference to a certain character in words[7], allowing you to change c as you would words[7][some_i].
Also, I should add that your replace functions do not need that vector argument.
Ideone Example with that change

How to make C++ program that is supposed to add up ages and separate it into categories?

I'm supposed to make a program that counts the number of people in each age group:
0-16 (including 16) is infant
16-29 is young
29-55 is middle
55-75 is old
75+ is really old
The intervals are closed to the left and open to the right.
I wrote a program that compiles, but does not give me the correct values. I'm new at coding so can anyone point me in the right direction? Here is what I have:
#include <iostream>
using namespace std;
main()
{
int countinfant, countyoung, countmiddle, countold, countreallyold;
char age;
countinfant=0;
countyoung=0;
countmiddle=0;
countold=0;
countreallyold=0;
cout<< "Please Enter Ages. To end, enter *\n";
cin.get(age);
while (age>0 && age != '*')
{
if (age>=0 && age<=16) countinfant = countinfant + 1;
if (age>16 && age<=29) countyoung = countyoung + 1;
if (age>29 && age<=55) countmiddle = countmiddle + 1;
if (age>55 && age<=75) countold = countold + 1;
if (age>75 && age>=76) countreallyold = countreallyold + 1;
cin.get(age);
}
cout<< "\n The Number of Infant's Are: " << countinfant;
cout<< "\n The Number of Young's Are: " << countyoung;
cout<< "\n The Number of Middle's Are: " <<countmiddle;
cout<< "\n The Number of old's Are: " <<countold;
cout<< "\n The Number of Really Old's Are: " <<countreallyold;
cout<<endl;
return 0;
}
Actually your problem is very easy to figure out once I looked closer at the code.
The get function of input streams read a single character and not numbers. So if you enter the character 5 as input it will be read and stored in age as a character, and if the encoding used on your system is ASCII encoding (which is the most common these days) then the value for the character '5' is the integer 53.
You then proceed to use the character you have read as an integer, which as it is encoded will give you the wrong results.
To get the correct values you need to read an integer, however since you want to check for the asterisk to end the input you can't use normal integer input with the >> operator, which is why you used get I guess. The solution is to use strings and check the string for the asterisk, and if not an asterisk convert the string to an integer.
Something like
std::string input;
while (std::cin >> input && input != "*")
{
int age = std::stoi(input);
...
}
It does not work because you declared age as a char. The program reads the input as a char, so if you enter 0, the value in age will be the ASCII code of the character 0, which is 48 (0x30). You need to declare it as int age; and for the exit condition simply enter a negative value, e.g. -1, don't use the '*'.

why will strcpy only copy a limited number of elements:

C++ newbie here. Writing a simple program. Everything works,except when I attempt to extract firstname and surname and print these individually, the number of letters printed in surname will always be the same size as the number in firstname. So if the name is will jackson, the program will print firstname as: will and second name as: jack. How do I solve this?
here is the code
for( i = 0; i < 19; i++)
if(cAddress[i] == ' ' || cAddress[i] == '_' || cAddress[i] == '-' || cAddress[i] == '.')
break;
strncpy(cFirst, cAddress, i);
cFirst[i] = '\0';
cout << endl << "\n";
cout << "Your first name is " << cFirst << endl;
strcpy(cSur,cAddress + i + 1);
cSur[i] = '\0';
cout << endl;
cout << "Your surname is " << cSur << endl;
You are adding a \0 character at the (i+1)th position - this marks the end of string, so that's all it prints. Before that line, cSur probably contains the entire surname.
Most of your code looks a lot like C -- and doesn't even take full advantage of the C standard library. In C++, I'd write something more like:
int pos = Address.find_first_of(" _-.");
std::string FirstName(Address, 0, pos);
std::string SurName(Address, pos);
If, for whatever reason, you insist on using C style strings, you might consider starting with strpbrk to find the separator.
cSur[i] = '\0';
is incorrect. i is the length of the first name. cSur is already zero terminated by strcpy.
Having explained that, Jerry Coffin's answer is what I would recommend as good c++ code.