Change the value of a variable in C++? - c++

i hope you can help me.
The thing is that i don't know how to change the value of a variable, for example, i have a
"char" variable and then i wanna change it to "int" or "float"
This is the code
#include<iostream>
#include<cstdlib>
using namespace std;
main()
{
{
cout<<" El valor de las calificaciones es A=10,B=9,C=8,D=7,E=6,F=5,G=4,H=3,I=2,J=1 " <<endl;}
char calificaciones[4];
int resultado,A=10,B=9,C=8,D=7,E=6,F=5,G=4,H=3,I=2,J=1, i, promedio;
for(i=1;i<4;i++)
{
cout<<"Ingrese calificacion con letra "<<i;
cin>>calificaciones[i];
}
promedio=(calificaciones[1]+calificaciones[2]+calificaciones[3])/3;
cout<<"El promedio de sus tres calificaciones es "<<promedio<<endl;
system("pause");
}
The program is supposed to ask for the user to enter three scores and the scores are shown in letters as you can see, A=10, B=9, etc, and once the user enters three letters the program is going to divide them into three, but since the variable "calificaciones" was a string first, how do i make the operation i want to do this, or whats the command that i could use for the program to understand that the user entered three letters and an operation will be made with them?
Hope you can help me and thanks.

If your original question is, how to change datatype, sorry that is not possible.
Although, what you are trying to achieve can be done by std::map
Create Map of your grades.
std::map<char,int> myGrades;
myGrades.insert ( std::pair<char,int>('A',10) );
myGrades.insert ( std::pair<char,int>('B',9) );
myGrades.insert ( std::pair<char,int>('C',8) );
myGrades.insert ( std::pair<char,int>('D',7) );
Read input: (this is same. only change is index starts from 0)
for(i=0;i<3;i++)
{
cout<<"Ingrese calificacion con letra "<<i;
cin>>calificaciones[i];
}
Get actual integers from map.
int total_grades = ( myGrades.find(calificaciones[0])->second +
myGrades.find(calificaciones[1])->second +
myGrades.find(calificaciones[2])->second);
promedio=total_grades /3.0; //<-- NOtice 3.0 to avoid int/int

It's impossible to change the datatype of a variable in strongly-typed languages like C++, Java, etc. You'll need to define a new variable with the desired type instead. Weakly-typed languages like Python and PHP are (generally) typeless and will let you mix and match datatypes however you like, but it's not possible in C++. You can technically use void pointers to point to objects of any type, but they don't let you change the type of existing variables. Here is more information on strong and weak typing.
If you're okay with creating a new variable, you can use conversion functions or manually convert between datatypes (if possible). For example, it's not possible to convert the string "Hello world" to an int, but you can change a string like "42" to an int. The cstdlib / stdlib.h header provides functions like atof() and atoi() which can do basic conversions (make sure you convert any C++ strings to character arrays using myString.c_str() before passing them). stringstream is also a very powerful tool which easily converts practically anything to a string, among other uses.
I'm not quite sure what you want to do, but you can use the ASCII values of the characters to convert them. For example, the letter A has the ASCII value of 65, B is 66, C is 67, and so on. Because characters are inherently stored as numbers, you can convert them without using special conversion functions. You can simply assign a char to an int:
char ch = 'A';
int x = ch; // this is an implicit conversion
cout << x << endl; // this prints '65'
The character is being cast to an integer. You can also explicitly convert it:
char ch = 'A';
cout << ch << endl; // this prints 'A'
cout << (int) ch << endl; // this prints '65' because of the explicit conversion
It also works the other way around:
int x = 65;
char ch = x;
cout << ch << endl; // this prints 'A'

Related

How can I read accented characters in C++ and use them with isalnum?

I am programming in French and, because of that, I need to use accented characters. I can output them by using
#include <locale> and setlocale(LC_ALL, ""), but there seems to be a problem when I read accented characters. Here is simple example I made to show the problem :
#include <locale>
#include <iostream>
using namespace std;
const string SymbolsAllowed = "+-*/%";
int main()
{
setlocale(LC_ALL, ""); // makes accents printable
// Traduction : Please write a string with accented characters
// 'é' is shown correctly :
cout << "Veuillez écrire du texte accentué : ";
string accentedString;
getline(cin, accentedString);
// Accented char are not shown correctly :
cout << "Accented string written : " << accentedString << endl;
for (unsigned int i = 0; i < accentedString.length(); ++i)
{
char currentChar = accentedString.at(i);
// The program crashes while testing if currentChar is alphanumeric.
// (error image below) :
if (!isalnum(currentChar) && !strchr(SymbolsAllowed.c_str(), currentChar))
{
cout << endl << "Character not allowed : " << currentChar << endl;
system("pause");
return 1;
}
}
cout << endl << "No unauthorized characters were written." << endl;
system("pause");
return 0;
}
Here is an output example before the program crashes :
Veuillez écrire du texte accentué : éèàìù
Accented string written : ʾS.?—
I noticed the debugger from Visual Studio shows that I have written something different than what it outputs :
[0] -126 '‚' char
[1] -118 'Š' char
[2] -123 '…' char
[3] -115 '' char
[4] -105 '—' char
The error shown seems to tell that only characters between -1 and 255 can be used but, according to the ASCII table the value of the accented characters I used in the example above do not exceed this limit.
Here is a picture of the error dialog that pops up : Error message: Expression: c >= -1 && c <= 255
Can someone please tell me what I am doing wrong or give me a solution for this? Thank you in advance. :)
char is a signed type on your system (indeed, on many systems) so its range of values is -128 to 127. Characters whose codes are between 128 and 255 look like negative numbers if they are stored in a char, and that is actually what your debugger is telling you:
[0] -126 '‚' char
That's -126, not 126. In other words, 130 or 0x8C.
isalnum and friends take an int as an argument, which (as the error message indicates) is constrained to the values EOF (-1 on your system) and the range 0-255. -126 is not in this range. Hence the error. You could cast to unsigned char, or (probably better, if it works on Windows), use the two-argument std::isalnum in <locale>
For reasons which totally escape me, Windows seems to be providing console input in CP-437 but processing output in CP-1252. The high half of those two code pages is completely different. So when you type é, it gets sent to your program as 130 (0xC2) from CP-437, but when you send that same character back to the console, it gets printed according to CP-1252 as an (low) open single quote ‚ (which looks a lot like a comma, but isn't). So that's not going to work. You need to get input and output to be on the same code page.
I don't know a lot about Windows, but you can probably find some useful information in the MS docs. That page includes links to Windows-specific functions which set the input and output code pages.
Intriguingly, the accented characters in the source code of your program appear to be CP-1252, since they print correctly. If you decide to move away from code page 1252 -- for example, by adopting Unicode -- you'll have to fix your source code as well.
With the is* and to* functions, you really need to cast the input to unsigned char before passing it to the function:
if (!isalnum((unsigned char)currentChar) && !strchr(SymbolsAllowed.c_str(), currentChar)) {
While you're at it, I'd advise against using strchr as well, and switch to something like this:
std::string SymbolsAllowed = "+-*/%";
if (... && SymbolsAllowed.find(currentChar) == std::string::npos)
While you're at it, you should probably forget that you ever even heard of the exit function. You should never use it in C++. In the case here (exiting from main) you should just return. Otherwise, throw an exception (and if you want to exit the program, catch the exception in main and return from there).
If I were writing this, I'd do the job somewhat differently in general though. std::string already has a function to do most of what your loop is trying to accomplish, so I'd set up symbolsAllowed to include all the symbols you want to allow, then just do a search for anything it doesn't contain:
// Add all the authorized characters to the string:
for (unsigned char a = 0; a < std::numeric_limits<unsigned char>::max(); a++)
if (isalnum(a) || isspace(a)) // you probably want to allow spaces?
symbolsAllowed += a;
// ...
auto pos = accentedString.find_first_not_of(symbolsAllowed);
if (pos != std::string::npos) {
std::cout << "Character not allowed: " << accentedString[pos];
return 1;
}

Trying to ignore all whitespace up to the first character (desperately needing a simple nudge)

I'll be flat out honest, this is a small snippet of code I need to finish my homework assignment. I know the community is very suspicious of helping students, but I've been racking my head against the wall for the past 5 hours and literally have accomplished nothing on this assignment. I've never asked for help on any assignments, but none have given me this much trouble.
All I'm having trouble with is getting the program to strip the leading whitespace out. I think I can handle the rest. I'm not asking for a solution to my overall assignment, just a nudge on this one particular section.
I'll post the full assignment text here, but I am NOT posting it to try to get a full solution, I'm only posting it so others can see the conditions I have to work with.
"This homework will give you more practice in writing functions and also how numbers are read into a variable. You need to write a function that will read an unsigned integer into a variable of type unsigned short int. This will have a maximum value of 65535, and the function needs to take care of illegal numbers. You can not use "cin >>", inside the function.
The rules for numeric input are basically as follows:
1) skip all leading white spaces
2) first character found must be numeric else an error will occur
3) numeric characters are then processed one at a time and combine with number
4) processing stops when non-numeric found
We will follow these rules and also add error handling and overflow. If an illegal entry is made before a numeric than an error code of "1" will be sent back, if overflow occurs, that is number bigger then 65535, then error code of "2" will be sent back. If no error then "0" is sent back.
Make sure the main function will continue to loop until the user enters a “n” or “N” for NO, the main should test the error code returned from the function called “ReadInt” and display appropriate error messages or display the number if there is no error. Take care in designing the “ReadInt” function, it should be value returning and have a reference parameter. The function needs to process one character at a time from the input buffer and deal with it in a correct fashion. Once the number has been read in, then make sure the input buffer is empty, otherwise the loop in main may not work correct. I know this is not how the extraction works, but lets do it this way.
You do not need to turn in an algorithm with this assignment, but I would advise you to write one. And the debugger may prove helpful as well. You are basically rewriting the extraction operator as it works on integers."
A majority of my code won't make sense as I've been deleting things and adding things like crazy to try everything I can think of.
#include <iostream>
#include <CTYPE.h>
using namespace std;
int ReadInt (unsigned short int &UserIn);
int main()
{
int Error;
unsigned short int UserInput;
char RepeatProgram;
do
{
Error=ReadInt(UserInput);
if (Error==0)
cout << "Number is " << UserInput << endl;
else if (Error==1)
cout << "Illegal Data Entry\n";
else if (Error==2)
cout << "Numerical overflow, number too big\n";
cout << "Continue? n/N to quit: ";
cin >> RepeatProgram;
cout << endl;
} while (RepeatProgram!='N' && RepeatProgram!='n');
}
int ReadInt (unsigned short int &UserIn)
{
int Err=0;
char TemporaryStorage;
long int FinalNumber=0;
cout << "Enter a number: ";
//cin.ignore(1000, !' '); this didn't work
cin.get(TemporaryStorage);
cout << TemporaryStorage;//I'm only displaying this while I test my ideas to see if they are working or not, before I move onto the the next step
cout << endl;
return Err;
}
I really appreciate any help I may get and hope I don't give the impression that I'm looking for a full free solution to the whole problem. I want to do this on my own, I'm just lot on this beginning.
As a preface, I want to state that this is a question made by a student, but unlike most of their type, it is a quality question that merits a quality answer, so I'll try to do it ;). I won't try to just answer your concrete question, but also to show you other slight problems in your code.
First of all, let's analyze your code step by step. More or less like what a debugger would do. Take your time to read this carefully ;)...
#include <iostream>
#include <CTYPE.h>
Includes headers <iostream> and <ctype.h> (the uppercase works because of some flaws/design-decisions of NTFS in Windows). I'ld recommend you to change the second line to #include <cctype> instead.
using namespace std;
This is okay for any beginner/student, but don't get an habit of it! For the purposes of "purity", I would explicitly use std:: along this answer, as if this line didn't existed.
int ReadInt (unsigned short int &UserIn);
Declares a function ReadInt that takes a reference UserIn to type unsigned short int and returns an object of type int.
int main()
{
Special function main; no parameters, returns int. Begin function.
int Error;
unsigned short int UserInput;
char RepeatProgram;
Declares variables Error, UserInput, and RepeatProgram with respective types int, unsigned short int, and char.
do
{
Do-while block. Begin.
Error=ReadInt(UserInput);
Assign return value of ReadInt of type int called with argument UserInput of type int& to variable Error of type unsigned short int.
if (Error==0)
std::cout << "Number is " << UserInput << endl;
If Error is zero, then print out UserInput to standard output.
else if (Error==1)
std::cout << "Illegal Data Entry\n";
else if (Error==2)
std::cout << "Numerical overflow, number too big\n";
Otherwise, if an error occurs, report it to the user by means of std::cout.
std::cout << "Continue? n/N to quit: ";
std::cin >> RepeatProgram;
Query the user if he/she wants to continue or quit. Store the input character in RepeatProgram of type char.
std::cout << std::endl;
Redundant, unless you want to add padding, which is probably your purpose. Actually, you're better off doing std::cout << '\n', but that doesn't matters too much.
} while (RepeatProgram!='N' && RepeatProgram!='n');
Matching expression for the do-while block above. Repeat execution of the given block if RepeatProgram is neither lower- or uppercase- letter N.
}
End function main. Implicit return value is zero.
int ReadInt (unsigned short int &UserIn)
{
Function ReadInt takes a reference UserIn to unsigned short int and returns an object of type int. Begin function.
int Err=0;
char TemporaryStorage;
long int FinalNumber=0;
Declares variables Err, TemporaryStorage, and FinalNumber of respective types int, char, and long int. Variables Err and FinalNumber are initialized to 0 and 0, respectively. But, just a single thing. Didn't the assignment said that the output number be stored in a unsigned short int? So, better of this...
unsigned short int FinalNumber = 0;
Now...
std::cout << "Enter a number: ";
//std::cin.ignore(1000, !' '); this didn't work
Eh? What's this supposed to be? (Error: Aborting debugger because this makes no logic!**). I'm expecting that you just forgot the // before the comment, right? Now, what do you expect !' ' to evaluate to other than '\0'? istream::ignore(n, ch)will discard characters from the input stream until either n characters have been discarded, ch is found, or the End-Of-File is reached.
A better approach would be...
do
std::cin.get(TemporaryStorage);
while(std::isspace(TemporyStorage));
Now...
std::cin.get(TemporaryStorage);
This line can be discarded with the above approach ;).
Right. Now, where getting into the part where you obviously banged your head against all solid objects known to mankind. Let me help you a bit there. We have this situation. With the above code, TemporaryStorage will hold the first character that is not whitespace after the do-while loop. So, we have three things left. First of all, check that at least one digit is in the input, otherwise return an error. Now, while the input is made up of digits, translate characters into integers, and multiply then add to get the actual integer. Finally, and this is the most... ahem... strange part, we need to avoid any overflows.
if (!std::isdigit(TemporaryStorage)) {
Err = 1;
return Err;
}
while (std::isdigit(TemporaryStorage)) {
unsigned short int OverflowChecker = FinalNumber;
FinalNumber *= 10; // Make slot for another digit
FinalNumber += TemporaryStorage - '0'; '0' - '0' = 0, '1' - '0' = 1...
// If an unsigned overflows, it'll "wrap-around" to zero. We exploit that to detect any possible overflow
if (FinalNumber > 65535 || OverflowChecker > FinalNumber) {
Err = 2;
return Err;
}
std::cin.get(TemporaryStorage);
}
// We've got the number, yay!
UserIn = FinalNumber;
The code is self-explanatory. Please comment if you have any doubts with it.
std::cout << TemporaryStorage;//I'm only displaying this while I test my ideas to see if they are working or not, before I move onto the the next step
cout << endl;
return Err;
Should I say something here? Anyway, I already did. Just remember to take that std::couts out before showing your work ;).
}
End function ReadInt.
You can skip leading whitespace from a stream using std::ws. For example:
std::cin >> std::ws;
This use of >> just invokes the manipulator std::ws on the stream. To meet the teacher's requirements you can invoke it directly:
std::ws(std::cin);
Formatted input automatically skips whitespace. Note that should also always check whether input was successful:
if (std::cin.get(TemporaryStorage)) {
...
}

The cmd does not show binary or simbols

Whenever I compile the program and run it, if the output contains some binary code or any symbols, like ?, heart, ! something like that, it never shows up.
Is there anyone has same problem or anyone who knows how to solve it? My window is not in Korean, but I am using Korean Keyboard with U.S. like:
My local and any other things are set up with U.S.
Supposed your code (which you unfortunately don't show in your question) is something like
int main() {
int n = 4;
float n2 = 4;
char n = 4;
std::cout << n << std::endl;
std::cout << n1 << std::endl;
std::cout << n2 << std::endl;
}
You should acknowledge that char values should be initialized using '4' to get a printable character.
These can also be numbers, but you need to put the correct character encoding codes then, that are supported by your targets environment.
The most common encoding nowadays is ASCII, where the correct decimal equivalent for 4 is encoded as 52 as decimal number.
C++ provides different overloads of the std::ostream& operator<<(std::ostream&, type) for all of the mentioned types like int, float and char. Rendering the numerical types is already done automatically.
If you actually want to render the numerical value contained from char n2, simply cast it.
My window is not in Korean, but I am using Korean Keyboard with U.S. like: ...
Your keyboard settings don't have any relevance here.
Change
char n2 = 4;
to
char n2 = '4';

how to insert a word and use it to make comparison in if condition in c++

i want to use the word i insert to use it to make comparison in if condition to show some word it the comparison is true.
here is my code
#include <iostream>
using namespace std;
int main()
{
char u[5];
cout<<" p " <<" c "<<" U "<<endl;
cout<<" pepsi=5"<<" coca=3"<<" 7-UP=2"<<endl;
cout<<"CHOOSE your drink"<<endl;
cin>>u;
if (u=="pepsi")
cout<<"your choice is pepsi and ur bill is 5 ";
}
First in the future I would suggest trying to be more specific on what your problem is and what you don't understand. Just saying I want to do X and here is my code is giving us very little to work with and we are basically just guessing on what you are having problems with.
Now on to what I believe you are having problems with (I am assuming since you didn't tell us what is going wrong).
In this case you are using a character array with a length of 5. Now when you use character arrays you need to take into account that all the reasonable inputs that that variable might store will actually fit into that character array.
Let's look at pepsi. You might think it would fit but in fact it doesn't because you are forgetting about the null character that is added on the end. This is what it looks like.
u[0] = 'p'
u[1] = 'e'
u[2] = 'p'
u[3] = 's'
u[4] = 'i'
u[5] = '\0'
So as you can see there is actually 6 characters in this word which will cause a overflow. I am assuming this is your problem.
Now how do we fix this? As others have said in the comments if you are using C++ it is probably better for you to use std::string for this problem since it will hide from you most of the problems you have to do deal with when using C style string (What you are using now). Then once you feel more comfortable with the language you can come back and revisit C style strings.
With std::string it would look something like this. Remember that when testing strings case matters (IE "string" is not the same as "String").
std::string choice;
std::cin >> choice;
if (choice == "pepsi")
{
std::cout << "You selected pepsi!" << std::endl;
}
Hope that helps a little and fixes your problems.

Task using for (strcmp aswell)

This is the code that I have now:
int main() {
char stupac1, stupac2;
for (stupac1 = 'A'; stupac1 <= 'Z'; ++stupac1)
{
for (stupac2 = 'a'; stupac2 <= 'z'; ++stupac2)
// between the caps and the non caps there are 32 letters (ASCII code)
if(strcmp (reinterpret_cast <const char*> (stupac1),
reinterpret_cast <const char*> (stupac2)) == 32 )
{
cout <<stupac1 << stupac2 << endl;
}
else
{
cout << "These letters suck" << endl;
}
}
return 0;
}
The task: I need to write a program with 2 consecutive loops that will make a table which has the letters A-Z and a-z in 2 columns.
I need to use for, but strcmp can be removed if is not necessary. I was trying something but nothing is printed when I run this code and it crashes.
In C++, characters (char) are scalar values just like int, not strings. For example 'A' is equal to 65, assuming an ASCII/Unicode system. To test for equality, use the == operator.
It's quite easy to "count" from A to Z in ASCII, but not all C++ implementations are ASCII. For bonus points with your teacher, point out that the program wouldn't run under EBCDIC.
Also, before getting too accustomed to char * strings, be aware that real C++ programs almost exclusively use std::string, which also uses the == operator for comparison.
strcmp (reinterpret_cast <const char*> (stupac1), reinterpret_cast <const char*>(stupac2))
This invokes undefined behavior, as the arguments to strcmp should be null-terminated strings, but what you're passing are not null-terminated.
Since it is not clear what you're trying to do, I'm not going to suggest an alternative and correct solution.
Single chars are just like a smaller version of int, so you can compare them or subtract their values, just like with ints.
A much simpler version of your test would be
if (stupac2 - stupac1 == 32)
See, much easier. :-)
Whenever you seem to need reinterpret_cast you are probably trying things the wrong way.