How to convert string like 3 word 12 with word to a int only contain number 312 without using stoi in C++? My Codeblode gave me an error stoi is not a member of std when I tried to use it.
Thank you in advance!
Go through the line and skip non-digit symbols. And for digits use -'0' conversion and *10 shift approach. E.G.:
#include <stdio.h>
#include <ctype.h>
//or cctype to use isdigit()
#include <string.h>
//or cstring to use strlen()
int main()
{
char str[] = "3 word 12 with word"; // can be any string
int result = 0; // to store resulting number
// begin of solution
for (int i = 0; i < strlen(str); i++)
{
if (isdigit(str[i]))
{
result *= 10;
result += str[i] - int('0');
}
}
// end of solution
printf("%d\n", result);
return 0;
}
Same idea as in VolAnd's answer. Just, because the question is tagged c++, using some STL stuff.
#include <iostream>
#include <numeric>
#include <string>
using namespace std;
int main(){
std::string input("3 word 12 with word");
int num = std::accumulate(input.begin(), input.end(), 0,
[](int val, const char elem) {
if (isdigit(elem)) {
val = val*10 + (elem-'0');
}
return val;
}
);
std::cout << num << std::endl;
return 0;
}
see http://en.cppreference.com/w/cpp/algorithm/accumulate
note: It gets slightly more interesting if you want to allow a leading minus sign....
And using boost::adaptors::filter(rng, pred) on this one would be fun but slightly overdoing it ;-)
Assuming that s is your initial string.
int toInt(string s) {
string digits;
for(size_t i = 0; i < s.size(); i++)
if(s[i] >= '0' && s[i] <= '9')
digits.push_back(s[i]);
int res = 0;
for(size_t i = 0; i < digits.size(); i++)
res = res * 10 + digits[i] - '0';
return res;
}
Leading zeros are not a problem.
Note however that it is possible to receive an overflow if the resulting digits string will contain a big number.
Related
When I try to compile my code this error pops out:
invalid conversion from 'int' to 'const char*'
My task is to write a program that calculates the sum of numbers with odd index.
Please don't roast me (I'm learning how to code in c++), and give some tips how to fix it and get my code working.
#include <bits/stdc++.h>
#include <cmath>
#include <string>
#include <iostream>
using namespace std;
int main()
{
string text;
cin >> text;
int len = text.length(), sum = 0, number = 0, a = 0;
for (int i = len; i > 0; i++) {
a = text[i];
if (i % 2 == 1) {
number = atoi(a);
sum = sum + number;
}
}
cout << sum;
return 0;
}
Your for loop is incorrect because at the first try it starts at out of range index and increases farther. here :
#include <iostream>
using namespace std;
int main()
{
string text;
cin >> text;
int len = text.length(), sum = 0, number = 0, a = 0;
for (int i = 0; i < len; i++) {
a = text[i];
if (i % 2 == 1) {
number = a - '0';
sum = sum + number;
}
}
cout << sum;
return 0;
}
atoi is a function for converting a string to an integer, but a is a character not a string. That's why you have the error.
Replace atoi(a); with a - '0'. That's a formula for converting a digit character to its integer value.
I see a few issues. The most obvious:
number = atoi(a);
atoi expects a const char *, but a is an int.
Note that it would help if you listed which line produces the error message.
Without trying it, I think you can get rid of the atoi() and just do:
sum += a - '0';
The other choice would be to make a into a string and use text.subst() to just get a single character, then you could do:
sum += atoi (a.c_str());
or
sum += stoi(a);
In programming, there are always a dozen of ways to do the same thing.
Learn to extract functions. This will do your task without converting to string.
int sumOfDigitsInEvenPos(int x, int base = 10) {
x = std::abs(x);
int sum = 0;
while (x) {
sum += x % base;
x /= base * base;
}
return sum;
}
There are more than few mistakes :
starting with declaring 'a' as int.
in Your for loop you are starting with length which should be
length-1.
In for loop again you are using i++ which should be i-- or start with i=0;
When you are getting number why you are taking string as input
taking as int/long should be more convient.
atoi accepts char * not int
try out below code it should solve your problem
#include <bits/stdc++.h>
#include <cmath>
#include <string>
#include <iostream>
using namespace std;
int main()
{
string text;
cin>>text;
int len= text.length();
cout<<len<<endl;
int sum=0,number=0;
char a;
for(int i=len-1;i>0;i--)
{
a=text[i];
if(i%2==1)
{ number= (int)a;
sum = sum+number;
}
}
cout<<sum;
return 0;
}
I think you need to check return code of atoi function, because string consists non only of numeric values.
And length returns size of string, for example 5, but symbols iterates from 0 to 4. text[4] - final symbol.
Hi I'm really new to c++ and I wanted to write a code which receives a number from user and sums its digits and keeps doing that until it gets a one-digit number and returns it as a result. But I noticed that when my number is large (like 15 digits long), the wrong number is stored in the variable i declared for storing user input. What do I do?
#include <iostream>
#include <string>
#include <sstream>
using namespace std;
int get_sum(long x) {
cout << x<<endl;
if (x < 10) {
return x;
}
else {
string num_in_str = to_string(x);
long result=0;
for (int i = 0; i < num_in_str.size(); i++) {
int digit = num_in_str[i] - '0';
result += digit;
}
return get_sum(result);
}
}
int main()
{
long input;
cin >> input;
int final_result = get_sum(input);``
cout << final_result;
}
Oh I found out. I had to use uint64_t data type
Integer data types in C++ can store numbers up to certain limit. In particular, depending on platform and compiler, "long" can be 32 or 64 bit, and store up to 2^31-1 or 2^63-1. If you want to process numbers of an arbitrary precision, I'd suggest to read each input as string, and process it character-by character, like this:
#include <cctype>
#include <iostream>
#include <string>
int main()
{
std::string s;
while (std::getline(std::cin, s)) {
// parse string
long sum = 0;
for (std::size_t i = 0; i < s.length(); ++i) {
if (std::isdigit(s[i]))
sum += s[i] - '0';
else
break;
}
std::cout << sum << std::endl;
if (sum < 10) break;
}
return 0;
}
This function is meant to remove all special characters, numbers, and whitespace from the char array.
// Michael E. Torres II
// Vigenere Cipher
// February 4, 2018
// C++ code to implement Vigenere Cipher
#include <iostream>
#include <string>
#include <iomanip>
#include <fstream>
#include <algorithm>
#include <cctype>
#include <iterator>
#include <sstream>
#include <functional>
using namespace std;
// This function generates the key in
// a cyclic manner until it's length isi'nt
// equal to the length of original text
string generateKey(string str, string key)
{
int x = str.size();
for (int i = 0; ; i++)
{
if (x == i)
i = 0;
if (key.size() == str.size())
break;
key.push_back(key[i]);
}
return key;
}
// This function returns the encrypted text
// generated with the help of the key
string cipherText(string str, string key)
{
string cipher_text;
for (int i = 0; i < str.size(); i++)
{
// converting in range 0-25
int x = (str[i] + key[i]) % 26;
// convert into alphabets(ASCII)
x += 'A';
cipher_text.push_back(x);
}
return cipher_text;
}
// This function decrypts the encrypted text
// and returns the original text
string originalText(string cipher_text, string key)
{
string orig_text;
for (int i = 0; i < cipher_text.size(); i++)
{
// converting in range 0-25
int x = (cipher_text[i] - key[i] + 26) % 26;
// convert into alphabets(ASCII)
x += 'A';
orig_text.push_back(x);
transform(orig_text.begin(), orig_text.end(), orig_text.begin(), ::tolower);
}
return orig_text;
}
string removeNonAlpha(char *str)
{
unsigned long i = 0;
unsigned long j = 0;
char c;
while ((c = str[i++]) != '\0')
{
if (isalpha(c)) // this is where the breakpoint is automatically placed
{
str[j++] = c;
}
}
str[j] = '\0';
return str;
}
// Driver program to test the above function
int main(int argc, char *argv[])
{
string keyword = "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb";
stringstream ss;
char a[] = "“I think and think for months and years. Ninety-nine times, the conclusion is false. The hundredth time I am right.” – Albert Einstein “Imagination is more important than knowledge. For knowledge is limited, whereas imagination embraces the entire world, stimulating progress, giving birth to evolution.” – Albert Einstein";
int i = 0;
string str = removeNonAlpha(a);
str.append(512 - str.length(), 'X');
transform(str.begin(), str.end(), str.begin(), ::toupper);
transform(keyword.begin(), keyword.end(), keyword.begin(), ::toupper);
string key = generateKey(str, keyword);
string cipher_text = cipherText(str, key);
transform(cipher_text.begin(), cipher_text.end(), cipher_text.begin(), ::tolower);
transform(key.begin(), key.end(), key.begin(), ::tolower);
string orig = originalText(cipher_text, key);
cout << "Original/Decrypted Text : " << "\n";
for (int i = 0; i < orig.size(); i += 81)
orig.insert(i, "\n");
cout << orig;
cout << "\n\n" << "Ciphertext : " << "\n";
for (int i = 0; i < cipher_text.size(); i += 81)
cipher_text.insert(i, "\n");
cout << cipher_text;
cout << "\n\nPress ENTER key to Continue\n";
getchar();
return 0;
}
The char array works fine with this while loop, so long as there are no special characters [.,%$#!^]. As soon as there are any special characters in the char array, it gives me the debug assertion:
"Program: ...\Projects\ConsoleApplication17\Debug\ConsoleApplication17.exe
File: minkernel\crts\ucrt\src\appcrt\convert\isctype.cpp
Line: 42
Expression: c >= -1 && c <= 255
...
The program '[11048] ConsoleApplication17.exe' has exited with code 3 (0x3)."
If I run this on repl.it or cpp.sh, I get no issues though. I appreciate any help. Thank you.
It isn't done at all. It needs to be cleaned up a lot, but I'm just trying to test it as is.
see https://msdn.microsoft.com/en-us/library/xt82b8z8.aspx
isalpha expects a number between 0 and 0xFF:
The behavior of isalpha and _isalpha_l is undefined if c is not EOF or
in the range 0 through 0xFF, inclusive. When a debug CRT library is
used and c is not one of these values, the functions raise an
assertion.
You need to cast you char to an unsigned char before passing to isalpha.
I am writing up a function that reverses the order of the string "rdd" to "ddr",
when I run it I get an error that substring is out of range. Any help is appreciated!
#include <iostream>
#include <string>
#include <stdio.h>
#include <ctype.h>
using namespace std;
string reverse(const string & s);
int main() {
cout << reverse("rdd") << endl;
}
string reverse(const string & s) {
string rname(s);
for (unsigned i = rname.size()-1; i >= 0; i--) {
cout << rname[i];
}
return rname;
}
This is problem:
for (unsigned i = rname.size()-1; i >= 0; i--) {
Since i is unsigned, i-- will take it from 0 to UINT_MAX. The test i >= 0 can never fail for unsigned int. After this happens you access out of bounds in the loop body.
Instead the loop could look like:
for (unsigned i = rname.size(); i --> 0; )
(using the --> operator), or a better option would be to use C++ idioms:
for (auto it = rname.rbegin(); it != rname.rend(); ++it)
cout << *it;
Also see reverse adapters although that might be overkill for this case.
Your i is unsigned, therefore the condition i >= 0 is always satisfied. Consider:
unsigned int i = 0;
i--; // i will undeflow, and assume the largest unsigned number possible
if(i < 0) printf("Works?"); // suprise! It will be false and printf does not fire!
for (unsigned i = rname.size()-1; i >= 0; i--) {
The problem is in the above statement because -
rname.size() will return length of string. So this loop will run from rname.size()-1to 0(both including) then i-- will be UINT_MAX and condition which is i>=0, will always be true but your string size may less than UINT_MAX so it will return an error which is out of bound error.
One of our assignments in working with C++ in 1st year programming was to write a function that can check if a number is palindromic or not (e.g 16461). I'd upload my code but I don't even know where to begin when it comes to extracting digits from an integer or checking the number of digits in an integer. Any help or hints would be appreciated!
There are many ways to solve this. I like most the solution that builds the mirror number and checks whether it is identical to the original (even though, it is arguably not the most efficient way). The code should be something like:
bool isPalindrom(int n) {
int original = n;
int mirror = 0;
while (n) {
mirror = mirror * 10 + n % 10;
n /= 10;
}
return mirror == original;
}
You can use modulo arithmetic (% operator) to extract individual digits. An alternative would be to get the string representation of your number and work with that.
Hints:
"Number of digits" is a tricky thing to define, since you can always add 0's on the left-hand side and still have the same number. Read carefully and think carefully about how you want to define this.
The digits of an integer are associated with powers of 10 (recall 123 = 1*100 + 2*10 + 3*1), so to extract digits you need to be extracting powers of 10. The key operations are remainder and truncated division. What happens if you do (123 % 10)? How about (123 / 10)? How about ((123 / 10) % 10)?
Best convert the integer into a string first. Testing a string if it is a palindrome is much easier.
#include <sstream>
#include <iostream>
#include <string>
bool isPalindrome(int value)
{
// convert integer into text
std::ostringstream oss;
oss << value;
std::string valueText = oss.str();
if (valueText.size()%2==0) {
return false;
}
for (int i = 0; i < (valueText.size()/2); ++i) {
if (valueText[i]!=valueText[valueText.size()-i-1]) {
return false;
}
}
return true;
}
int main()
{
for (int i = 0; i < 100000; ++i) {
if (isPalindrome(i)) {
std::cout << i << std::endl;
}
}
return 0;
}
First convert the integer into a std::string:
std::ostringstream oss;
oss << value;
std::string valueText = oss.str();
Now check if the string has a odd number of digits:
if (valueText.size()%2==0) {
return false;
}
If the string has a odd number of digits, test if the digits match:
for (int i = 0; i < (valueText.size()/2); ++i) {
if (valueText[i]!=valueText[valueText.size()-i-1]) {
return false;
}
}
Here's a solution that converts the integer to a C-style string and go from there.
#include <iostream>
#include <stdio.h>
#include <string.h>
using namespace std;
bool isPalindrome(int n) {
char s[256];
sprintf(s, "%d", n);
char *p = s, *q = &s[strlen(s) - 1];
while (*p == *q && p++ < q--)
;
return (p == q) || (*p == *q);
}
int main() {
int n = 1644451;
cout << isPalindrome(n) << endl;
return 0;
}
If performance is not an issue, and if you can do c++11, an easy to read solution :
template<class T>
bool isPalindrome(T i)
{
auto s = std::to_string(i);
auto s2 = s;
std::reverse(s.begin(), s.end());
return s == s2;
}
which is of course much slower than manually going through the digits, but imho is very readable...
call it with:
std::cout << isPalindrome<int>(12321);
std::cout << isPalindrome<int>(1232);