Question about string replace [solved]

Greetings

It's me again, with a question about string replacement.

Here's my code:

1
2
3
4
5
6
7
8
9
10
11
12

int textfragment(int typ){
	
	string text=getfragment(typ);
	string insertme=(const char*)minute;
	
	string findme="{min}";
	text.replace(findme.begin(), findme.end(), insertme.begin(), insertme.end());
	cout << text << endl;

	return 0;
}


getfragment() connects to a mysql server and returns a string.



Here my debugger (gdb) output:


Schiesse (poscheck)
Schuss! (1)[-10|11|0](0/19/0)[20]
schuss ende (-10|30)
mynum: 20
team: 1/1
name: Alex

Program received signal SIGSEGV, Segmentation fault.
[Switching to Thread 0xb7a6b8d0 (LWP 22716)]
0xb7b5c25b in strlen () from /lib/i686/cmov/libc.so.6
(gdb) bt
#0 0xb7b5c25b in strlen () from /lib/i686/cmov/libc.so.6
#1 0xb7d0a96b in std::basic_string<char, std::char_traits<char>, std::allocator<char> >::basic_string () from /usr/lib/libstdc++.so.6
#2 0x0805d67f in textfragment (typ=3) at engine.cc:352
#3 0x0805d985 in score (mynum=20, scoreteam=1) at engine.cc:5427
#4 0x0805dbcd in playhalbzeit () at engine.cc:6048
#5 0x0805e1c6 in main (args=2, argv=0xbfd84bf4) at engine.cc:6259
(gdb)


So my question is: What am I doing wrong?

Thanks

Marco

EDIT: minute is a global integer
Last edited on
If minute is an integer then casting the integer to a const char* probably does not result in a valid C-style string that can be assigned to insertme.

Use std::stringstream or sprintf() to convert integers to strings.
Using sprintf() for insertme gives a compiling-error.
1
2
engine.cc: In function ‘int textfragment(int)’:
engine.cc:353: error: cannot convert ‘std::string’ to ‘char*’ for argument ‘1’ to ‘int sprintf(char*, const char*, ...)’

Using a var. for sprintf and then giving the value to insertme
1
2
3
char* muh;
	sprintf(muh,"%d",minute);
	string insertme=muh;

is returning an error as well:


Program received signal SIGSEGV, Segmentation fault.
[Switching to Thread 0xb7a228d0 (LWP 24349)]
0xb7b09aff in _IO_default_xsputn_internal () from /lib/i686/cmov/libc.so.6
(gdb) bt
#0 0xb7b09aff in _IO_default_xsputn_internal () from /lib/i686/cmov/libc.so.6
#1 0xb7add9f2 in vfprintf () from /lib/i686/cmov/libc.so.6
#2 0xb7afe21c in vsprintf () from /lib/i686/cmov/libc.so.6
#3 0xb7ae653b in sprintf () from /lib/i686/cmov/libc.so.6
#4 0x0805d673 in textfragment (typ=3) at engine.cc:353
#5 0x0805d99d in score (mynum=9, scoreteam=452) at engine.cc:5429
#6 0x0805dbe5 in playhalbzeit () at engine.cc:6050
#7 0x0805e1de in main (args=2, argv=0xbfd3bbb4) at engine.cc:6261


EDIT: trying stringstream

EDIT(II): strimstream does not work aswell:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
string text=getfragment(typ);
	stringstream ss;
	string insertme="";
	
	ss.clear ();
	ss.str ("");
	
	ss << minute;
	ss >> insertme;
	
	
	string findme="{min}";
	text.replace(findme.begin(), findme.end(), insertme.begin(), insertme.end());




terminate called after throwing an instance of 'std::out_of_range'
what(): basic_string::replace

Program received signal SIGABRT, Aborted.
[Switching to Thread 0xb7a228d0 (LWP 24513)]
0xb7f20424 in __kernel_vsyscall ()
(gdb) bt
#0 0xb7f20424 in __kernel_vsyscall ()
#1 0xb7ac8640 in raise () from /lib/i686/cmov/libc.so.6
#2 0xb7aca018 in abort () from /lib/i686/cmov/libc.so.6
#3 0xb7ce7928 in __gnu_cxx::__verbose_terminate_handler ()
from /usr/lib/libstdc++.so.6
#4 0xb7ce5805 in ?? () from /usr/lib/libstdc++.so.6
#5 0xb7ce5842 in std::terminate () from /usr/lib/libstdc++.so.6
#6 0xb7ce597a in __cxa_throw () from /usr/lib/libstdc++.so.6
#7 0xb7c7d58f in std::__throw_out_of_range () from /usr/lib/libstdc++.so.6
#8 0xb7cc3ece in std::string::replace () from /usr/lib/libstdc++.so.6
#9 0xb7cc3fb7 in std::string::replace () from /usr/lib/libstdc++.so.6
#10 0x0805db40 in textfragment (typ=3) at engine.cc:364
#11 0x0805ddcb in score (mynum=21, scoreteam=1) at engine.cc:5435
#12 0x0805e013 in playhalbzeit () at engine.cc:6056
#13 0x0805e60c in main (args=2, argv=0xbff3a5b4) at engine.cc:6267
(gdb)


Suppose i did something wrong?
Last edited on
Did you even read the reference on how to use these facilities?
As long as this¹ is the right reference, i did. If this was the wrong page give me a hint and i'll try again.



¹:http://www.cplusplus.com/reference/iostream/stringstream/str.html
I just went through std::string::replace() and no overload searches for a particular substring. You'll need to use std::string::find().

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include <iostream>
#include <sstream>

int main(){
	std::stringstream ss;
	std::string insert;
	std::string txt("aaaaaa{num}zzzzzz");
	std::string find("{num}");
	ss <<42;
	ss >>insert;
	txt.replace(txt.find(find),find.size(),insert);
	std::cout <<txt<<std::endl;
	return 0;
}
Thanks, I found it by myself after som research. But anyway it's returnung an error:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
string txt=getfragment(typ);
	stringstream ss;

	
	string insert;
	
	
		
	ss.clear();
	ss << minute;
	ss >> insert;
	string find="{min}";
	txt.replace(txt.find(find),find.size(),insert);
	ss.clear();
	ss << score_h;
	ss >> insert;
	find="{score_home}";
	txt.replace(txt.find(find),find.size(),insert);
	ss.clear();
	ss << score_g;
	ss >> insert;
	find="{score_guest}";
	txt.replace(txt.find(find),find.size(),insert);
	cout << txt << endl;


terminate called after throwing an instance of 'std::out_of_range'
what(): basic_string::replace

Program received signal SIGABRT, Aborted.
[Switching to Thread 0xb7a068d0 (LWP 773)]
0xb7f04424 in __kernel_vsyscall ()
(gdb) bt
#0 0xb7f04424 in __kernel_vsyscall ()
#1 0xb7aac640 in raise () from /lib/i686/cmov/libc.so.6
#2 0xb7aae018 in abort () from /lib/i686/cmov/libc.so.6
#3 0xb7ccb928 in __gnu_cxx::__verbose_terminate_handler ()
from /usr/lib/libstdc++.so.6
#4 0xb7cc9805 in ?? () from /usr/lib/libstdc++.so.6
#5 0xb7cc9842 in std::terminate () from /usr/lib/libstdc++.so.6
#6 0xb7cc997a in __cxa_throw () from /usr/lib/libstdc++.so.6
#7 0xb7c6158f in std::__throw_out_of_range () from /usr/lib/libstdc++.so.6
#8 0xb7ca7ece in std::string::replace () from /usr/lib/libstdc++.so.6
#9 0xb7ca81db in std::string::replace () from /usr/lib/libstdc++.so.6
#10 0x0805d96b in textfragment (typ=3) at engine.cc:363

363 is the first "txt.replace(txt.find(find),find.size(),insert);".

Im trying to evaluate the error now, what happened if "txt" was empty before the replacement? (It should not be, but i'll check again)

If you want to try:

In Minute {min} traf {player} für {club}. Neues Zwischenresultat {score_home} : {score_guest}.

Is one of the txt values, so maybe something is wrong with this?
Or what if {min} was not part of the txt string?
Last edited on
Alright, if "txt.find(find)" had no result it returned "-1". -1 is "out of range"

So here is the solution how to prevent it and replace more than one "{min}" in the source:

1
2
3
4
5
6
7
int found=txt.find(find);
	while(found>=0){
		if(found>=0){
			txt.replace(found,find.size(),insert);
		}
		found=txt.find(find);
	}


Thanks for your help Helios :)
Last edited on
Topic archived. No new replies allowed.