remove std::string from std::vector<char>

Hi,

I am currently trying to remove an occurrence of a std::string from a vector<char>. Also, I have a way of finding an occurrence of a string in a vector but I don't know if it is the most efficient way.

Heres and example:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
// create compare strings (only an example...)
string _begin = "begin";
string _end = "end";
// vector<char> some_vector;  
// vector contains "begin" and "end"                           
// this is actually a incoming tcp data packet

// check to see if the vector contains a string
if (strcmp(some_vector.data(), _begin.c_str()) > 0 &&
     strcmp(some_vector.data(), _end.c_str()) > 0){			
  // here i want to remove "begin" and "end" from the vector<char>
  ...
  ...
}


1. What is the best way to compare the vector<char> to the strings
2. Is there a more efficient way than looping through and checking byte by byte in vector<char> to find a common occurrence of the two strings?

Thanks!
Last edited on
The condition of your if statement doesn't do what your comments imply it does. The first thing to do is look up strcmp so that you know what it does, and then decide if it's appropriate for the job.


Is there a more efficient way than looping through and checking byte by byte in vector<char> to find a common occurrence of the two strings?


It isn't clear what you're trying to accomplish. If your vector<char> is meant to be a string, make it a string.
I apologize for the confusion. Basically what I am doing is getting getting data from a socket and trying to check for a start and delimiter.

So my tcp packet is binary data with an indicator of the beginning of the packet, and an indicator for the end of the packet. That way I can extract the correct data from the array and parse accordingly (and to know when I have gotten a full valid packet).

Once data has been received on the socket, the code goes into a constant loop (with a timeout) and keeps trying to read packets until the begin and end delimiters have been found.

I ran into issues trying to use char* so I figured I would just use a vector<char> so I don't have any memory issues and what not.

Heres a snippet of the code (I have some enums for errors and what not):
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
// loop through until the beginning delimiter and end delimiter are found
// the loop timeout is 20 loops
int loopTimeout = 0;
bool looper = true;
while (looper){
	// create buffer array for single packet
	char buf[MAX_INC_TCP_SIZE + 1];	// buffer for incoming data
	memset(buf, '\0', sizeof(buf));

	// recv data on the socket
        int ret = recv(_connectedSocket, buf, sizeof(buf), 0);
	err = errno;
	// check for an error on the socket
	if (ret <= 0) {	// error on the socket
		// check if its a recoverable error or not
		if ((err != EAGAIN) && (err != EWOULDBLOCK)){
			_dataErrorCode = TCPRET_ERROR;
			return false;
		}
	}
	else {	// data was read, append to string
		// null terminate the array
		buf[ret] = '\0';
		concat.insert(concat.end(), buf, (buf + strlen(buf)));	// insert the array
	}

	// check if the data contains the start and end delimiters
	if (strcmp(concat.data(), _dataRecvStartStr.c_str()) > 0 &&
		strcmp(concat.data(), _dataRecvEndStr.c_str()) > 0){
		// pop out of while loop
		looper = false;
	}
	else {	// if it doesnt, then check the loop counter
		// check the loop count
		if (loopTimeout >= LOOP_TIMEOUT){
			_dataErrorCode = TCPRET_INVALID_PACKET;
			return false;
		}
	        else
		        loopTimeout++;	// increment loop timeout
		}
	}
}

// this is where I want to remove the start and end delimiters from the array
// 
// 


Again, I apologize for the confusion, my description was a little vague above.
Last edited on
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include <iostream>
#include <vector>
#include <string>
#include <algorithm>

int main()
{
    std::vector<char> vec ;
    for( char c : "abcdefghijklmnopabcdefghijkl" ) vec.push_back(c) ;
    for( char c : vec ) std::cout << c ;
    std::cout << '\n' ;

    const std::string str = "fghij" ;

    // remove the first occurrence of str from the vector
    auto s = std::search( vec.begin(), vec.end(), str.begin(), str.end() ) ;
    if( s != vec.end() ) vec.erase( s, s+str.size() ) ;
    for( char c : vec ) std::cout << c ;
    std::cout << '\n' ;
}


http://liveworkspace.org/code/JvsgN$0
Basically what I am doing is getting getting data from a socket and trying to check for a start and delimiter.

While search-erase is the natural way to remove a subsequence in C++ in general, your specific task has a solution in boost.asio: take a look at async_read_until()
http://www.boost.org/doc/libs/release/doc/html/boost_asio/reference/async_read_until.html
Topic archived. No new replies allowed.