how to find nth quote char?

B

baibaichen

hi , i have a string, looks like
~~ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") =
"FileSystemTest", "FileSystemTest_2003.vcproj",
"{ABC6E827-F34C-4E45-B384-AC33DF83803B}" ~~

what i want get is between 5th and 6th doule quote char, i.e.
FileSystemTest_2003.vcproj

is there any general algorithm to complete this simple task in simple
way.

my implementation is :

static const TCHAR quoteChar = '"';
static const TCHAR equalChar = '=';
size_t firstposEqual = data.find(equalChar);

size_t firstposQuote = data.find(quoteChar,++firstposEqual);
if (firstposQuote == string::npos)
return;

size_t secondQuoteChar = data.find(quoteChar,++firstposQuote);
if (secondQuoteChar == string::npos)
return;
//relative path
firstposQuote = data.find(quoteChar,++secondQuoteChar);
if (firstposQuote == string::npos)
return;
secondQuoteChar = data.find(quoteChar,++firstposQuote);
if (secondQuoteChar == string::npos)
return;
string relativePath =
data.substr(firstposQuote,secondQuoteChar-firstposQuote);

i think it is very awful!!

thanks
 
G

Gernot Frisch

baibaichen said:
hi , i have a string, looks like
~~ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") =
"FileSystemTest", "FileSystemTest_2003.vcproj",
"{ABC6E827-F34C-4E45-B384-AC33DF83803B}" ~~

what i want get is between 5th and 6th doule quote char, i.e.
FileSystemTest_2003.vcproj

is there any general algorithm to complete this simple task in
simple
way.

I would run a loop to count 6x "" and then store the positions of 5th
and 6th quotes...
 
B

baibaichen

yes, you are right, but it is just impovement....., what i want to get
is looks like:

pair<iterator, iterator> pair_find(iterator, iterator, value )
 
S

Simon Biber

baibaichen said:
yes, you are right, but it is just impovement....., what i want to get
is looks like:

pair<iterator, iterator> pair_find(iterator, iterator, value )

Is this the sort of thing you are trying to write?

/* Find the n'th and n+1'th occurrence of value between a and b.
First result is iterator to element after n'th occurrence.
Second result is iterator to element before n+1'th occurrence.
If reached end of given range, throws an exception
*/
template<typename iter, typename valtype>
pair<iter, iter>
pair_find(
iter a,
iter b,
const valtype& value,
size_t n)
{
pair<iter, iter> result;
iter j = a;
for(size_t i = 0; i < n; ++i)
{
while(j != b && *j != value) ++j;
if(j == b) throw i;
++j;
}
result.first = j;
while(j != b && *j != value) ++j;
if(j == b) throw size_t(-1);
result.second = j;
return result;
}

I'm quite a beginner at C++ myself. If there are problems with this code
can someone please help me correct them?
 
N

Neil Cerutti

hi , i have a string, looks like
~~ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") =
"FileSystemTest", "FileSystemTest_2003.vcproj",
"{ABC6E827-F34C-4E45-B384-AC33DF83803B}" ~~

what i want get is between 5th and 6th doule quote char, i.e.
FileSystemTest_2003.vcproj

is there any general algorithm to complete this simple task in
simple way.

A finite state machine that found quoted strings would be of
help, but you'd have to write it yourself.

You might want to take a peek at boost::tokenizer or
boost::regex, either of which could provide help.

Here's a boost::tokenizer sample solution.

#include <iostream>
#include <string>
#include <boost/tokenizer.hpp>

int main()
{

std::string line = "Project(\"{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}\")"
" = \"FileSystemTest\", \"FileSystemTest_2003.vcproj\", \"{ABC6E827-"
"F34C-4E45-B384-AC33DF83803B}\"";
typedef boost::tokenizer<boost::char_separator<char> > tokenizer;
tokenizer tokens(line, boost::char_separator<char>("\""));
int i = 0;
std::string proj_file = "\"Not Found\"";
for (tokenizer::iterator iter = tokens.begin(); iter != tokens.end()
; ++iter, ++i)
{
if (i == 5) {
proj_file = *iter;
break;
}
}
std::cout << "[" << proj_file << "]\n";
return 0;
}
 
J

Jay Nabonne

hi , i have a string, looks like
~~ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") =
"FileSystemTest", "FileSystemTest_2003.vcproj",
"{ABC6E827-F34C-4E45-B384-AC33DF83803B}" ~~

what i want get is between 5th and 6th doule quote char, i.e.
FileSystemTest_2003.vcproj

is there any general algorithm to complete this simple task in simple
way.

One way:

#include <iostream>
#include <string>
#include <algorithm>

using namespace std;

// Create a predicate for find_if.
struct NFindPred
{
NFindPred(char c, int which) : m_c(c), m_remaining(which) {}

bool operator ()(char c)
{ return c == m_c && --m_remaining == 0; }

private:
char m_c;
int m_remaining;
};

int main()
{
// string (broken across lines, but still single string)
string s =
"~~ Project(\"{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}\") ="
"\"FileSystemTest\","
"\"FileSystemTest_2003.vcproj\","
\"{ABC6E827-F34C-4E45-B384-AC33DF83803B}\""
"~~";

string::const_iterator i5 =
std::find_if(s.begin(), s.end(), NFindPred('"', 5));

if (i5 != s.end())
{
string::const_iterator i6 =
find_if(s.begin(), s.end(), NFindPred('"', 6));

string subs(i5+1, i6);

cout << subs << endl;
}

return 0;
}

- Jay
 
J

Jay Nabonne

One way:

#include <iostream>
#include <string>
#include <algorithm>

using namespace std;

// Create a predicate for find_if.
struct NFindPred
{
// default to 1
NFindPred(char c, int which=1) : m_c(c), m_remaining(which) {}
bool operator ()(char c)
{ return c == m_c && --m_remaining == 0; }

private:
char m_c;
int m_remaining;
};

<snip>
// continue searching from here...
string::const_iterator i6 =
find_if(i5+1, s.end(), NFindPred('"'));
string subs(i5+1, i6);

cout << subs << endl;
}

- Jay
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,764
Messages
2,569,567
Members
45,041
Latest member
RomeoFarnh

Latest Threads

Top