How to read multiple integers from string - c++

INPUT:
Mint Ice Cream 6 80
CODE:
int IntAmount=2;
string line, name, data;
ifstream fd('Input.txt);
getline(fd, line);
name=line.substr(0, 20); // name="Mint Ice Cream "
data=line.substr(20); // data ="6 80"
for(int i=0; i<IntAmount; i++){
// code that reads N[i] integer by integer from string called data
}
I got some integers stored in the same string data. How do I extract them into array N[i] if I know there are IntAmount of them? I know that I can read the Input in much more basic way, but this is just very simplified input.

Following function will do the job for you:
int string_to_int(char const *input_str, std::size_t count)
{
int result_integer = 0;
std::size_t i = 0 ;
if ( input_str[0] == '+' || input_str[0] == '-' )
++i;
while(i < count)
{
if ( input_str[i] >= '0' && input_str[i] <= '9' )
{
int val = (input_str[0] == '-') ? ('0' - input_str[i] ) : (input_str[i]-'0');
result_integer = result_integer * 10 + val;
}
else
throw std::invalid_argument("invalid string input");
i++;
}
return result_integer;
}

EDIT: nevermind I thought it was C#
You could split the data string into multiple strings as such data.Split(' ') (which splits it at the ' '-character) and then for each substring it returns you can use the function int.Parse(<substring here>) to get the integer equivalent for it.

Related

Spinning words in C++ and recieving error

I'm trying to create a program according to the prompt below but I keep recieving a Caught std::exception, what(): basic_string::at: __n (which is 0) >= this->size() (which is 0) error, I though I was solid at C++ but I guess time takes its toll. My code is down below. Basically, first I parse the string by space character and save them in a vector<string> after that I check if a word is larger than 5 and reverse it if it is and do nothing if it is not. If it isn't the final word, I add a space at the end. Bing bang boom, prompt complete, or at least I thought.
std::string spinWords(const std::string &str)
{
std::vector<std::string> words;
std::string spinnedWord;
int count = 0;
for(unsigned int i = 0; i < str.length(); i++)
{
char currentChar = str.at(i);
if (currentChar == ' ')
{
count++;
continue;
}
else if((int)words.size() == count)
{
words.push_back(&currentChar);
}
else
{
words[count] += currentChar;
}
}
for(unsigned int i = 0; i < words.size(); i++)
{
if(words[i].size() >= 5)
{
for (unsigned int j = words[i].length() - 1; j >= 0; j--)
{
spinnedWord += words[j].at(i);
}
}
if(i + 1 != words.size())
{
spinnedWord += ' ';
}
}
return spinnedWord;
}// spinWords
Write a function that takes in a string of one or more words, and
returns the same string, but with all five or more letter words
reversed (Just like the name of this Kata). Strings passed in will
consist of only letters and spaces. Spaces will be included only when
more than one word is present.
Edit1: I have changed words[j].at(i); to words[i].at(j);
and I have changed words.push_back(&currentChar); to words.push_back(std::string(1, currentChar));
From what I currently understand, when I was pushing back &currentChar, I was causing a undefined behavior. I'll look into how to avoid that in the future. However, the error from before is still present, so the question remains unanswered
for (unsigned int j = words[i].length() - 1; j >= 0; j--)
{
spinnedWord += words[j].at(i);
}
You swapped j an i here. It must be words[i].at(j). Also j probably shouldn't be unsigned here, because the loop condition j >= 0 is always true for unsigned integers.
EDIT: the UB concern for line words.push_back(&currentChar) is valid too. The way to fix it is to construct a string from a char explicitly:
words.push_back(std::string(1, currentChar));
words.push_back(&currentChar);
You're trying to construct a std::string from a pointer to a single character. This compiles because there is a matching constructor, but it takes a C-style string, which your pointer to a single character isn't.
Truly speaking I even do not understand your code. For example what the variable count is doing in the program. Or why you are using an additional container like std::vector when all can be and shall be done with an object of the type std::string because it has all resources to do the task.
The container std::vector is needed only if the assignment is to split a string into words and return the words in an object of the type std::vector<std::string>. But your task is entirely different.
Pay attention to that in general there can be more than one space between words. Even if it is not so in any case you shall use a general approach and not rely on that between words there is only one space.
Your function does not make sense for example when the original string starts from a space character. In this case count will be equal to 1 due to this if statement
if (currentChar == ' ')
{
count++;
continue;
}
but the size of the vector will be equal to 0, So as words.size() is not equal to count then the else statement will be executed
else if((int)words.size() == count)
{
words.push_back(&currentChar);
}
else
{
words[count] += currentChar;
}
that results in undefined behavior.
I can suggest the following solution. In the demonstrative program below I do not use the standard algorithm std::reverse because I think that you have to reverse a word by your own code.
Here you are.
#include <iostream>
#include <string>
#include <utility>
std::string spinWords( const std::string &s, std::string::size_type length = 5 )
{
std::string t( s );
const char *delim = " \t";
for ( std::string::size_type i = 0; i != t.size(); )
{
auto pos = t.find_first_not_of( delim, i );
if ( pos != std::string::npos )
{
i = t.find_first_of( delim, pos );
if ( i == std::string::npos ) i = t.size();
if ( length < i - pos )
{
auto n = i - pos;
for ( std::string::size_type j = 0; j < n / 2; j++ )
{
std::swap( t[pos + j], t[i - j - 1] );
}
}
}
else
{
i = t.size();
}
}
return t;
}
int main()
{
std::string s( "1 12 123 1234 12345 123456 1234567 123456789 1234567890" );
std::cout << s << '\n';
std::cout << spinWords( s ) << '\n';
return 0;
}
The program output is
1 12 123 1234 12345 123456 1234567 123456789 1234567890
1 12 123 1234 12345 654321 7654321 987654321 0987654321

What is the proper way of reading a composite key and a numeric value from an input file?

I'm trying to read a text file consisting of numerous strings which either represent a key/value (the key is a car number in a format of a letter/' '/3digits/' '/2letters; the value is unsigned long long; \t or ' ' between them) or an empty line, e.g.:
empty line
empty line
Z 999 ZZ 80
A 000 AA 124
Z 666 ZZ 42
I am using a cin.getline() function for that, reading a whole line and going through every character, saving a key and a value into an 'element' variable and pushing it into a vector afterwards. But for some reason the program seems to work unexpectedly, giving a weird output:
0
0
Z 999 ZZP 80
A 000 AA| 124
Z 666 ZZ* 42
So far I have been trying to analyse what could go wrong but I just can't see it. I've also tried using other tools like scanf() or cin.get() but failed miserably. Can someone please explain to me why this is happening and maybe show a more correct way of solving this task? Here is the code:
struct kv {
char key[8];
unsigned long long val;
};
int main()
{
std::vector<kv> data_vector;
kv element;
char str[64] = {};
char num[32] = {};
while (std::cin.getline(str, 64)) {
if (str[0] == ' ' || str[0] == '\n' || str[0] == '\t' || str[0] == EOF) {
continue;
}
size_t i = 0, n = 0;
for (i = 0; i < 8; i++)
element.key[i] = str[i];
while (!(str[i] >= '0' && str[i] <= '9'))
i++;
while (str[i] >= '0' && str[i] <= '9')
num[n++] = str[i++];
element.val = atoi(num);
data_vector.push_back(element);
for (n = 0; n < 32; n++)
num[n] = 0;
for (i = 0; i < 64; i++)
str[i] = 0;
}
for (size_t i = 0; i < data_vector.size(); i++) {
std::cout << data_vector[i].key << "\t" << data_vector[i].val << std::endl;
}
return 0;
}
EDIT: as #JimRhodes pointed out, changing char key[8] to char key[9] and adding element.key[8] = '\0' helped, but empty lines are still being processed the wrong way (as they should be ignored), giving an output of 0.
I think you may not be understanding how std::cin.getline() works. First of all, you do not want to test the return value of std::cin.getline() for true or false. You need to check for eof or fail. Secondly, std::cin.getline() discards the newline character so there is no need to check for '\n'. Your loop could start like this:
for ( ; ; )
{
str[0] = '\0'; // Clear any previous data
std::cin.getline(str, 64);
if ( std::cin.eof() )
{
break; // No more data, exit loop
}
if ( std::cin.fail() || (str[0] < 'A') )
{
continue; // Empty line or line does not start with a letter
}
. . .

How to store in a string and convert to character array?

Write a C++ program to perform addition of two hexadecimal numerals which are less than 100 digits long. Use arrays to store hexadecimal numerals as arrays of characters.the solution is to add the corresponding digits in the format of hexadecimal directly. From right to left, add one to the digit on the left if the sum of the current digits exceed 16. You should be able to handle the case when two numbers have different digits.
The correct way to get the input is to store as character array. You can either first store in a string and convert to character array, or you can use methods such as cin.getline(), getc(), cin.get() to read in the characters.
I don't know what is wrong with my program and it I don't know how to use the function getline() and eof()
char a[number1],b[number1],c[number2],h;
int m,n,p(0),q(0),k,d[number1],z[number1],s[number2],L,M;
cout<<"Input two hexadecimal numerals(both of them within 100 digits):\n";
cin.getline(a,100);
cin.getline(b,100);
int x=strlen(a) ;
int y=strlen(b);
for(int i=0;i<(x/2);i++)
{
m=x-1-i;
h=a[i];
a[i]=a[m];
a[m]=h;
}
for(int j=0;j<(y/2);j++)
{
n=y-1-j;
h=b[j];
b[j]=b[n];
b[n]=h;
}
if(x>y)
{
for(int o=0;o<x;o++)//calculate a add b
{
if(o>=(y-1))
z[o]=0;//let array b(with no character)=0
if(a[o]=='A')
d[o]=10;
else if(a[o]=='B')
d[o]=11;
else if(a[o]=='C')
d[o]=12;
else if(a[o]=='D')
d[o]=13;
else if(a[o]=='E')
d[o]=14;
else if(a[o]=='F')
d[o]=15;
else if(a[o]=='0')
d[o]=0;
else if(a[o]=='1')
d[o]=1;
else if(a[o]=='2')
d[o]=2;
else if(a[o]=='3')
d[o]=3;
else if(a[o]=='4')
d[o]=4;
else if(a[o]=='5')
d[o]=5;
else if(a[o]=='6')
d[o]=6;
else if(a[o]=='7')
d[o]=7;
else if(a[o]=='8')
d[o]=8;
else if(a[o]=='9')
d[o]=9;
if(b[o]=='A')
z[o]=10;
else if(b[o]=='B')
z[o]=11;
else if(b[o]=='C')
z[o]=12;
else if(b[o]=='D')
z[o]=13;
else if(b[o]=='E')
z[o]=14;
else if(b[o]=='F')
z[o]=15;
else if(b[o]=='0')
z[o]=0;
else if(b[o]=='1')
z[o]=1;
else if(b[o]=='2')
z[o]=2;
else if(b[o]=='3')
z[o]=3;
else if(b[o]=='4')
z[o]=4;
else if(b[o]=='5')
z[o]=5;
else if(b[o]=='6')
z[o]=6;
else if(b[o]=='7')
z[o]=7;
else if(b[o]=='8')
z[o]=8;
else if(b[o]=='9')
z[o]=9;
p=d[o]+z[o]+q;
if(p>=16)//p is the remained number
{
q=1;
p=p%16;
}
else
q=0;
if(p==0)
c[o]='0';
else if(p==1)
c[o]='1';
else if(p==2)
c[o]='2';
else if(p==3)
c[o]='3';
else if(p==4)
c[o]='4';
else if(p==5)
c[o]='5';
else if(p==6)
c[o]='6';
else if(p==7)
c[o]='7';
else if(p==8)
c[o]='8';
else if(p==9)
c[o]='9';
else if(p==10)
c[o]='A';
else if(p==11)
c[o]='B';
else if(p==12)
c[o]='C';
else if(p==13)
c[o]='D';
else if(p==14)
c[o]='E';
else if(p==15)
c[o]='F';
}
k=x+1;
if(q==1)//calculate c[k]
{
c[k]='1';
for(int f=0;f<=(k/2);f++)
{
m=k-f;
h=c[f];
c[f]=c[m];
c[m]=h;
}
}
else
{
for(int e=0;e<=(x/2);e++)
{
m=x-e;
h=c[e];
c[e]=c[m];
c[m]=h;
}
}
}
if(x=y)
{
for(int o=0;o<x;o++)//calculate a add b
{
if(a[o]=='A')
d[o]=10;
else if(a[o]=='B')
d[o]=11;
else if(a[o]=='C')
d[o]=12;
else if(a[o]=='D')
d[o]=13;
else if(a[o]=='E')
d[o]=14;
else if(a[o]=='F')
d[o]=15;
else if(a[o]=='0')
d[o]=0;
else if(a[o]=='1')
d[o]=1;
else if(a[o]=='2')
d[o]=2;
else if(a[o]=='3')
d[o]=3;
else if(a[o]=='4')
d[o]=4;
else if(a[o]=='5')
d[o]=5;
else if(a[o]=='6')
d[o]=6;
else if(a[o]=='7')
d[o]=7;
else if(a[o]=='8')
d[o]=8;
else if(a[o]=='9')
d[o]=9;
if(b[o]=='A')
z[o]=10;
else if(b[o]=='B')
z[o]=11;
else if(b[o]=='C')
z[o]=12;
else if(b[o]=='D')
z[o]=13;
else if(b[o]=='E')
z[o]=14;
else if(b[o]=='F')
z[o]=15;
else if(b[o]=='0')
z[o]=0;
else if(b[o]=='1')
z[o]=1;
else if(b[o]=='2')
z[o]=2;
else if(b[o]=='3')
z[o]=3;
else if(b[o]=='4')
z[o]=4;
else if(b[o]=='5')
z[o]=5;
else if(b[o]=='6')
z[o]=6;
else if(b[o]=='7')
z[o]=7;
else if(b[o]=='8')
z[o]=8;
else if(b[o]=='9')
z[o]=9;
p=d[o]+z[o]+q;
M=p;
if(p>=16)
{
q=1;
p=p%16;
}
else
q=0;
s[o]=p;
if(p==0)
c[o]='0';
else if(p==1)
c[o]='1';
else if(p==2)
c[o]='2';
else if(p==3)
c[o]='3';
else if(p==4)
c[o]='4';
else if(p==5)
c[o]='5';
else if(p==6)
c[o]='6';
else if(p==7)
c[o]='7';
else if(p==8)
c[o]='8';
else if(p==9)
c[o]='9';
else if(p==10)
c[o]='A';
else if(p==11)
c[o]='B';
else if(p==12)
c[o]='C';
else if(p==13)
c[o]='D';
else if(p==14)
c[o]='E';
else if(p==15)
c[o]='F';
}
k=x+1;
if(q==1)
{
c[k]='1';
for(int f=0;f<=(k/2);f++)
{
m=k-f;
h=c[f];
c[f]=c[m];
c[m]=h;
}
}
else
{
for(int e=0;e<=(x/2);e++)
{
m=x-e;
h=c[e];
c[e]=c[m];
c[m]=h;
}
}
}
Lets look at what cin.getline does:
Extracts characters from stream until end of line. After constructing
and checking the sentry object, extracts characters from *this and
stores them in successive locations of the array whose first element
is pointed to by s, until any of the following occurs (tested in the
order shown):
end of file condition occurs in the input sequence (in which case setstate(eofbit) is executed)
the next available character c is the delimiter, as determined by Traits::eq(c, delim). The delimiter is extracted (unlike basic_istream::get()) and counted towards gcount(), but is not stored.
count-1 characters have been extracted (in which case setstate(failbit) is executed).
If the function extracts no characters (e.g. if count < 1), setstate(failbit)
is executed. In any case, if count>0, it then stores a null character
CharT() into the next successive location of the array and updates
gcount().
The result of that is in all cases, s now points to a null terminated string, of at most count-1 characters.
In your usage, you have up to 99 digits, and can use strlen to count exactly how many. eof is not a character, nor it is a member function of char.
You then reverse in place the inputs, and go about your overly repetitious conversions.
However, it's much simpler to use functions, both those you write yourself and those provided by the standard.
// translate from '0' - '9', 'A' - 'F', 'a' - 'f' to 0 - 15
static std::map<char, int> hexToDec { { '0', 0 }, { '1', 1 }, ... { 'f', 15 }, { 'F', 15 } };
// translate from 0 - 15 to '0' - '9', 'A' - 'F'
static std::map<int, char> decToHex { { 0, '0' }, { 1, '1' }, ... { 15, 'F' } };
std::pair<char, bool> hex_add(char left, char right, bool carry)
{
// translate each hex "digit" and add them
int sum = hexToDec[left] + hexToDec[right];
// we have a carry from the previous sum
if (carry) { ++sum; }
// translate back to hex, and check if carry
return std::make_pair(decToHex[sum % 16], sum >= 16);
}
int main()
{
std::cout << "Input two hexadecimal numerals(both of them within 100 digits):\n";
// read two strings
std::string first, second;
std::cin >> first >> second;
// reserve enough for final carry
std::string reverse_result(std::max(first.size(), second.size()) + 1, '\0');
// traverse the strings in reverse
std::string::const_reverse_iterator fit = first.rbegin();
std::string::const_reverse_iterator sit = second.rbegin();
std::string::iterator rit = reverse_result.begin();
bool carry = false;
// while there are letters in both inputs, add (with carry) from both
for (; (fit != first.rend()) && (sit != second.rend()); ++fit, ++sit, ++rit)
{
std::tie(*rit, carry) = hex_add(*fit, *sit, carry);
}
// now add the remaining digits of first (will do nothing if second is longer)
for (; (fit != first.rend()); ++fit)
{
// we need to account for a carry in the last place
// potentially all the way up if we are adding e.g. "FFFF" to "1"
std::tie(*rit, carry) = hex_add(*fit, *rit++, carry);
}
// or add the remaining digits of second
for (; (sit != second.rend()); ++sit)
{
// we need to account for a carry in the last place
// potentially all the way up if we are adding e.g. "FFFF" to "1"
std::tie(*rit, carry) = hex_add(*sit, *rit++, carry);
}
// result has been assembled in reverse, so output it reversed
std::cout << reverse_result.reverse();
}
Regarding the text of your problem: “add one to the digit on the left if the sum of the current digits exceed 16” is wrong; it should be 15, not 16.
Regarding your code: I did not have the patience to read all your code, however:
I have noticed one long if/else. Use a switch (but you do not need one).
To find out if a character is a hex digit use isxdigit (#include <cctype>).
The user might input uppercase and lowercase characters: convert them to the same case using toupper/tolower.
To convert a hex digit to an integer:
if the digit is between ‘0’ and ‘9’ simply subtract ‘0’. This works because the codes for ‘0’, ‘1’… are 0x30, 0x31... (google ASCII codes).
if the digit is between ‘A’ and ‘F’, subtract ‘A’ and add 10.
Solving the problem:
“less than 100 digits long” This is a clear indication regarding how your data must be stored: a simple 100 long array, no std::string, no std::vector:
#define MAX_DIGITS 100
typedef int long_hex_t[MAX_DIGITS];
In other words your numbers are 100 digits wide, at most.
Decide how you store the number: least significant digit first or last? I would chose to store the least significant first. 123 is stored as {3,2,1,0,…0}
Use functions to simplify your code. You will need three functions: read, print and add:
int main()
{
long_hex_t a;
read( a );
long_hex_t b;
read( b );
long_hex_t c;
add( c, a, b );
print( c );
return 0;
}
The easiest function to write is add followed by print and read.
For read use get and putback to analyze the input stream: get extracts the next character from stream and putback is inserting it back in stream (if we do not know how to handle it).
Here it is a full solution (try it):
#include <iostream>
#include <cctype>
#define MAX_DIGITS 100
typedef int long_hex_t[MAX_DIGITS];
void add( long_hex_t c, long_hex_t a, long_hex_t b )
{
int carry = 0;
for ( int i = 0; i < MAX_DIGITS; ++i )
{
int t = a[i] + b[i] + carry;
c[i] = t % 16;
carry = t / 16;
}
}
void print( long_hex_t h )
{
//
int i;
// skip leading zeros
for ( i = MAX_DIGITS - 1; i >= 0 && h[i] == 0; --i )
;
// all zero
if ( i < 0 )
{
std::cout << '0';
return;
}
// print remaining digits
for ( i; i >= 0; --i )
std::cout << char( h[i] < 10 ? h[i] + '0' : h[i] - 10 + 'A' );
}
void read( long_hex_t h )
{
// skip ws
std::ws( std::cin );
// skip zeros
{
char c;
while ( std::cin.get( c ) && c == '0' )
;
std::cin.putback( c );
}
//
int count;
{
int i;
for ( i = 0; i < MAX_DIGITS; ++i )
{
char c;
if ( !std::cin.get( c ) )
break;
if ( !std::isxdigit( c ) )
{
std::cin.putback( c );
break;
}
c = std::toupper( c );
h[i] = c <= '9'
? ( c - '0' )
: ( c - 'A' + 10 );
}
count = i;
}
// reverse
for ( int i = 0, ri = count - 1; i < count / 2; ++i, --ri )
{
int t = h[i];
h[i] = h[ri];
h[ri] = t;
}
// fill the rest with zero
for ( int i = count; i < MAX_DIGITS; ++i )
h[i] = 0;
}
int main()
{
long_hex_t a;
read( a );
long_hex_t b;
read( b );
long_hex_t c;
add( c, a, b );
print( c );
return 0;
}
This is a long answer. Because you have much bug in your code. Your using of getline is ok. But your are calling a eof() like e.eof() which is wrong. If you have looked at your compilation error, you would see that it was complaining about calling eof() on the variable e because it is of non-class type. Simple meaning it is not an object of some class. You cannot put the dot operator . on primitive types like that. I think what you are wanting to do, is to terminate the loop when you have reached the end of line. So that index1 and index2 can get the length of the string input. If I were you, I would just use C++ builtin strlen() function for that. And in the first place, you should use C++ class string to handle strings. Also strings have a null - terminating character '\0' at the end of them. If you don't know about it, I suggest you take some time to read about strings.
Secondly, you have many bugs and errors in your code. The way you are reversing your string is not correct. Ask yourself, what are the contents of the arrays a and b at position which have higher index than the length of the string? You should use reverse() for reversing strings and arrays.
You have errors on adding loop also. Note, you are changing the arrays value when they are A, B, C, D, and so on for hexadecimal values with the corresponding decimal values 10,11,12,13 and so on. But you should change the values for the character '0' - '9' also. Because when the array holds '0' it is not integer 0. But is is ASCII '0' which has integer value of 48. And the character '1' has integer value of 49 and so on. You want to replace this values with corresponding integer values also. When you are also storing the result values in c, you are only handling only those values which are above 9 and replacing them with corresponding characters. You should also replace the integers 0 - 9 with there corresponding ASCII characters. Also don't forget to put a null terminating character at the end of the result.
Also, when p is getting larger than 15, you are only changing your carry, but you should also change p accordingly.
I believe you can reverse the result array c in a much more elegant way. By only reversing when the calculation has been performed totally. You can simple call reverse() for that.
I believe you can think hard a little bit more, and write the code in the right way. I have a few suggestions for you, don't use variable names like a,b,c,o. Try to name variables with what are they really doing. Also, you can improve your algorithm and shorten your code and headache with one simple change in the algorithm. First find the length of a and then find the length of b. If there lengths are unequal, find out which has lesser length. Then add 0s in front of it to make both lengths equal. Now, you can simply start from the back, and perform the addition. Also, you should use builtin methods like reverse() , swap() and also string class to make your life easier ;)
#include <iostream>
#include <algorithm>
#include <string>
using namespace std;
int main(){
string firstVal,secondVal;
cout<<"Input two hexadecimal numerals(both of them within 100 digits):\n";
cin >> firstVal >> secondVal;
//Adjust the length.
if(firstVal.size() < secondVal.size()){
//Find out the number of leading zeroes needed
int leading_zeroes = secondVal.size() - firstVal.size();
for(int i = 0; i < leading_zeroes; i++){
firstVal = '0' + firstVal;
}
}
else if(firstVal.size() > secondVal.size()){
int leading_zeroes = firstVal.size() - secondVal.size();
for(int i = 0; i < leading_zeroes; i++){
secondVal = '0' + secondVal;
}
}
// Now, perform addition.
string result;
int digit_a,digit_b,carry=0;
for(int i = firstVal.size()-1; i >= 0; i--){
if(firstVal[i] >= '0' && firstVal[i] <= '9') digit_a = firstVal[i] - '0';
else digit_a = firstVal[i] - 'A' + 10;
if(secondVal[i] >= '0' && secondVal[i] <= '9') digit_b = secondVal[i] - '0';
else digit_b = secondVal[i] - 'A' + 10;
int sum = digit_a + digit_b + carry;
if(sum > 15){
carry = 1;
sum = sum % 16;
}
else{
carry = 0;
}
// Convert sum to char.
char char_sum;
if(sum >= 0 && sum <= 9) char_sum = sum + '0';
else char_sum = sum - 10 + 'A';
//Append to result.
result = result + char_sum;
}
if(carry > 0) result = result + (char)(carry + '0');
//Result is in reverse order.
reverse(result.begin(),result.end());
cout << result << endl;
}

my code doesn't run some thing wrong about strings, c++

I was training on solving algorithms, I wrote a code but it won't compile
in (if) I can not check s[i]=='S' .
I'm trying to if s[i] is S character or not but I don't know where my problem is.
If I can't use this syntax, what could be a solution?
#include<iostream>
#include<string>
using namespace std;
int main()
{
double v_w=25,v_s=25,d_w=25,d_s=25;
int n;
cin>>n;
string s[]={"WSSS"};
int i ;
for (i=0; i<n; i++)
{
if( s[i] == "W" )
{
v_s += 50;
d_w = d_w + (v_w/2);
d_s = d_s + (v_s/2);
cout<<"1 \n";
}
if(s[i]=='W')
{
v_w +=50;
d_w = d_w + (v_w/2);
d_s = d_s + (v_s/2);
cout<<"2 \n";
}
return 0;
}
cout<< d_w<<endl<<d_s;
}
string s[]={"WSSS"}; means an array of strings which the first one is "WSSS".
What you need is:
std::string s="WSSS";
string s[] = {"Hello"} is an array of strings (well, of one string).
If you iterate over it, or index into it s[0] is "Hello".
Whereas
string s{"Hello"} is one string, which is made up of characters.
If you iterate over it, or index into it s[0], you will get 'H'.
To pre-empt all the other things that are going to go wrong when the string versus character problem is sorted, lets move the return 0; from the middle of the for loop.
Then let's think about what happens if the number n entered is larger than the length of the string:
int n;
cin>>n; //<- no reason to assume this will be s.length (0 or less) or even positive
string s{"WSSS"}; //one string is probably enough
int i ;
for(i=0;i<n;i++)
{
if( s[i] == 'W' ) //ARGGGGGGG may have gone beyond the end of s
{
In fact, let's just drop that for now and come back to it later. And let's use a range based for loop...
#include<iostream>
#include<string>
using namespace std;
int main()
{
double v_w = 25, v_s = 25, d_w = 25, d_s = 25;
string s{ "WSSS" };
for (auto && c : s)
{
if (c == 'W')
{
v_w += 50;
d_w = d_w + (v_w / 2);
d_s = d_s + (v_s / 2);
cout << "2 \n";
}
}
cout << d_w << '\n' << d_s << '\n'; //<- removed endl just because...
return 0;
}
s is an array of strings in this case it has only element:
string s[] = {"WSSS"};
so writing s[2]; // is Undefined behavior
your code will produce a UB if the user enters n greater than the number of elements in s:
n = 4;
for(i = 0; i < n; i++) // s[3] will be used which causes UB
{
if( s[i] == 'W' ) // s[i] is a string not just a single char
{
}
}
also as long as s is an array of strings then to check its elements check them as strings not just single chars:
if( s[i] == "W" ) // not if( s[i] == 'W' )
I think you wanted a single string:
string s = {"WSSS"};
because maybe you are accustomed to add the subscript operator to character strings:
char s[] = {"WSSS"};
if so then the condition above is correct:
if( s[i] == 'W' )

How does strings comparison in C++ work?

I am trying to solve this problem.
I am implementing it with strings. Here is my code snippet
string s,ss;
// s and ss both contains integer input.
while(s <= ss )
//while( s<=ss && s.size() <= ss.size())
{
int i = inc, j = dec; // inc and dec are middle values. both equal if odd else different
while((s[j]-'0')==9 && i < len && j>=0){
// for cases like 999
s[i] = s[j] = '0';
i++;
j--;
}
if(j<0){
s = "1" + s;
int l = s[len-1] - '0';
l++;
//cout<<l<<"\n";
s[len] = (l + '0');
}
else{
int l = s[j] - '0';
l++;
s[i] = s[j] = (l+'0');
}
if(s <= ss)
cout<<"out in wild "<<s<<" and "<<ss<<"\n";
}
cout<<s<<endl;
The problem that I am facing is when input is like 999 or 9999. The outer while loop keeps on looping even when the value of s increases, but if I add while( s<=ss && s.size() <= ss.size()) it works completely fine. Why is while(s<=ss) is not working? I rarely use the string class, so I don't understand it completely. Why don't string s= 101 and ss=99 stop the while loop?
Complete code link is here
You are comparing strings with lexicographical order, not numbers , so "101" is less than "99" (because '1' < '9') , e.g.
int main(){
std::string s = "99";
std::string ss = "101";
std::cout << std::boolalpha << (s <= ss);
}
Outputs false.
Notes:
A better design for your program would be to manipulate numbers (int or double ...) and not strings in the first place, so this kind of expressions would naturally work as you expect.
E.g. "101" + "99" is "10199", not "200" ...
But if you really need strings, consider this post to sort strings containing numbers.
As pointed by #Deduplicator, a program that needlessly overuses strings is sometimes called Stringly Typed
Also see std::lexicographical_compare
Since your input explicitly only involves positive integers without leading 0, writing a comparison function is trivial, something like : (untested)
/* Returns 1 if the integer represented by s1 > the integer represented by s2
* Returns -1 if the integer represented by s1 < the integer represented by s2
* Return 0 is both are equals
*
* s1 and s2 must be strings representing positive integers without trailing 0
*/
int compare(const std::string& s1, const std::string& s2)
{
if(s1.size() > s2.size())
return 1;
if(s2.size() > s1.size())
return -1;
for(std::size_t i = 0 ; i < s1.size() ; ++i)
{
if(s1[i] - '0' < s2[i] - '0')
return 1;
if(s2[i] - '0' < s1[i] - '0')
return -1;
}
return 0;
}
While s and ss are string variables, they are compared character by character.
In the case that you mentioned being: s = "101" & ss = "99", by first hand it will check the first character in each string, and as '1' < '9' it exit up with s < ss. I would advise you to convert those values to integers before comparison.
As the s is compared with ss in lexicographical order, I would suggest you to compare one char from tail with one char from head (one by one till you reach the middle) to solve that problem.