expected primary expression before ; token - c++

I am trying to write a function that will split a string based on a given character and return a vector of the resulting strings but I am getting a compilation error at the line of my for loop. Any ideas why? I should be able to assign astring[0] to a char pointer correct?
/*
splits string by a given character and returns a vector of each segment
if string = "ab cd ef" and split_char = " " it will return a vector with
"ab" in first location "cd" in second location and "ef" in third location
*/
vector<string> split_string(string string_to_split, const char split_char)
{
//deletes leading split characters
int num_leading_split_char = 0;
for (char * c = string_to_split[0]; c* == split_char; c++)
{
num_leading_split_char++;
}
string_to_split.erase(0, num_leading_split_char);
//makes the split string vector
vector<string> split_string;
string temp_string = "";
for (char * c = string_to_split[0]; c*; c++)
{
if (*c == split_char)
{
split_string.push_back(temp_string); //add string to vector
temp_string = ""; //reset temp string
}
else
{
temp_string += *c; //adds char to temp string
}
}
return split_string;
}
error message:
pgm5.cpp: In function ‘std::vector >
split_string(std::__cxx11::string, char)’:
pgm5.cpp:257:34: error: invalid conversion from
‘__gnu_cxx::__alloc_traits >::value_type {aka
char}’ to ‘char*’ [-fpermissive] for (char c = string_to_split[0];
c == split_char; c++)
^
pgm5.cpp:257:40: error: expected primary-expression before ‘==’ token
for (char c = string_to_split[0]; c == split_char; c++)
^~
pgm5.cpp:269:34: error: invalid conversion from
‘__gnu_cxx::__alloc_traits >::value_type {aka
char}’ to ‘char*’ [-fpermissive] for (char c = string_to_split[0];
c; c++)
^
pgm5.cpp:269:39: error: expected primary-expression before ‘;’ token
for (char c = string_to_split[0]; c; c++)
^
Compilation failed.

I should be able to assign std::string str[0] to a char* pointer correct?
No. str[0] is a char literal not a char* pointer. Your complier is giving you this exact error. Since you're already using std::string why not just simply leverage some of the nice operations it provides for you like substr and find so you don't need to reinvent the wheel or maybe it's a flat tire in your case (kidding). Also, it's a good idea to pass non-POD types that you're not modifying as const references to avoid unnecessary copies i.e. const std::string &. I know in your code there is an erase operation, but in this example there is no need to modify the string being passed in.
std::vector<std::string> split_string(const std::string &string_to_split, char delim)
{
std::vector<std::string> results;
size_t match = 0;
size_t found = 0;
// match each part of string_to_split on delim and tokenize into results
// if delim char is never found then return empty vector
while ((found = string_to_split.find(delim, match)) != std::string::npos)
{
results.push_back(string_to_split.substr(match, found - match));
match = found + 1; // start again at next character
}
// after the loop, if any match was found store the last token
if (match != 0)
{
results.push_back(string_to_split.substr(match));
}
return results;
}
If you are tokenizing on spaces you can use it like this.
std::string test("This is a test.");
std::vector<std::string> tokenized = split_string(test, ' ');
for (const auto& s : tokenized)
{
std::cout << "s=" << s << std::endl;
}
Which will yield the following results.
s=This
s=is
s=a
s=test.

Try this you can try it at http://cpp.sh/8r6ze:
#include <sstream> // std::istringstream
#include <string>
#include <vector>
#include <iostream>
std::vector<std::string> split_string(const std::string string_to_split,
const char delimiter)
{
std::vector<std::string> tokens;
std::string token;
std::istringstream tokenStream(string_to_split);
while (std::getline(tokenStream, token, delimiter))
{
tokens.push_back(token);
}
return tokens;
}
int main ()
{
const std::string theString{"thy with this"};
for (const auto &s:split_string(theString,' ')){
std::cout << s <<std::endl;
}
return 0;
}

Related

Check equality from a void pointer typecasted data

in my below program i get compilation error
error: comparison between distinct pointer types 'unsigned char*' and 'const char*' lacks a cast
How to tackle this and do comparison
#include <iostream>
#include <vector>
using namespace std;
std::vector<std::uint8_t> vec;
void Init(void* tmp)
{
auto dd = static_cast<std::uint8_t *>(tmp);
std::cout<<"loop : "<<dd<<std::endl;
if(dd == "BBBB_DDDDD_XXUSTYY_99_7DFFXX9B67")
std::cout<<"equal";
else
std::cout<<"not equal";
}
std::string PadIt(std::string& str, std::size_t outputLength)
{
if (outputLength > str.size()) {
char paddingChar = ' ';
str.insert(str.size(), outputLength - str.size(), paddingChar);
}
std::cout<<"PadIt str is : "<<str<<" size is: "<<str.size()<<std::endl;
return str;
}
int main() {
std::string key_str = "BBBB_DDDDD_XXUSTYY_99_7DFFXX9B67";
std::string obid = PadIt(key_str,16);
std::vector<std::uint8_t> vec(obid.begin(),obid.end());
Init(vec.data());
}
I want to do comparison of string in Init function, if a wrong string is given it show give false

How do I replace a single character like 'A' with something like "10"?

#include <iostream>
#include <string>
using namespace std;
int main ()
{
string s;
cin >> s;
for (int i = 0; i < s.size (); i++)
{
if (s[i] == 'A')
{
s[i] = "10";
}
cout << s[i];
}
return 0;
}
I am getting following error:
main.cpp: In function
'int main()': main.cpp:10:5: error: invalid conversion from 'const char*' to 'char' [-fpermissive] s[i]= "10";
Any help would be highly appreciated. Thank you.
You can find the position of A, starting from index 0 until end of the string and whenever you find, replace it with 10 using the information of both position where you found and the length of the string you would like to find in the given string.
Something like follows: https://www.ideone.com/dYvF8d
#include <iostream>
#include <string>
int main()
{
std::string str;
std::cin >> str;
std::string findA = "A";
std::string replaceWith = "10";
size_t pos = 0;
while ((pos = str.find(findA, pos)) != std::string::npos)
{
str.replace(pos, findA.length(), replaceWith);
pos += replaceWith.length();
}
std::cout << str << std::endl;
return 0;
}
why not use string::find() to locate the character you want to replace and then string::insert to insert a "10"? maybe not the best way, but can finish it correctly.
You code's question is that the operator[] of std::string returns a char&, and you can not assign a string literal to it.
And I think I should give you a function to implement it.
void Process(std::string& op)
{
auto pos=op.find('A');
op.erase(pos,1);
if(pos!=std::string::npos)
{
op.insert(pos,"10");
}
}

c++ std::string array as function parameter

I'm kind of new to C++. I want to make split function for std::string in c++ like java split function in String class(I don't want to use boost library). so I made custom split function which is..
using namespace std;
void ofApp::split(string ori, string tokens[], string deli){
// calculate the number of tokens
int length = 0;
int curPos = 0;
do{
curPos = ori.find(deli, curPos) + 1;
length++;
}while(ori.find(deli, curPos) != string::npos);
length++;
// to save tokens, initialize tokens array
tokens = new string[length]; // this is the line I'm suspicious about..
int startPos = 0;
int strLength = 0;
int curIndex = 0;
do{
strLength = ori.find(deli, startPos) - startPos;
tokens[curIndex++] = ori.substr(startPos, strLength);
startPos = ori.find(deli, startPos) + 1;
}while(ori.find(deli, startPos) != string::npos);
tokens[curIndex] = ori.substr(startPos, ori.length() - startPos);
}
First, I thought passing parameter as string tokens[] is the way call by reference, so when function is finished, tokens[] array will be full of tokens seperated by deli string. But when i call this function like
string str = "abc,def,10.2,dadd,adsf";
string* tokens;
split(str, tokens, ",");
after this, tokens array is completely empty. On my guess, this happens because of the line
tokens = new string[length];
I think memory space for tokens array as local variable is allocated and when split function is finished, this memory space will be free as block is finished.
when i try to debug, split function itself is working very well as tokens array is full of tokens at least in split function block. I think my guess is right but how can I solve this problem? Any solution? I think this is not only matter of std::string array, this is homework of "call by reference".
Requirement
pass std::string[] type to function parameter (return tokens[] is OK too. But I think this will have same problem)
when function is finished, array must full of tokens
tokens array length must be calculated in split function(if user has to calculate tokens length, it is foolish function). Because of this, memory for tokens array can't be allocated before split function call.
Thank you in advanced for your great answer!
As #chris suggested, something like the following code should work.
Example Code
#include <iostream>
#include <string>
#include <vector>
std::vector<std::string> split(const std::string& delimiter, const std::string& str)
{
std::vector<std::string> result;
std::size_t prevPos = 0;
while (prevPos != std::string::npos)
{
std::size_t currPos = str.find(delimiter, prevPos);
result.push_back(str.substr(prevPos, currPos - prevPos));
prevPos = currPos;
if (prevPos != std::string::npos)
{
// Skip the delimiter
prevPos += delimiter.size();
}
}
return result;
}
int main()
{
std::string str("this,is,a,test");
std::vector<std::string> splitResult = split(",", str);
for (const auto &s : splitResult)
{
std::cout << "'" << s << "'\n";
}
std::cout << "\n";
str = "this - is - a - test";
splitResult = split(" - ", str);
for (const auto &s : splitResult)
{
std::cout << "'" << s << "'\n";
}
return 0;
}
Example Output
'this'
'is'
'a'
'test'
'this'
'is'
'a'
'test'

Using a <string,string> or <string, char> map instead of <char, char> in C++

I am new to STL and want to get used to string datatype instead of the char datatype. I am trying to map a string to a char in this code but it gives 2 compilation errors at lines 13 and 14 - "error: invalid conversion from 'char' to 'const char*' and error: invalid conversion from 'int' to 'const char*'". How can I fix these errors?
I have written the correct code in commented lines (using a map of char,char) to show what I want to implement with strings. I think the problem is probably that a string is not taken as an array of characters in C++.
What is the best way to implement the same without using char datatype?
#include <bits/stdc++.h>
using namespace std;
int main()
{
//map<char,char> M;
map<string, char> M;
string S,R;
cin>>S>>R;
for(int i=0;i<26;i++)
{
//M[S[i]]=(char)(i+'a');
//M[(char)toupper(S[i])]=(char)(i+'A');
M[S[i]]=(char)(i+'a');
M[toupper(S[i])]=(char)(i+'A');
}
for(int i=0;i<R.size();i++)
cout<<M[R[i]];
return 0;
}
Thanks in advance.
S[i] returns a single char, while toupper() returns an int. std::string does not have a constructor that accepts a single char by itself (but it does have an = operator that does) or an int at all. You need to use something more like this instead:
// using string(const char* s, size_type count)
char c = S[i];
M[string(&c, 1)] = (char)(i+'a');
c = (char) toupper(c);
M[string(&c, 1)] = (char)(i+'A');
Or:
// using string(size_type count, char ch)
char c = S[i];
M[string(1, c)] = (char)(i+'a');
c = (char) toupper(c);
M[string(1, c)] = (char)(i+'A');
Or:
// using operator=(char ch)
string tmp;
tmp = S[i];
M[tmp] = (char)(i+'a');
tmp = (char) toupper(c);
M[tmp] = (char)(i+'A');

c++ ocurrence of a std::string inside another std::string

i am tryng to count the ocurrence of a std::string inside another std::string using this:
static int cantidadSimbolos(const std::string & aLinea/*=aDefaultConstString*/,
const std::string & aSimbolo/*=aDefaultSimbolSeparador*/)
{
if(aSimbolo.empty()) return 0;
if (aLinea.empty()) return 0;
int aResultado=0;
//This is the line that the compiler doesnt like
aResultado=std::count(aLinea.begin(),aLinea.end(),aSimbolo);
return aResultado;
}
but the compiler doesnt like it, this is the error that the compiler emits:
error: no match for ‘operator==’ in
‘_first._gnu_cxx::__normal_iterator<_Iterator,
_Container>::operator* >() == __value’
any help??
thx in advance!
The following code will find the count of the non-overlapping occurrences of a given string.
using namespace std;
static int countOccurences(const string & line, const string & symbol) {
if (symbol.empty()) return 0;
if (line.empty()) return 0;
int resultCount = 0;
for (size_t offset = line.find(symbol); offset != string::npos;
offset = line.find(symbol, offset + symbol.length()))
{
resultCount++;
}
return resultCount;
}
int main(int argc, const char * argv[])
{
cout << countOccurences("aaabbb","b") << endl;
return 0;
}
The find function will return either an iterator to the first element of the value it matches to or return 'last' hence string::npos. This ensures no overlap with offset + symbol.length().
I did my best to translate the variables to English for readability for English users.