Keep in mind, if you choose to answer the question, I am a beginner in the field of programming and may need a bit more explanation than others as to how the solutions work.
Thank you for your help.
My problem is that I am trying to do computations with parts of a string (consisting only of numbers), but I do not know how to convert an individual char to an int. The string is named "message".
for (int place = 0; place < message.size(); place++)
{
if (secondPlace == 0)
{
cout << (message[place]) * 100 << endl;
}
}
Thank you.
If you mean that you want to convert the character '0' to the integer 0, and '1' to 1, et cetera, than the simplest way to do this is probably the following:
int number = message[place] - '0';
Since the characters for digits are encoded in ascii in ascending numerical order, you can subtract the ascii value of '0' from the ascii value of the character in question and get a number equal to the digit.
Related
int main()
{
string s;
cout << "enter the string :" << endl;
cin >> s;
for (int i = 0; i < s.length(); i++)
s[i] ^= 32;
cout << "modified string is : " << s << endl;
return 0;
}
I saw this code which converts uppercase to lowercase on stackoverflow.
But I don't understand the line s[i] = s[i]^32.
How does it work?
^= is the exclusive-or assignment operator. 32 is 100000 in binary, so ^= 32 switches the fifth bit in the destination. In ASCII, lower and upper case letters are 32 positions apart, so this converts lower to upper case, and also the other way.
But it only works for ASCII, not for Unicode for example, and only for letters. To write portable C++, you should not assume the character encoding to be ASCII, so please don't use such code. #πάντα ῥεῖs answer shows a way to do it properly.
How does it work?
Let's see for ASCII value 'A':
'A' is binary 1000001
XORed with 32 (binary 100000)
yields any value where the upper character indicating bit isn't set:
1000001
XOR
100000
= 1100001 == 'a' in ASCII.
Any sane and portable c or c++ application should use tolower():
int main()
{
string s;
cout<<"enter the string :"<<endl;
cin>>s;
for (int i=0;i<s.length();i++) s[i] = tolower( (unsigned char)s[i] );
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
cout<<"modified string is : "<<s<<endl;
return 0;
}
The s[i]=s[i]^32 (cargo cult) magic, relies on ASCII table specific mapping to numeric char values.
There are other char code tables like e.g. EBCDIC
, where the
s[i]=s[i]^32
method miserably fails to retrieve the corresponding lower case letters.
There's a more sophisticated c++ version of converting to lower case characters shown in the reference documentation page of std::ctype::tolower().
In C++, like its predecessor C, a char is a numeric type. This is after all how characters are represented on the hardware and these languages don't hide that from you.
In ASCII, letters have the useful property that the difference between an uppercase and a lowercase letter is a single binary bit: the 5th bit (if we start numbering from the right starting at 0).
Uppercase A is represented by the byte 0b01000001 (0x41 in hex), and lowercase a is represented by the byte 0b01100001 (0x61 in hex). Notice that the only difference between uppercase and lowercase A is the fifth bit. This pattern continues from B to Z.
So, when you do ^= 32 (which, incidentally, is 2 to the 5th power) on a number that represents an ASCII character, what that does is toggle the 5th bit - if it is 0, it becomes 1, and vice versa, which changes the character from upper to lower case and vice versa.
I'm new in C++ and I have simple problem. I have to change my number (1011) to decimal result. Cmath is included. I try to use pow method but look at my output please:
Code:
char *b = "1011";
int maxPow = 3;
for (int i = 0; i < 3; ++i) {
cout << b[i] * pow(b[i], (maxPow - i) / 1.0) << endl;
}
Output:
5.7648e+006
110592
2401
I try to make it like this:
result = 1*2^3 + 1*2^2 + 0*2^1 + 1*2^0
The problem is with my array? Where? Please, help me if you can.
So, the problem you're running into, is that you are looping over a ascii value and multiplying the ascii value. Try something like int digit = b[i]-'0'; and then substitute where you use b[i] with the variable digit.
subtracting '0' ... means you are subtracting the ascii value of zero from a given character. So subtracting the ascii value of '0' from '0' gives you the numerical value 0, or subtracting ascii '0' from ascii '1', giving you the numerical value 1.
Take a look at - http://www.asciitable.com/index/asciifull.gif to get a better understanding.
Another little demo you can do, is just cout b[i], and you will see the value 48 or 49 printed, as they are the numerical values of ascii 0 and ascii 1, respectively.
I have a program I'm making for date validation. I am receiving the input from user in the form of MM/DD/YYYY and storing it as a character array.
First I tried to break it apart into int variables for month day and year with casting
char UserDate[10];
int month = 00, day = 00, year = 0000;
cout << "Enter a date in the format of MM/DD/YYYY" << endl;
cin >> UserDate;
month = (int)UserDate[0] + (int)UserDate[1];
day = (int)UserDate[3] + (int)UserDate[4];
year = (int)UserDate[6] + (int)UserDate[7] + (int)UserDate[8] + (int)UserDate[9];
I then tried it without casting
char UserDate[10];
int month = 00, day = 00, year = 0000;
cout << "Enter a date in the format of MM/DD/YYYY" << endl;
cin >> UserDate;
month = UserDate[0] + UserDate[1];
day = UserDate[3] + UserDate[4];
year = UserDate[6] + UserDate[7] + UserDate[8] + UserDate[9];
The problem is I cant get the actual value out of the index of the array.
The results I get for the date entered 01/01/2014 are as follows:
month = 48'0' + 49'1'; //months value is 97
day = 48'0' + 49'1'; //days value is 97
year = 50'2' + 48'0' + 49'1' + 52'4'; //years value is 199
This happens for both methods above whether i cast the char as int or not. How do I get the value stored at the index that I want since there is no UserDate[1].Value??
Casting does not convert a char into an int. Subtract '0' to get the int value.
month = 10 * (UserDate[0] - '0') + UserDate[1] - '0';
Your UserDate array is in fact an array of characters, each represented by a standard ASCII code (see the complete ASCII table here). Using explicit casting like you did results in converting the char (no matter whether a letter or a digit) to the integer ASCII code. For example - the character '0' has an ASCII value of 48, so writing (int)'0' equals 48.
Since digits 0-9 appear sequentially in the ASCII table, you can evaluate each char by writing:
int digit = (int)UserDate[...] - '0'
The mathematics here are pretty simple so I trust you to understand why that's true.
Please notice that if your character is not a digit, this conversion will result in a negative integer or a number greater than 9, so you should check that the value you've received is valid.
The problem you're running into here is that C does not convert characters to numbers in this manner. A char is a 1-byte number. Whether or not a char is signed or unsigned depends on your compiler unless you specifically specify in your code. If I do:
char x = '1';
int y = (int)x;
I actually have that y = 49 with my compiler and on my platform. This is the ASCII value of the character 1, and for the intent of this discussion it might be different for someone else (specifically, if I make x an unsigned char I'm probably okay, and the ASCII value for 1 is low enough that it might be anyway). Don't assume that chars are going to hold a specific value unless you know what you're doing. Some people use them as tiny integers and there are tricks that you can do if you understand ASCII. In my opinion, these are best hidden away in a library or used only in very special cases.
Secondly, you can't just add the casted values: even assuming the cast works, you're adding the digits-for the year 1999, your method would give 28. Because it doesn't, what you're getting is the sum of the ASCII values of that part of the string. If you want + to concatenate strings, you have to use std::string for everything. Otherwise, chars are basically 1-byte integers.
If you are absolutely, absolutely positive that the string is valid, you can do the following. If it is not valid, this will break, so you'll need to validate the string. Here's a program that demonstrates the technique. This is not the best coding practice: you should probably use std::string, make parseDate a constructor, and do a few other things. I've kept this intentionally simple at the cost of some good design practices. In reality, I suggest looking for a date handling library: boost.date_time is not something that I have used, but based off my experiences with other parts of boost would make it my first choice. You will eventually need more functionality unless this is a very small project, and why reinvent the wheel? Anyhow:
#include <stdio.h>
class date {
public:
int day, month, year;
};
date parseDate(const char* str) {
date d;
sscanf(str, "%i/%i/%i", &d.month, &d.day, &d.year);
return d;
}
void main() {
char test[255];
scanf("%s", &test);
date d = parseDate(test);
printf("%i %i %i", d.day, d.month, d.year);
}
Note that, at least in my opinion, sscanf and scanf are actually more powerful than cin and cout in a lot of ways-for this kind of parsing specifically, and without bringing in external libraries, they're almost always my first choice. Since you're already using a char array (which is unsafe, you should probably use std::string), you need no extra conversion. If you need to pass an std::string into this, use std::string::c_str(), as in:
string dateString;
cin>>dateString;
date d = parseDate(dateString.c_str());
Hope this helps.
I am new to C so I do not understand what is happening in this line:
out[counter++] = recurring_count + '0';
What does +'0' mean?
Additionally, can you please help me by writing comments for most of the code? I don't understand it well, so I hope you can help me. Thank you.
#include "stdafx.h"
#include "stdafx.h"
#include<iostream>
void encode(char mass[], char* out, int size)
{
int counter = 0;
int recurring_count = 0;
for (int i = 0; i < size - 1; i++)
{
if (mass[i] != mass[i + 1])
{
recurring_count++;
out[counter++] = mass[i];
out[counter++] = recurring_count + '0';
recurring_count = 0;
}
else
{
recurring_count++;
}
}
}
int main()
{
char data[] = "yyyyyyttttt";
int size = sizeof(data) / sizeof(data[0]);
char * out = new char[size + 1]();
encode(data, out, size);
std::cout << out;
delete[] out;
std::cin.get();
return 0;
}
It adds the character encoding value of '0' to the value in recurring_count. If we assume ASCII encoded characters, that means adding 48.
This is common practice for making a "readable" digit from a integer value in the range 0..9 - in other words, convert a single digit number to an actual digit representation in a character form. And as long as all digits are "in sequence" (only digits between 0 and 9), it works for any encoding, not just ASCII - so a computer using EBCDIC encoding would still have the same effect.
recurring_count + '0' is a simple way of converting the int recurring_count value into an ascii character.
As you can see over on wikipedia the ascii character code of 0 is 48. Adding the value to that takes you to the corresponding character code for that value.
You see, computers may not really know about letters, digits, symbols; like the letter a, or the digit 1, or the symbol ?. All they know is zeroes and ones. True or not. To exist or not.
Here's one bit: 1
Here's another one: 0
These two are only things that a bit can be, existence or absence.
Yet computers can know about, say, 5. How? Well, 5 is 5 only in base 10; in base 4, it would be a 11, and in base 2, it would be 101. You don't have to know about the base 4, but let's examine the base 2 one, to make sure you know about that:
How would you represent 0 if you had only 0s and 1s? 0, right? You probably would also represent the 1 as 1. Then for 2? Well, you'd write 2 if you could, but you can't... So you write 10 instead.
This is exactly analogous to what you do while advancing from 9 to 10 in base 10. You cannot write 10 inside a single digit, so you rather reset the last digit to zero, and increase the next digit by one. Same thing while advancing from 19 to 20, you attempt to increase 9 by one, but you can't, because there is no single digit representation of 10 in base 10, so you rather reset that digit, and increase the next digit.
This is how you represent numbers with just 0s and 1s.
Now that you have numbers, how would you represent letters and symbols and character-digits, like the 4 and 3 inside the silly string L4M3 for example? You could map them; map them so, for example, that the number 1 would from then on represent the character A, and then 2 would represent B.
Of course, it would be a little problematic; because when you do that the number 1 would represent both the number 1 and the character A. This is exactly the reason why if you write...
printf( "%d %c", 65, 65 );
You will have the output "65 A", provided that the environment you're on is using ASCII encoding, because in ASCII 65 has been mapped to represent A when interpreted as a character. A full list can be found over there.
In short
'A' with single quotes around delivers the message that, "Hey, this A over here is to receive whatever the representative integer value of A is", and in most environments it will just be 65. Same for '0', which evaluates to 48 with ASCII encoding.
I have a char a[] of hexadecimal characters like this:
"315c4eeaa8b5f8aaf9174145bf43e1784b8fa00dc71d885a804e5ee9fa40b16349c146fb778cdf2d3aff021dfff5b403b510d0d0455468aeb98622b137dae857553ccd8883a7bc37520e06e515d22c954eba5025b8cc57ee59418ce7dc6bc41556bdb36bbca3e8774301fbcaa3b83b220809560987815f65286764703de0f3d524400a19b159610b11ef3e"
I want to convert it to letters corresponding to each hexadecimal number like this:
68656c6c6f = hello
and store it in char b[] and then do the reverse
I don't want a block of code please, I want explanation and what libraries was used and how to use it.
Thanks
Assuming you are talking about ASCII codes. Well, first step is to find the size of b. Assuming you have all characters by 2 hexadecimal digits (for example, a tab would be 09), then size of b is simply strlen(a) / 2 + 1.
That done, you need to go through letters of a, 2 by 2, convert them to their integer value and store it as a string. Written as a formula you have:
b[i] = (to_digit(a[2*i]) << 4) + to_digit(a[2*i+1]))
where to_digit(x) converts '0'-'9' to 0-9 and 'a'-'z' or 'A'-'Z' to 10-15.
Note that if characters below 0x10 are shown with only one character (the only one I can think of is tab, then instead of using 2*i as index to a, you should keep a next_index in your loop which is either added by 2, if a[next_index] < '8' or added by 1 otherwise. In the later case, b[i] = to_digit(a[next_index]).
The reverse of this operation is very similar. Each character b[i] is written as:
a[2*i] = to_char(b[i] >> 4)
a[2*i+1] = to_char(b[i] & 0xf)
where to_char is the opposite of to_digit.
Converting the hexadecimal string to a character string can be done by using std::substr to get the next two characters of the hex string, then using std::stoi to convert the substring to an integer. This can be casted to a character that is added to a std::string. The std::stoi function is C++11 only, and if you don't have it you can use e.g. std::strtol.
To do the opposite you loop over each character in the input string, cast it to an integer and put it in an std::ostringstream preceded by manipulators to have it presented as a two-digit, zero-prefixed hexadecimal number. Append to the output string.
Use std::string::c_str to get an old-style C char pointer if needed.
No external library, only using the C++ standard library.
Forward:
Read two hex chars from input.
Convert to int (0..255). (hint: sscanf is one way)
Append int to output char array
Repeat 1-3 until out of chars.
Null terminate the array
Reverse:
Read single char from array
Convert to 2 hexidecimal chars (hint: sprintf is one way).
Concat buffer from (2) to final output string buffer.
Repeat 1-3 until out of chars.
Almost forgot to mention. stdio.h and the regular C-runtime required only-assuming you're using sscanf and sprintf. You could alternatively create a a pair of conversion tables that would radically speed up the conversions.
Here's a simple piece of code to do the trick:
unsigned int hex_digit_value(char c)
{
if ('0' <= c && c <= '9') { return c - '0'; }
if ('a' <= c && c <= 'f') { return c + 10 - 'a'; }
if ('A' <= c && c <= 'F') { return c + 10 - 'A'; }
return -1;
}
std::string dehexify(std::string const & s)
{
std::string result(s.size() / 2);
for (std::size_t i = 0; i != s.size(); ++i)
{
result[i] = hex_digit_value(s[2 * i]) * 16
+ hex_digit_value(s[2 * i + 1]);
}
return result;
}
Usage:
char const a[] = "12AB";
std::string s = dehexify(a);
Notes:
A proper implementation would add checks that the input string length is even and that each digit is in fact a valid hex numeral.
Dehexifying has nothing to do with ASCII. It just turns any hexified sequence of nibbles into a sequence of bytes. I just use std::string as a convenient "container of bytes", which is exactly what it is.
There are dozens of answers on SO showing you how to go the other way; just search for "hexify".
Each hexadecimal digit corresponds to 4 bits, because 4 bits has 16 possible bit patterns (and there are 16 possible hex digits, each standing for a unique 4-bit pattern).
So, two hexadecimal digits correspond to 8 bits.
And on most computers nowadays (some Texas Instruments digital signal processors are an exception) a C++ char is 8 bits.
This means that each C++ char is represented by 2 hex digits.
So, simply read two hex digits at a time, convert to int using e.g. an istringstream, convert that to char, and append each char value to a std::string.
The other direction is just opposite, but with a twist.
Because char is signed on most systems, you need to convert to unsigned char before converting that value again to hex digits.
Conversion to and from hexadecimal can be done using hex, like e.g.
cout << hex << x;
cin >> hex >> x;
for a suitable definition of x, e.g. int x
This should work for string streams as well.