How to get the difference between 2 strings and store them?

Hi all, I'm using VS2008 with C++98. I would like to find the differences between 2 given string, extract and store them.

For example,

String A: Box 1 is pulled with 20.1N force. Mass is 2kg and friction constant between the surfaces is k=0.4.
String B: Box 1 is pulled with %dN force. Mass is %d%s and friction constant between the surfaces is k=%f.

The String A and B are come in a pair and the string could be different.

How can I use String B to compare with String A, and get the result 20.1; 2kg; 0.4 and store them in array/vector?

Any idea or algorithm that suitable for this??

Thanks.

----------------------------------------
Edited:

Hope this explain well.

1. Pass in a string as String_A
2. Find the string in front the 1st delimiter(e.g. %d) of String B in vectorData
3. Crop the string in front the 1st delimiter as StringCrop_B, saved the string position
4. Find StringCrop_B in String_A
5. If StringCrop_B exist in String_A, crop String_A by using string position and declare as StringCrop_A
6. If StringCrop_B equal to StringCrop_A
7. Start to extract the differences

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
	
CString String_A = str_WindowCaption;
CString String_B;
CString StringCrop_A;
CString StringCrop_B;
int init = 0;
int strA_pos = 0;
int strB_pos = 0;

for(UINT i=0; i<vectorData.size(); i++) {

String_B = vectorData[i];					

strB_pos = String_B.Find(_T("%s"));
if (strB_pos == -1) {
	strB_pos = String_B.Find(_T("%d"));
	if (strB_pos == -1) {
		strB_pos = String_B.Find(_T("%f"));
		if(strB_pos != -1) {
			StringCrop_B = String_B.Mid(init, strB_pos-init);
		}
	}
}

strA_pos = String_A.Find(StringCrop_B, init);				
if (strA_pos != -1){												
	StringCrop_A = String_A.Mid(strA_pos, strB_pos-strA_pos);
}
	
if (StringCrop_B == StringCrop_A) {
	// do stuff
}
}
Last edited on
@Joshua0101,
What does your assignment actually say? (As opposed to your paraphrasing of it.)

https://en.wikipedia.org/wiki/XY_problem
Last edited on
Extracting all numbers from a string has been covered in another post. That would get you:

20.1 2 0.4

If you just need the numbers from a string, that would probably be OK - but it won't get you the kg. Do you need the kg? As lastchance asked, what is the actual assignment?

PS if you have say a vector of double, how do you propose to store kg? If you want to store 2kg in a vector then the vector will need to be of something like type string. But then when you come to use the vector, you've still got conversions to do...
Sorry that I didn't explain it well. I have updated the question with some code.

I get some idea from the other topics on how to extract numbers too but I'm not sure how to implement them in my situation, because my input string consist of many different variables like number (different data types), character, and also some numbers are not required to extract.

And yes, I have to store the 'kg'. What if storing the result as 20.1 2 kg 0.4?
Last edited on
So from the updated description, you want a vector of string that holds the extracted data as a string?

So the extracted data would be:

"20.1" "2" "kg" "0.4"

stored in a std::vector<std::string>

yes?
Yes, the final result should be the everything that is different between the String_A and String_B.
One way to do this is:

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
#include <iostream>
#include <vector>
#include <string>
#include <cstdlib>

int main()
{
	const char* const StringA = "Box 1 is pulled with 20.1N force.Mass is 2kg and friction constant between the surfaces is k = 0.4";
	const char* const StringB = "Box 1 is pulled with %fN force.Mass is %d%s and friction constant between the surfaces is k = %f";

	std::vector<std::string> data;

	for (const char *sa = StringA, *sb = StringB, *se = sa; *sa && *sb; ++sa)
		if (*sb++ == '%') {
			switch (*sb++) {
				case 'f':
					strtod(sa, (char**)&se);
					break;

				case 'd':
					strtol(sa, (char**)&se, 10);
					break;

				case 's':
					for (se = sa; *se != ' '; ++se);
					break;
			}

			data.emplace_back(sa, se);
			sa = se - 1;
		}

	for (const auto& d : data)
		std::cout << d << '\n';
}


which displays:


20.1
2
kg
0.4


as required.
Last edited on
Hi @seeplus,

Thanks for the example but I have some doubt which is, for the switch case, what if the delimiter included this type of float, %.3f?

Also, since I'm using C++98,
1. I can't use emplace_back while push_back also can't take 2 arguments.
2. How can I convert this line for (const auto& d : data) to a normal for loop for (int i=0; i<data.size(); i++) that consist of &?
Last edited on
If you require a full format-specifier parser, then that is a bit more complicated.

If you are still using C++98, I really suggest that you update to a much more recent compiler. If you're using Windows then MS VS2019 Community is free - or there's gnu c++ compiler for Linux.

 
data.emplace_back(sa, se);


becomes:

 
data.push_back(std::string(sa, se));


1
2
for (const auto& d : data)
		std::cout << d << '\n';


becomes:

1
2
for (int i = 0; i < data.size(); ++i)
    std::cout << data[i] << '\n';


Last edited on
To simply ignore any chars following % and before either d, f or s then:

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
#include <iostream>
#include <vector>
#include <string>
#include <cstdlib>
#include <cstring>

int main()
{
	const char* const StringA = "Box 1 is pulled with 20.1N force.Mass is 2kg and friction constant between the surfaces is k = 0.4";
	const char* const StringB = "Box 1 is pulled with %3.1fN force.Mass is %d%s and friction constant between the surfaces is k = %f";

	const char* const valid = "fds";

	std::vector<std::string> data;

	for (const char *sa = StringA, *sb = StringB, *se = sa; *sa && *sb; ++sa)
		if (*sb++ == '%') {
			while (strchr(valid, *sb++) == NULL);
			switch (*(sb - 1)) {
				case 'f':
					strtod(sa, (char**)&se);
					break;

				case 'd':
					strtol(sa, (char**)&se, 10);
					break;

				case 's':
					for (se = sa; *se != ' '; ++se);
					break;
			}

			data.emplace_back(sa, se);
			sa = se - 1;
		}

	for (const auto& d : data)
		std::cout << d << '\n';
}


which for the format %3.1f gives the same result as before:


20.1
2
kg
0.4

Last edited on
Hi, thanks and it works! I have 1 more doubt is, could it possible that I apply the same concept in the for loop to paste the elements in the vector into another string?

Let's say we get
20.1
2
kg
0.4

and we paste them into this string
Box 1, F=%fN, m=%d%s, k=%f

then, we get the final output
Box 1, F=20.1N, m=2kg, k=0.4

Once you have the numbers in the vector, you can use them as you need.
Topic archived. No new replies allowed.