Issue with str.push_back - c++

I am trying to create a C++ function with the following behavior:
Input: "A4B5C3" ; Output: "AAAABBBBBCCC"
Input: "R1T3" ; Output: "RTTT"
And so on.
I have written the following function:
#include <iostream>
#include <string>
#include <vector>
using namespace std;
string foo(string s){
int count = 0;
string t = "";
char letter = 'a';
for (string::iterator it=s.begin(); it<s.end(); it++){
if(count%2==0)
{
cout << "count: "<<count << " *it: "<< *it << endl;
letter = *it;
}
else
{
cout <<"count: "<< count << " *it: " << *it << " letter: " << letter << endl;
int j = 0;
while (j<*it)
{
t.push_back(letter);
j++;
}
}
count++;
}
cout << endl<<endl;
return(t);
}
However , on calling foo("A1B4C2D8"), I get this output:
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD
For some reason, my while loop seems to be running 48 more times than I would like it to...

There are no character encodings where the integer 1 is equal to the character '1' (for example).
In the ASCII encoding the character '1' is equal to the integer 49.
That means the condition j<*it is flawed.
The C++ specification requires that all digits are encoded consecutively, so '0' will always come before '1', and '1' will always come before '2', and so on. With that knowledge, together with knowing that char is a simple integer type, you can always subtract '0' from any digit character to get its integer value.
For example '2' - '0' == 2.
To solve your problem the condition should be j < (*it - '0').

Here :
while (j< *it)
you are comparing an integer (int) with a character (char). The character '0' does not equal 0, but as digits have consecutive representations you can subtract '0' from the character to get the corresponding integer:
while (j< *it - '0')

Issue is in the line
int j = 0;
while (j<*it)
...
You are comparing the int value with the chacter.

The character '0' in ASCII encoding has the hexadecimal integer value 0x30 and the decimal integer value 48. The character '1' has the hexadecimal integer value 0x31 and the decimal integer value 49. And so on till '9' that has the hexadecimal integer value 0x39 and the decimal integer value 57.
Even not knowing those ASCII codes the shortest fix is changing int j = 0; to int j = '0'; or char j = '0';. Then the loop while (j < *it) will iterate correctly.

Related

Why is negative char number converting differently?

I need to convert characters from a string into int's then place them into a vector. I started by making a new string of the numbers without the spaces. I then want to iterate through the numbers in the result string and convert to int, then push into a vector. I am having issues with the negative numbers not converting to the right values. I commented out the vector part because I realized the issue is before that, the wrong values are going into the vector.
#include <iostream>
#include <sstream>
#include <vector>
using namespace std;
int main() {
string result = "";
string str = "8 3 -5 42 -1 0 0 -9 4 7 4 -4";
for(char c : str) {
if(c == ' ') {
continue;
}
else {
result += c;
}
}
cout << "result: " << result;
vector<int> lst;
//for(int x = 0; x < result.length(); x++) {
//lst.push_back(result[x] - '0');
//}
//testing the values being converted
int x = result[2] - '0';
cout << "\n" << x;
}
For example,
int x = result[0] - '0';
cout << "\n" << x;
gives me 8, which is the right conversion of the first number in the string.
but,
int x = result[2] - '0';
cout << "\n" << x;
gives me -3, which is not the -5 I am looking for. I am stuck on this and I cannot figure out why the negative numbers are not properly converting, or where the -3 is even coming from. Any help is appreciated, thank you.
Your input is: "8 3 -5 42 -1 0 0 -9 4 7 4 -4"
You put non-space characters into the result array, so:
result[0]->'8'
result[1]->'3'
result[2]->'-'
result[3]->'5'
So result[2] is - which has an ASCII code of 45. The zero digit has an ASCII code of 48. So result[2] - '0' is 45 minus 48 or -3.
You don't say why you expect -5. What character do you think is five less than the digit zero?

Displaying input character's binary value

I'm trying to understand why I keep getting an unexpected binary result. For example, if I were to write
8
I will get a result of
00111000
and not
00001000
I'm not trying to manipulate to get another result, I'm trying to see what the actual data is for my input and understand why it's giving that input.
I'm using C++ in visual studio with a platform of Win32.
This is my code:
#include <stdio.h>
#include <bitset>
#include <iostream>
using namespace std;
int main() {
char cl;
cout << "The minimum value of char is " << CHAR_MIN << endl;
cout << "The maximum value of char is " << CHAR_MAX << endl;
cout << "The storage size in byte(s) of a char is " << sizeof(cl) << endl;
cout << "Input hexadecimal number in the data type of char for example a" << endl;
scanf_s("%c", &cl, sizeof(cl));
bitset < 8 * sizeof(cl)>charBits(cl);
cout << "The converted binary value is " << charBits << endl;
printf("The converted decimal value is% i \n", cl);
}
The value being input is an ASCII character, and you should convert that value to its corresponding number before printing. in ASCII, the letters 'a'-'f' have the range 97-102, 'A'-'F' have the range 65-70, and '0'-'9' have the range 48-57. So after getting your input, test its ASCII value with if's and subtract accordingly like this:
// Subtracting 87 converts 'a' to 10 and 'f' to 15, the numerical representations
// of those hexadecimal values, which are then converted to binary by bitset.
if (cl >= 97 && cl <= 102)
cl -= 87;
// Subtract 10 less again for the same reason above.
else if (cl >= 65 && cl <= 70)
cl -= 55;
// Subtracting 48 from '0' converts it to the number 0 in memory,
// and subtracting 48 from '9' converts it to the number 9.
else if (cl >= 48 && cl <= 57)
cl -= 48;
You'll notice that this breaks the decimal printing, so you should convert the number to decimal for printing like this cout << static_cast<int>(cl) << endl;.

Problem converting a std::string of digits to vector<int> [duplicate]

This question already has answers here:
C++ handling very large integers
(15 answers)
Closed 3 years ago.
I am supposed to get two big integer numbers (up to 600 digits) from console screen and write the result on the console again.
I defined two variables of type std::string to store two big integer numbers .I take their values from the user. To take the sum of that two numbers, I defined two vectors to store the digits of that two strings of numbers .
Here is the problem, when I try to loop through the vector to print the digits that I took from strings of numbers I get the following result .The Ascii values of the digits are printed on The Console.
Could anyone tell me how to fix this problem please.
Note: The code is still not complete .
For the first string I took the numbers 9 8 7 6 5 4 3 2 1 from the user , on the console window I got the following result.
[0]57
[1]56
[2]55
[3]54
[4]53
[5]52
[6]51
[7]50
[8]49
#include <iostream>
#include <sstream>
#include <vector>
#include <algorithm>
std::string Sum_Of_Two_Long_Integers()
{
std::string First_String ;
std::string Second_String ;
std::string Result_String ;
std::cout << "Please enter the first number: " ;
std::getline(std::cin, First_String);
std::cout << "Please enter the second number: " ;
std::getline(std::cin, Second_String);
std::vector <int> First_String_Vector (First_String.length()) ;
std::vector <int> Second_String_Vector (Second_String.length()) ;
for(int Counter = 0 ; Counter < First_String_Vector.size() ; ++ Counter)
{
First_String_Vector[Counter] = First_String[Counter] ;
Second_String_Vector[Counter] = Second_String[Counter] ;
std::cout << "[" << Counter << "]" << First_String_Vector[Counter] << std::endl ;
}
return Result_String ;
}
int main()
{
std::string Result_String = Sum_Of_Two_Long_Integers() ;
std::cout << "Result = " << Result_String << std::endl ;
return 0 ;
}
First_String_Vector[Counter] = First_String[Counter] ;
Second_String_Vector[Counter] = Second_String[Counter] ;
The digits are stored as ASCII in you string, you should convert to integer before placing them into the vector.
This would do the trick:
First_String_Vector[Counter] = First_String[Counter] - '0';
Second_String_Vector[Counter] = Second_String[Counter] - '0';
I would also add a check for valid input before populating your vectors to make sure that you only read digits:
if(First_String[Counter] < '0' || First_String[Counter] > '9' ||
Second_String[Counter] < '0' || Second_String[Counter] > '9')
{
std::cout << "Invalid input\n";
return "":// Or better throw an exception
}
EDIT: '6' isn't equal to 6. The first one is a char, its value is ASCII for character '6', and the second is the integer 6.
ASCII is an encoding. Characters are mapped to some numbers. Value for '0' is 48, '1' is 49, ..., '9' is 57
To be even more precise C++ does not guarantee to use ASCII encoding (though I don't know of an implementation that does not use it), but it does guarantee that '0'...'9' have contiguous integer values. So '6' - '0' will give us integer 6.

Checking for characters in string in a do...while

do
{
e=0;
cout << "Enter input of base " << base << ": ";
cin >> input;
for ( i=0; i<input.length(); i++)
{
if (input[i]=='A')
value=10;
else if (input[i]=='B')
value=11;
else if (input[i]=='C')
value=12;
else if (input[i]=='D')
value=13;
else if (input[i]=='E')
value=14;
else if (input[i]=='F')
value=15;
else
value=input[i];
if(value>=base)
{
cout << "Invalid input data for your input base!!!" << endl << endl;
e=1;
}
}
}while (e==1);
When ever the user key in let's say 101101, and the base is 2, it will output Invalid for 6 times. What's the error?
I tried to use npos, find(), but they didn't work!
Here:
value=input[i];
You seem to be assuming that the value of the character '0' is 0 and the value of character '1' is 1 (and similarly for other digits). Your assumption is wrong for the character encoding that your system uses. In fact, '0' cannot possibly be represented by the value 0, because that is reserved for the null terminator character that designates the end of a character string.
Thanks But what should i do next?
Subtracting value of a character from another gives you the distance between the representations of those characters (subtracting character from itself gives you 0). Number digit characters are guaranteed to be sequential (0 is immediately before 1 is immediately before 2 ...). Given these axioms, it's easy to prove that subtracting the value of '0' from a character gives you the value that you're looking for.
Replace:
else
value=input[i];
With:
else
value=input[i] - '0';
Because:
'0' = 0x30 = 48

Why does my string get empty values appended to it when subtracting characters?

I am attempting to solve a problem from topcoder.com and it's driving me crazy. I am learning C++ after a long break from C and am having trouble with strings.
The purpose of the program is to decode a string of 0s and 1s that has gone through an encryption algorithm that consists of adding each adjacent digit to the digit in question.
So 010111 becomes 112232 (LSB and MSB are considered to have zeros next to them). Below is my algorithm to decode the string:
#include <string>
#include <vector>
#include <iostream>
using namespace std;
class BinaryCode {
public:
vector<string> decode(string message);
};
vector<string> BinaryCode::decode(string message) {
vector<string> decoded(2);
int i;
string myTempString;
myTempString.append("0");
myTempString.append(1,message[0] - myTempString[0]);
for(i=2; i<message.size(); i++) {
myTempString.append(1,message[i-1] - myTempString[i-1] - myTempString[i-2]);
}
decoded[0] = myTempString;
myTempString = "";
myTempString.append("1");
myTempString.append(1,message[0] - myTempString[0]);
for(i=2; i<message.size(); i++) {
myTempString.append(1, message[i-1] - myTempString[i-1] - myTempString[i-2]);
}
decoded[1] = myTempString;
return decoded;
}
int main () {
string message("123210122");
BinaryCode *code = new BinaryCode;
vector<string> result = code->decode(message);
cout << "Decoded strings are "+result[0]+" and "+result[1];
getchar();
return 0;
}
The output is nonsense:
Decoded strings are 01
This is just a guess, since you don't show what output you're getting, but it looks like you're doing math on the character values and ending up with characters in the control range. For example, '1' - '0' is not '1' (character 49), it is 1, or Control-A. This is not printable and will typically be invisible in the output. Similarly, '1' + '2' is 49 + 50, or 99, which is 'c'. C++ is not going to magically convert these characters to integers for you. Hopefully this will give you the information you need to fix your code.
A character is an 8-bit integral type. It has the special property that, when printed, it will appear as the character that matches the ASCII value that it contains.
For example:
int valueAsInt = 65;
char valueAsChar = valueAsInt;
std::cout << valueAsChar << "\n";
valueAsInt = 'A';
std::cout << valueAsInt << "\n";
A
65
Take the value of the character literal '0'. This corresponds to the ASCII value 48. '1' is 49, etc.
If you subtract 48 from 49, you get 1. But that's not what you're looking for.
The ASCII value 1 corresponds to a non-printable character, called "start of heading". It was once used on old printers as a sort of markup. It would not print, but it would modify how further characters are printed.
When you subtract one numeric character from another, you get a delta, not a printable character. To turn this delta back into a printable character, you have to add it to a base character:
char value = '5' - '3';
value += '0';
std::cout << "5 - 3 = " << value << "\n";
5 - 3 = 2
So, your code such as message[0] - myTempString[0] must be changed to message[0] - myTempString[0] + '0' in order to work the way you intend it to.