How to extract integers from array of strings in C++ - c++

Given an array of the form
char* timePeriod= {"6AM#8AM","11AM#1PM","7AM#3PM","7AM#10AM","10AM#12PM"};
how can I extract the start and end time in integer arrays of following form:
start_time={6,11,7,7,10}
end_time={8,1,3,10,12}

You can use "sscanf" to do so. And don't forget to mark it as useful :)
#include <stdio.h>
int main()
{
int a,b,i;
int start_time[5], end_time[5];
char *t[5] = {"6AM#8AM","11AM#1PM","7AM#3PM","7AM#10AM","10AM#12PM"};
char *(*ptr)[5] = &t;
for(i=0;i<5;i++)
{
sscanf((*ptr)[i], "%d%*[AP]M#%d%*[AP]M", &a, &b);
start_time[i]=a;
end_time[i]=b;
}
printf("Starting time : ");
for(i=0;i<5;i++)
{
printf("%d ",start_time[i]);
}
printf("\nEnding time : ");
for(i=0;i<5;i++)
{
printf("%d ",end_time[i]);
}
return 0;
}
OUTPUT:
Starting time : 6 11 7 7 10
Ending time : 8 1 3 10 12

A pretty simple way would be to use strtok to split the string on the #, then use atoi on each piece. It will stop once it sees a non-numeric value.

sscanf is capable of doing this, although I don't think it's a very good way. look at here for details
#include <stdio.h>
int main() {
const char* t = "6PM#8AM";
int a, b;
sscanf(t, "%d%*[AP]M#%d%*[AP]M", &a, &b);
printf("%d %d\n", a, b);
return 0;
}
or you can regex in C++11
#include <iostream>
#include <regex>
#include <string>
using namespace std;
int main() {
string t("6PM#8AM");
smatch match;
regex re("([[:digit:]])+[AP]M#([[:digit:]])+[AP]M");
if (regex_match(t, match, re)) {
cout << match[1].str() << " " << match[2].str() << '\n';
}
return 0;
}

Note: the following solution makes a few very specific assumptions about your dataset (if these are not the case, you may prefer using a regex).
The string will always start with integers
The endtimes will always either be in the 4th or 5th index of your string
Zero is not a valid time
#include <iostream>
#include <string>
int main() {
std::string timePeriod[5] = {"6AM#8AM","11AM#1PM","7AM#3PM","7AM#10AM","10AM#12PM"};
int startTimes[5] = {0,0,0,0,0};
int endTimes[5] = {0,0,0,0,0};
for(int i=0;i<5;i++) {
std::string s = timePeriod[i];
startTimes[i] = atoi(s.c_str()); // Convert first number to integer
endTimes[i] = atoi(s.substr(4).c_str()); // Convert 2nd numbers to integer
if(endTimes[i] == 0) // If zero
endTimes[i] = atoi(s.substr(5).c_str()); // Get the 5th index instead
std::cout << "Start: " << startTimes[i] << "\t End: " << endTimes[i] << std::endl;
}
}
The lack of leading zeros makes it a bit trickier, but ultimately - it can be quickly solved using substrings (assuming also you don't mind changing the char* into a std::string).

Related

Array print function

I am trying to create a function that prints the elements of an array. I set it up so it calculates the size of the array, but I cannot figure why it doesn't work. Can you give me some suggestions?
Thanks!
#include <iostream>
#include <string>
using namespace std;
void print_array(string s){
for(int i = 0; i < ( sizeof(s) / sizeof(s[0]) ); i++){
cout << s[i] << "\n";
}
}
int main()
{
string names[5] = {"Dante", "Greg", "Bob", "Victor", "Saber"};
print_array(names);
}
Welcome to Stack Overflow! Be aware that there are many questions similar to this that have received answers.
As mentioned in a comment, you would need to specify the size of the array if you plan on passing it into a function, because the compiler will look at it not as an array of strings (string s[]), but as a pointer to strings (string s*). Thus, you would need to modify it a little like so:
#include <iostream>
#include <string>
using namespace std;
void print_array(string s[], int size){
for(int i = 0; i < size; i++)
{
cout << s[i] << "\n";
}
}
int main()
{
string names[5] = {"Dante", "Greg", "Bob", "Victor", "Saber"};
print_array(names, sizeof(names) / sizeof(names[0]));
}
You are passing a string instead of an array of strings. You could modify your code by using vectors like this:
void print_array(const std::vector<std::string> &vector){
for (const auto &string : vector) {
std::cout << string << "\n";
}
}
int main()
{
std::vector<std::string> names = {"Dante", "Greg", "Bob", "Victor", "Saber"};
print_array(names);
}
Using vectors allows you to use auto generated for loops, wich are easy to read and use.

A function to find how many times string 1 contains string 2 c++

I want to check how many times my first string contains the second string.
I read about it in the internet, and i found a function name std::find, i tried to use it and i failed...
std::string Str1 = "Hello Hello";
std::string Str2 = "ll";
Now what?
I tried to use
std::count
as well but i found out that its work just on a letters.
counter = std::count(Str1.begin(), Str2.end(), Str2); // dident work
Help??
Edit:
Thats what i am trying to do:
unsigned int Nucleus::get_num_of_codon_appearances(const std::string& codon) const
{
unsigned int counter = 0;
counter = std::count(this->_DNA_strand.begin(), this->_DNA_strand.end(), codon);
return counter;
}
You could do this quite easily with std::regex if you are using c++11 or greater.
Something like,
#include <regex>
#include <iterator>
#include <iostream>
#include <string>
using namespace std;
int main()
{
const string str = "one two hello three four hello five hello";
regex re("hello");
cout << "Number of hellos : " <<
distance(sregex_iterator(str.begin(),str.end(), re),sregex_iterator());
}
Demo
You can use std::string::find.
#include <string>
using namespace std;
size_t count (const string & src, const string & str) {
size_t cnt = 0, fnd = 0;
while (fnd = (src.find(str, fnd)) != string::npos) {
cnt++; fnd++;
}
return cnt;
}
...
count("Hello, world!", "ll");
As paxbun stated the string::find method is used there and that is a built-in function of the string class.
Reference of the .find() Method string::find ~ C++ Reference
As another approach including a class corresponding to your code above:
#include <iostream>
#include <string>
using namespace std;
//class declaration
class Nucleus{
private:
string _DNA_strand{"ABCADDASDASABCAFGDACCACABCDA"};
public:
const string get_codon(){return _DNA_strand;} //accessor of private variable
unsigned int get_num_of_codon_appearances(const string& _DNA_strand, const string& ) const;
};
//Function to return the number of times a string is found within another string.
unsigned int Nucleus::get_num_of_codon_appearances(const string& codon, const string& c) const
{
unsigned int count = 0; //sets count
size_t counter = 0; //sets counter
while (counter != string::npos) // if counter does not equal string no position
{
size_t i = counter + c.length(); // sets i to counter + length of searched for object
counter = codon.find(c, i); // .find() method
count++;
}
return count;
}
//Main Function
int main()
{
Nucleus temp; //sets the object temp of the class Nucleus
const string codon = temp.get_codon();
const string c = "ABC";
cout << "The Number of times " << c << " is found in "
<< temp.get_codon() << " is: " << temp.get_num_of_codon_appearances(codon, c) << endl;
return 0;
}
Example output:
The Number of times ABC is found in ABCADDASDASABCAFGDACCACABCDA is: 3
DEMO

Insert characters between a string

I am faced with a simple yet complex challenge today.
In my program, I wish to insert a - character every three characters of a string. How would this be accomplished? Thank you for your help.
#include <iostream>
int main()
{
std::string s = "thisisateststring";
// Desired output: thi-sis-ate-sts-tri-ng
std::cout << s << std::endl;
return 0;
}
There is no need to "build a new string".
Loop a position iteration, starting at 3, incrementing by 4 with each pass, inserting a - at the position indicated. Stop when the next insertion point would breach the string (which has been growing by one with each pass, thus the need for the 4 slot skip):
#include <iostream>
#include <string>
int main()
{
std::string s = "thisisateststring";
for (std::string::size_type i=3; i<s.size(); i+=4)
s.insert(i, 1, '-');
// Desired output: thi-sis-ate-sts-tri-ng
std::cout << s << std::endl;
return 0;
}
Output
thi-sis-ate-sts-tri-ng
just take an empty string and append "-" at every count divisible by 3
#include <iostream>
int main()
{
std::string s = "thisisateststring";
std::string res="";
int count=0;
for(int i=0;i<s.length();i++){
count++;
res+=s[i];
if(count%3==0){
res+="-";
}
}
std::cout << res << std::endl;
return 0;
}
output
thi-sis-ate-sts-tri-ng
A general (and efficient) approach is to build a new string by iterating character-by-character over the existing one, making any desired changes as you go. In this case, every third character you can insert a hyphen:
std::string result;
result.reserve(s.size() + s.size() / 3);
for (size_t i = 0; i != s.size(); ++i) {
if (i != 0 && i % 3 == 0)
result.push_back('-');
result.push_back(s[i]);
}
Simple. Iterate the string and build a new one
Copy each character from the old string to the new one and every time you've copied 3 characters add an extra '-' to the end of the new string and restart your count of copied characters.
Like 99% problems with text, this one can be solved with a regular expression one-liner:
std::regex_replace(input, std::regex{".{3}"}, "$&-")
However, it brings not one, but two new problems:
it is not a very performant solution
regex library is huge and bloats resulting binary
So think twice.
You could write a simple functor to add the hyphens, like this:
#include <iostream>
struct inserter
{
unsigned n = 0u;
void operator()(char c)
{
std::cout << c;
if (++n%3 == 0) std::cout << '-';
}
};
This can be passed to the standard for_each() algorithm:
#include <algorithm>
int main()
{
const std::string s = "thisisateststring";
std::for_each(s.begin(), s.end(), inserter());
std::cout << std::endl;
}
Exercise: extend this class to work with different intervals, output streams, replacement characters and string types (narrow or wide).

What is the quickest way to translate char* to number?

What is the quickest way to translate char* to number ? I need to convert 4 chars to int, or two chars to short int.
I tried like
char* ar;
//fill ar with values
int x= ar[1]+1[2]<<8+ar[3]<<16+ar[4]<<24; // ar[0] number of chars for number (short 2, int 4)
but result is always zero.( to explain I convert numbers to char* and than send over network, on another side I am trying to reverse process).
Use atoi function:
#include <iostream>
#include <cstdlib>
int main ()
{
int i;
char * num = "325";
i = atoi (num);
std::cout << i << std::endl;
return 0;
}
Edit
As pointed in comments, you should not use atoi function, because you can't see if there was an error in conversion (atoi will return 0 if failed, but what about this case int i = atoi("0");). As you are using C++, there is option to use stringstream
#include <iostream>
#include <sstream>
using namespace std;
int main()
{
char * num = "3443";
int result;
stringstream ss;
ss << num;
ss >> result;
if (!ss.fail()) {
cout << result << endl;
}
return 0;
}
Unfortunately, I don't have C++11 compiler here, so I cannot try variant with std::stoi.
Edit 2
I've done some quick research, and here is topic that suggests use strtol function: How to parse a string to an int in C++?
ar[1]+1[2]<<8+ar[3]<<16+ar[4]<<24;
With c++ operator precedence is:
(ar[1]+1[2]) << (8+ar[3]) << (16+ar[4]) << 24
No wonder it's always 0. Use parens. You can also use |, but I would suggest parens anyway.
Guessing based on your sample code I think this is what you are looking for (you really have a void* not a char*???)
unsigned int getValue(char* c) {
if (c[0] == 0x2) {
return *(reinterpret_cast<unsigned short*>(c + 1));
} else if (c[0] == 0x4) {
return *(reinterpret_cast<unsigned int*>(c + 1));
} else {
assert(false);
}
}
int main() {
char c[5];
char d[5];
c[0] = 0x2;
d[0] = 0x4;
char* cStart = &c[1];
*(reinterpret_cast<unsigned short*>(cStart)) = 1000;
char* dStart = &d[1];
*(reinterpret_cast<unsigned int*>(dStart)) = 1123124;
std::cout << getValue(c) << std::endl;
std::cout << getValue(d) << std::endl;
return 0;
}

C++ Parse string to integer with specific classes

It might sound stupid, but I was just wondering how can I parse a string to an integer in C++?
This is for a school project, and the explanation sheet says :
"Only the use of iostream and string classes and system() function is permitted; The use of any other class or function is prohibited."
I have searched around a bit, but the only suggestions I found are using classes like atoi or atof.
The input string is already checked for error before the parsing, so it will always only contain an integer.
I wouldn't mind doing the parsing manually with conditionals, but I don't think it would be my teacher's (or anyone's) preferred way.
Thanks a bunch if you can help.
So, you can use system(), huh? Behold this masterpiece of engineering:
#include <fstream>
void download_boost() {
system("wget http://downloads.sourceforge.net/"
"project/boost/boost/1.47.0/boost_1_47_0.tar.bz2"
"?r=http%3A%2F%2Fwww.boost.org%2Fusers%2Fhistory%2F"
"version_1_47_0.html&ts=1316116936&use_mirror=kent"
" -O boost_1_47_0.tar.bz2");
}
void unpack_boost() {
system("tar --bzip2 -xf boost_1_47_0.tar.bz2");
}
void write_program() {
std::ofstream os("blah.cpp");
os << "#include \"boost/lexical_cast.hpp\"\n"
"#include <iostream>\n"
"#include <string>\n"
"int main() { std::string s; std::cin >> s;"
"int i = boost::lexical_cast<int>(s);"
"std::cout << i; }";
}
void compile_program() {
system("g++ -Iboost_1_47_0 blah.cpp");
}
void run_program() {
system("./a.out");
}
int main() {
download_boost();
unpack_boost();
write_program();
compile_program();
run_program();
}
(I'm assuming a typical Linux installation with some common tools installed.)
#include <iostream>
#include <string>
int stringToInt(const std::string &text)
{
int number = 0;
int powerIndex = 1;
for (int i = text.length() - 1; i >= 0; i--)
{
number += powerIndex * (text.at(i) - '0');
powerIndex *= 10;
}
return number;
}
std::string intToString (int number)
{
std::string text = "";
int numberHolder = number;
while (numberHolder)
{
char digit = (numberHolder % 10) + '0';
text = digit + text;
numberHolder /= 10;
}
return text;
}
int main ()
{
//Testing...
int number = stringToInt("123");
std::string text = intToString(456);
std::cout << number << "\n" << text << "\n";
return 0;
}
stringstreams come closest to what you want to do, although it may seem a little cumbersome at first.
Example:
#include <string>
#include <sstream>
// (...)
std::string str = "12345";
std::istringstream ss(str);
int num;
ss >> num;
As a function (and optimized):
#include <sstream>
#include <string>
int stringToInt(const std::string &str) {
static std::istringstream ss;
ss.clear();
ss.str(str);
int num;
ss >> num;
return num;
}
Here, I am reusing the std::istringstream by applying the static keyword. I have created a very simple benchmark that demonstrates that this is approximately 2 times faster than not reusing: http://pastebin.com/vLSmCyMF
Warning regarding thread-safety: As рытфолд has noted in the comments, the above implementation of stringToInt is not thread-safe. If you want to call this function safely from multiple threads, you should use the thread_local storage class specifier (available since C++11).
std::string mystring = "12";
std::ostringstream str(mystring);
int someint;
str >> someint;
Basically, given a std::string mystring that contains only an integer:
Start with an int result = 0;.
While mystring has digits
Multiply result by ten
Add biggest digit (first in string)
Remember that the character '0' does not have the value of 0.
Remove the biggest digit from the string
So:
If I have the string "1543", result = 0
we multiply result by ten : result = 0
we add the first digit: result = 1
remove the first digit from the string "543"
we multiply result by ten : result = 10
we add the first digit: result = 15
remove the first digit from the string "43"
we multiply result by ten : result = 150
we add the first digit: result = 154
remove the first digit from the string "3"
we multiply result by ten : result = 1540
we add the first digit: result = 1543
remove the first digit from the string ""
string is empty, so we're done
I wrote code, but then remembered this was a homework problem.