How to find a particular value from a string in C++ - c++

I have this string "67030416680001337D4912601000000000000"
I want to take value before letter "D".
also want value 4 digits only after "D".
I have tried using:
string sPanNo = sTrkData.substr(0,17);
string sExpDate = sTrkData.substr(18, 4);
but problem is string before letter "D" will vary in length.

You can use string::find_first_of(), something like:
string::size_type dPos = sTrkData.find_first_of('D');
if (dPos != string::npos) {
string sPanNo = sTrkData.substr(0, dPos);
string sExpDate = sTrkData.substr(dPos + 1, 4);
}

You have to use member function find
For example
std::string::size_type n = sTrkData.find( 'D' );
string sPanNo = sTrkData.substr( 0, n );
string sExpDate;
if ( n != std::string::npos ) sExpDate = sTrkData.substr( n + 1, 4 );

You can use a regular expression to validate your input and extract the desired data in one step:
#include <iostream>
#include <regex>
#include <string>
int main() {
using namespace std;
string input("67030416680001337D4912601000000000000");
regex re("(\\d+)D(\\d{4})\\d+");
match_results<string::const_iterator> m;
if (regex_match(input, m, re)) {
cout << m[1].str() << endl;
cout << m[2].str() << endl;
} else {
cout << "invalid input\n";
}
}

or use <regex> C++ 11
#include <iostream>
#include <regex>
#include <string>
using namespace std;
std::regex base_regex ( "(\\d+)D(\\d{4})\\d+" );
std::smatch base_match;
string numberstring = "67030416680001337D4912601000000000000";
if (std::regex_match(numberstring, base_match, base_regex))
{
std::ssub_match base_sub_match = base_match[1];
std::string number1 = base_sub_match.str();
base_sub_match = base_match[2];
std::string number2 = base_sub_match.str();
cout << number1 << endl;
cout << number2 << endl;
}

Related

Function find() works incorrect

My task is to check if a number contains 8 or not. I've converted the number into a std::string and have used its find() method. But it only works with a number which starts with 8, for example 8, 81, 881, etc. For numbers like 18, 28, etc, it doesn't work.
#include <iostream>
#include <math.h>
#include <string>
using namespace std;
unsigned long long g = 0;
int main()
{
string str;
cin >> str;
int f = stoi(str);
string eig = "8";
for (int a = 1; a <= f; a++)
{
string b = to_string(a);
if (b.find(eig) != size_t() && b.rfind(eig) != size_t())
{
cout << "It worked with " << b << "\n";
g++;
}
}
cout << g;
}
You are using std::string::find() and std::string::rfind() incorrectly. They do not return size_t() if a match is not found. They return std::string::npos (ie size_type(-1)) instead. size_t() has a value of 0, so find(...) != size_t() will evaluate as true if no match is found at all (-1 != 0), or any character other than the first character is matched (>0 != 0). This is not what you want.
Also, your use of rfind() is redundant, since if find() finds a match then rfind() is guaranteed to also find a match (though just not necessarily the same match, but you are not attempting to differentiate that).
Try this:
#include <iostream>
#include <string>
using namespace std;
unsigned long long g = 0;
int main()
{
int f;
cin >> f;
for (int a = 1; a <= f; a++)
{
string b = to_string(a);
if (b.find('8') != string::npos)
{
cout << "It worked with " << b << "\n";
++g;
}
}
cout << g;
}
#include <iostream>
#include <string>
#include <cassert>
int main(int argc, char **argv) {
auto s = std::to_string(1234567890);
assert(s.find('8') != std::string::npos);
return 0;
}
Is this what you want?

Defining a string in an if statement

Im trying to make a number that is positive (already converted into a string) look like "+number" instead of "number" but i can't define it in an if
#include <iostream>
#include <string>
int main()
{
std::string x3s;
int number = 145;
if (number >= 0)
{
x3s = "+" + number;
}
std::cout << x3s << std::endl;
}
Firstly, there is an I/O manipulator std::showpos.
#include <iostream>
int main()
{
int number = 145;
std::cout << std::showpos << number << std::endl;
}
Secondly, you are using the verb "define" incorrectly.
You can use x3s = std::string("+") + std::to_string(number);

I wonder how to separate all the numerical values from a string without any space just like 123we45rt75

I read many functions online but they just solve that problem with spaces in strings.so how can I get out all the numerical values from a letter and number
sequence.
May be this could help you:
#include <iostream>
#include <string>
using namespace std;
int main()
{
string oldStr = "123we45rt75";
string newStr = "";
for(int i = 0; i < oldStr.length(); i++)
{
char val = oldStr[i];
if( (val <= 90 && val >= 65) || (val <= 122 && val >= 97) )
newStr += val;
}
cout <<"Old String: " << oldStr <<"\nNew String: " << newStr << endl;
return 0;
}
You can achieve this using the erase/remove idiom:
#include <algorithm>
#include <iostream>
#include <string>
int main()
{
std::string input = "123we45rt75";
input.erase(
std::remove_if(input.begin(), input.end(), [](const char c) { return (0 == std::isdigit(c)); }),
input.end());
std::cout << input << std::endl;
return 0;
}
std::remove_if() combined with std::isdigit() will let you find all the non-numeric characters. input.erase() will then remove the found characters from the string.

I would like to count the numbers in a string /c++

I have tried to count the numbers in a string but it doesnt work and I think it is logically good. I am a beginner in programming.
I know it works for one-digit numbers but that's intentional.
#include <iostream>
#include <string.h>
#include <vector>
using namespace std;
int main()
{
int numbs [10] = {0,1,2,3,4,5,6,7,8,9};
string str1;
cin >> str1;
vector <unsigned int> positions;
for (int a = 0 ;a <=10;a++)
{
int f = numbs[a];
string b = to_string(f);
unsigned pos = str1.find(b,0);
while(pos !=string::npos)
{
positions.push_back(pos);
pos = str1.find(b,pos+1);
break;
}
}
cout << "The count of numbers:" << positions.size() <<endl;
return 0;
}
If you need only to count digits in a string then there is no sense to use std::vector. You can count them without the vector. For example
#include <iostream>
#include <string>
int main()
{
std::string s( "A12B345C789" );
size_t count = 0;
for ( std::string::size_type pos = 0;
( pos = s.find_first_of( "0123456789", pos ) ) != std::string::npos;
++pos )
{
++count;
}
std::cout << "The count of numbers: " << count << std::endl;
return 0;
}
The output is
The count of numbers: 8
Also you could use standard algorithm std::count_if defined in header <algorithm>
For example
#include <iostream>
#include <string>
#include <algorithm>
#include <cctype>
int main()
{
std::string s( "A12B345C789" );
size_t count = std::count_if( s.begin(), s.end(),
[]( char c ) { return std::isdigit( c ); } );
std::cout << "The count of numbers: " << count << std::endl;
return 0;
}
The output is
The count of numbers: 8
If you need to count numbers instead of digits in a string then you should use standard C function strtol or C++ function std::stoi
Use substrings to extract every part of string with a delimiter(normally a space). Then convert each substring to number. The ones that qualify and converts probably are the numbers in your string. See how many you get.
You might also be interested in the C++ function "isdigit":
http://www.cplusplus.com/reference/locale/isdigit/
For example:
include <iostream>
#include <string.h>
#include <vector>
#include <locale> // std::locale, std::isdigit
using namespace std;
int main()
{
// Initialze array with count for each digit, 0 .. 9
int counts[10] = {0, 0, 0, 0, 0, 0, 0,0, 0, 0 };
int total = 0;
// Read input string
string str;
cin >> str;
// Parse each character in the string.
std::locale loc;
for (int i=0; i < str.length(); i++) {
if isdigit (str[i], loc) {
int idx = (int)str[i];
counts[idx]++
total++;
}
// Print results
cout << "The #/digits found in << str << " is:" << total << endl;
// If you wanted, you could also print the total for each digit ...
return 0;
}

extracting last 2 words from a sequence of strings, space-separated

I have any sequence (or sentence) and i want to extract the last 2 strings.
For example,
sdfsdfds sdfs dfsd fgsd 3 dsfds should produce: 3 dsfds
sdfsd (dfgdg)gfdg fg 6 gg should produce: 6 gg
You can use std::string::find_last_of function to find spaces.
int main()
{
std::string test = "sdfsdfds sdfs dfsd fgsd 3 dsfds";
size_t found1 = test.find_last_of( " " );
if ( found1 != string::npos ) {
size_t found2 = test.find_last_of( " ", found1-1 );
if ( found2 != string::npos )
std::cout << test.substr(found2+1, found1-found2-1) << std::endl;
std::cout << test.substr(found1+1) << std::endl;
}
return 0;
}
The following will work if your strings are whitespace separated.
#include <iostream>
#include <string>
#include <sstream>
#include <vector>
using namespace std;
int main()
{
string str = "jfdf fhfeif shfowejef dhfojfe";
stringstream sstr(str);
vector<string> vstr;
while(sstr >> str)
{
vstr.push_back(str);
}
if (vstr.size() >= 2)
cout << vstr[vstr.size()-2] << ' ';
if (vstr.size())
cout << vstr[vstr.size()-1] << endl;
return 0;
}
Returns the strings in the wrong order, but if that doesn't matter,
std::string s ("some words here");
std::string::size_type j;
for(int i=0; i<2; ++i) {
if((j = s.find_last_of(' ')) == std::string::npos) {
// there aren't two strings, throw, return, or do something else
return 0;
}
std::cout << s.c_str()+j+1;
s = " " + s.substr(0,j);
}
Alternatively,
struct extract_two_words {
friend std::istream& operator>> (std::istream& in , extract_two_words& etw);
std::string word1;
std::string word2;
};
std::istream& operator>> (std::istream& in , extract_two_words& etw) {
std::string str1, str2;
while(in) {
in >> str1;
in >> str2;
}
etw.word2 = str1;
etw.word1 = str2;
}
I would encourage you to have a look at the Boost library. It has algorithms and data structures that help you tremendously. Here's how to solve your problem using Boost.StringAlgo:
#include <boost/algorithm/string/split.hpp>
#include <iostream>
#include <vector>
#include <string>
int main()
{
std::string test = "sdfsdfds sdfs dfsd fgsd 3 dsfds";
std::vector<std::string> v;
boost::algorithm::split(v, test, [](char c) { return c==' ';});
std::cout << "Second to last: " << v.at(v.size()-2) << std::endl;
std::cout << "Last: " << v.at(v.size()-1) << std::endl;
}
I would also encourage you to always use the vector::at method instead of []. This will give you proper error handling.
int main()
{
std::string test = "sdfsdfds sdfs dfsd fgsd 3 dsfds";
size_t pos = test.length();
for (int i=0; i < 2; i++)
pos = test.find_last_of(" ", pos-1);
std::cout << test.substr(pos+1) << std::endl;
}
Simpler :)