How to put string elements separated by commas into an int array? - c++

This is the example:5,6,13,4,14,22, .
I want to fill the array with 5 6 13 4 12 22
After compilation it returns : 5 6 , 3 4 , 4 , 2 .
When I introduce 2,3,5,1,6,4 the array will be the correct one.
int nr=0;
for(int j=0;j<sizeOfString;j++){
if ((string[j] == ',')){
output << j <<" j ";//comma positions
}else{
stringArrayg[nr++]= putchar(string[j-2]);
}
}

Here is an example that uses vectors, std::replace, and std::istringstream:
#include <algorithm>
#include <iostream>
#include <sstream>
#include <string>
#include <vector>
std::vector<int> convertToIntArray(std::string input)
{
std::replace(input.begin(), input.end(), ',', ' ');
std::istringstream stringReader{ input };
std::vector<int> result;
int number;
while (stringReader >> number)
{
result.push_back(number);
}
return result;
}
int main()
{
std::string testString = "5,6,13,4,14,22";
std::vector<int> newArray = convertToIntArray(testString);
for (int i = 0; i < newArray.size(); ++i)
{
std::cout << newArray[i] << " ";
}
}

Why not using Boost::Tokenizer as like that:
include <iostream>
#include <vector>
#include <algorithm>
#include <boost/lexical_cast.hpp>
#include <boost/tokenizer.hpp>
using namespace std;
using namespace boost;
int main()
{
string str = "5,6,13,4,14,22"; /// string to parse
vector<int> nums; /// vector containing the numbers extracted from the string
char_separator<char> sep(","); /// char separator for the tokenizer
/// extracting all the tokens separated by ","
tokenizer<char_separator<char> > tokens(str, sep);
/// looping over the tokes and storing them in the vector by
/// casting each token to an int
std::transform( tokens.begin(), tokens.end(), std::back_inserter(nums), &boost::lexical_cast<int,std::string> );
/// printing the vector content
for(const auto &v: nums) {
cout << v << " ";
}
cout << endl;
return 0;
}

Related

Sort a Substring in Descending order using Vector, however getting segmentation fault

I want to sort the string from N to M where N indicates the starting index and M indicates the ending index.
However, my code is getting failed with segmentation fault.
Here is my code:
#include <iostream>
#include <algorithm>
#include <vector>
#include <string>
using namespace std;
int main()
{
string s;
int M=0,N=0;
cout<<"Enter String"<<endl;
getline(cin,s);
vector<char> data(s.begin(), s.end());
cout<<"Enter start_index and end_index for sorting";
cin>>N>>M; //Passed externally as N=start_index, M=end_index
std::sort(data.begin()+N, data.begin()+M, std::greater<char>());
for (std::vector<char>::const_iterator i = data.begin(); i != data.end(); ++i)
std::cout << *i << ' ';
return 0;
}
This example does work fine for me:
#include <iostream>
#include <algorithm>
#include <vector>
#include <string>
using namespace std;
int main()
{
string s = "ABCDEFG";
int N = 1;
int M = 5;
vector<char> data(s.begin(), s.end());
std::sort(data.begin() + N, data.begin() + M, std::greater<char>());
for (auto& character : data)
std::cout << character << ' ';
return 0;
}
http://coliru.stacked-crooked.com/a/ee7c5f05afe85115
I suspect you get an empty string with cin, and therefore your data.begin() is invalid.
Be cautious with user entered data. Always do proper checking for input that may break your code.
Additonally your templated greater is the comparing function for the wrong type.
The answer to the above question is from the guidance of Trevir.
In order to avoid the segmentation fault, check the size of the input
string and then apply operations on it.
#include <iostream>
#include <algorithm>
#include <vector>
#include <string>
using namespace std;
int main()
{
string s;
int M,N;
cout<<"Enter String"<<endl;
getline(cin,s);
if ( s.size() == 0 )
{
std::cout << "Empty Input" << std::endl;
return 0;
}
vector<char> data(s.begin(), s.end());
cout<<"Enter start_index and end_index for sorting";
cin>>N>>M; //Passed externally as N=start_index, M=end_index
std::sort(data.begin()+N, data.begin()+M, std::greater<char>());
for (std::vector<char>::const_iterator i = data.begin(); i != data.end(); ++i)
std::cout << *i;
return 0;
}

How to read a integer value from a string in C++? [duplicate]

I realize that this question may have been asked several times in the past, but I am going to continue regardless.
I have a program that is going to get a string of numbers from keyboard input. The numbers will always be in the form "66 33 9" Essentially, every number is separated with a space, and the user input will always contain a different amount of numbers.
I'm aware that using 'sscanf' would work if the amount of numbers in every user-entered string was constant, but this is not the case for me. Also, because I'm new to C++, I'd prefer dealing with 'string' variables rather than arrays of chars.
I assume you want to read an entire line, and parse that as input. So, first grab the line:
std::string input;
std::getline(std::cin, input);
Now put that in a stringstream:
std::stringstream stream(input);
and parse
while(1) {
int n;
stream >> n;
if(!stream)
break;
std::cout << "Found integer: " << n << "\n";
}
Remember to include
#include <string>
#include <sstream>
The C++ String Toolkit Library (Strtk) has the following solution to your problem:
#include <iostream>
#include <string>
#include <deque>
#include <algorithm>
#include <iterator>
#include "strtk.hpp"
int main()
{
std::string s = "1 23 456 7890";
std::deque<int> int_list;
strtk::parse(s," ",int_list);
std::copy(int_list.begin(),
int_list.end(),
std::ostream_iterator<int>(std::cout,"\t"));
return 0;
}
More examples can be found Here
#include <string>
#include <vector>
#include <iterator>
#include <sstream>
#include <iostream>
int main() {
std::string input;
while ( std::getline( std::cin, input ) )
{
std::vector<int> inputs;
std::istringstream in( input );
std::copy( std::istream_iterator<int>( in ), std::istream_iterator<int>(),
std::back_inserter( inputs ) );
// Log process:
std::cout << "Read " << inputs.size() << " integers from string '"
<< input << "'" << std::endl;
std::cout << "\tvalues: ";
std::copy( inputs.begin(), inputs.end(),
std::ostream_iterator<int>( std::cout, " " ) );
std::cout << std::endl;
}
}
#include <string>
#include <vector>
#include <sstream>
#include <iostream>
using namespace std;
int ReadNumbers( const string & s, vector <int> & v ) {
istringstream is( s );
int n;
while( is >> n ) {
v.push_back( n );
}
return v.size();
}
int main() {
string s;
vector <int> v;
getline( cin, s );
ReadNumbers( s, v );
for ( int i = 0; i < v.size(); i++ ) {
cout << "number is " << v[i] << endl;
}
}
// get string
std::string input_str;
std::getline( std::cin, input_str );
// convert to a stream
std::stringstream in( input_str );
// convert to vector of ints
std::vector<int> ints;
copy( std::istream_iterator<int, char>(in), std::istream_iterator<int, char>(), back_inserter( ints ) );
Here is how to split your string into strings along the spaces. Then you can process them one-by-one.
Generic solution for unsigned values (dealing with prefix '-' takes an extra bool):
template<typename InIter, typename OutIter>
void ConvertNumbers(InIter begin, InIter end, OutIter out)
{
typename OutIter::value_type accum = 0;
for(; begin != end; ++begin)
{
typename InIter::value_type c = *begin;
if (c==' ') {
*out++ = accum; accum = 0; break;
} else if (c>='0' && c <='9') {
accum *= 10; accum += c-'0';
}
}
*out++ = accum;
// Dealing with the last number is slightly complicated because it
// could be considered wrong for "1 2 " (produces 1 2 0) but that's similar
// to "1 2" which produces 1 0 2. For either case, determine if that worries
// you. If so: Add an extra bool for state, which is set by the first digit,
// reset by space, and tested before doing *out++=accum.
}
Try strtoken to separate the string first, then you will deal with each 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;
}

replacing a string in a vector without positioning

In the code i am working on now I have a vector load itself from a txt file now I was trying to see if their was a way to replace certain words in the vector without needing a position or anything
so for example if the txt contained a list of animals and i wanted to change bird to book how would i do that without need the position of the letters
#include <iostream>
#include <string>
#include <vector>
#include <fstream>
using namespace std;
vector <string> test;
int main()
{
string file;
fstream fout( "Vector.txt" );
while ( !fout.eof())
{
getline(fout,file);
test.push_back(file);
}
fout.close();
for( int i = 0; i < test.size(); i++)
{
cout << test[i] << endl;
}
system("pause");
}
txt contains:
dog
cat
bird
hippo
wolf
Use std::transform().
std::string bird2book(const string &str)
{
if (str == "bird")
return "book";
return str;
}
std::transform(test.begin(), test.end(), test.begin(), bird2book);
you can use std::replace
std::replace (test.begin(), test.end(), "bird", "book");
Try this:
typedef std::istream_iterator<string> isitr;
ifstream fin("Vector.txt");
vector <string> test{ isitr{fin}, isitr{} }; // vector contains strings
map<string,string> dict{ // replacements dictionary
{"bird", "book"}, {"cat", "kitten"}
};
for(auto& x: test) // x must be a reference
{
auto itr = dict.find(x);
if(itr != dict.end()) // if a match was found
x = itr->second; // replace x with the found replacement
// (this is why x must be a reference)
}
for(const auto& x: test)
cout << test << " ";
Use STL!! It's our power. Everything you need:
#include <iostream>
#include <algorithm>
#include <iterator>
#include <vector>
#include <string>
#include <fstream>
#include <map>
int main()
{
std::vector<std::string> words;
const std::map<std::string, std::string> words_to_replace{
{ "bird", "book" }, { "cat", "table" }
};
auto end = words_to_replace.cend();
std::transform(
std::istream_iterator<std::string>{ std::ifstream{ "file.txt" } },
std::istream_iterator<std::string>(),
std::back_inserter(words),
[&](const std::string& word) {
auto word_pos = words_to_replace.find(word);
return (word_pos != end) ? word_pos->second : word;
});
std::copy(words.cbegin(), words.cend(),
std::ostream_iterator<std::string>(std::cout, "\n"));
std::cout << std::endl;
}

how to split a string value that contains characters and numbers

I have a std::string s=n8Name4Surname. How can I obtain in 2 strings the Name and the Surname? THX
One way to do this is using Boost.Tokenizer. See this example:
#include <string>
#include <boost/tokenizer.hpp>
#include <boost/foreach.hpp>
int main()
{
using namespace std;
using namespace boost;
string text="n8Name4Surname.";
char_separator<char> sep("0123456789");
tokenizer<char_separator<char> > tokens(text, sep);
string name, surname;
int count = 0;
BOOST_FOREACH(const string& s, tokens)
{
if(count == 1)
{
name = s;
}
if(count == 2)
{
surname = s;
}
++count;
}
}
EDIT
If you put the results in a vector, its even less code:
#include <string>
#include <boost/tokenizer.hpp>
#include <boost/foreach.hpp>
#include <algorithm>
#include <iterator>
#include <vector>
int main()
{
using namespace std;
using namespace boost;
string text="n8Name4Surname.";
char_separator<char> sep("0123456789");
tokenizer<char_separator<char> > tokens(text, sep);
vector<string> names;
tokenizer<char_separator<char> >::iterator iter = tokens.begin();
++iter;
if(iter != tokens.end())
{
copy(iter, tokens.end(), back_inserter(names));
}
}
You can detect numerical characters in the string using function isdigit(mystring.at(position), then extract substring between those positions.
See:
http://www.cplusplus.com/reference/clibrary/cctype/isdigit/
Use Boost tokenizer with the digits 0-9 as delimiters. Then, throw away the string containing "n". It's overkill, I realize...
Simple STL approach:
#include <string>
#include <vector>
#include <iostream>
int main()
{
std::string s= "n8Name4Surname";
std::vector<std::string> parts;
const char digits[] = "0123456789";
std::string::size_type from=0, to=std::string::npos;
do
{
from = s.find_first_of(digits, from);
if (std::string::npos != from)
from = s.find_first_not_of(digits, from);
if (std::string::npos != from)
{
to = s.find_first_of(digits, from);
if (std::string::npos == to)
parts.push_back(s.substr(from));
else
parts.push_back(s.substr(from, to-from));
from = to; // could be npos
}
} while (std::string::npos != from);
for (int i=0; i<parts.size(); i++)
std::cout << i << ":\t" << parts[i] << std::endl;
return 0;
}
Mandatory Boost Spirit sample:
#include <string>
#include <boost/spirit/include/qi.hpp>
#include <iostream>
int main()
{
std::string s= "n8Name4Surname";
std::string::const_iterator b(s.begin()), e(s.end());
std::string ignore, name, surname;
using namespace boost::spirit::qi;
rule<std::string::const_iterator, space_type, char()>
digit = char_("0123456789"),
other = (char_ - digit);
if (phrase_parse(b, e, *other >> +digit >> +other >> +digit >> +other, space, ignore, ignore, name, ignore, surname))
{
std::cout << "name = " << name << std::endl;
std::cout << "surname = " << surname << std::endl;
}
return 0;
}