Find word in a string array

So i have made a program that reads a file and stores the content in a wstring variable (Needs to be a wstring as the file contains ANSI characters which i wont show if i read it into a normal string). The file contains file names and file content. The start of the file name is identified by "$file" and the start of the content is defined by "payload". Ive tried to use the string.find function and then do a while loop that checks to see if the position of the word $file is not equal to the end of the string. This works but some of the words in the file are conjoined. So like there would be an extra letter at the end of the word for example $fileq which doesnt get picked up by the find function. Anyone have any ideas how i would get around this issue?

Here is my code so far:

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
48
49
50
51
int main()
{
    initfs in;

    std::wstring str_buf;
    std::wstring head_buf;

    std::wifstream in_file("initfs_Win32", std::ios::binary);
    std::wstring head_data;
    in_file.seekg(0, 556);

    if (in_file.good()) {
        while (std::getline(in_file, head_data))
            head_buf += head_data + L"\r";
    }
    in_file.seekg(556, std::ios::beg);
    std::wstring in_data;

    std::wstring file = L"$file";
    std::wstring name = L"name";
    std::wstring payload = L"payload";

    if (in_file.good()) {
        while (std::getline(in_file, in_data))
            str_buf += in_data + L"\r";

        size_t pos$ = str_buf.find(file);
        size_t posN = str_buf.find(name);
        size_t posP = str_buf.find(payload);

        std::wofstream out_file("initfs");

        out_file << head_buf + str_buf;
        
        out_file.close();

        while (pos$ != std::string::npos)
        {
            /*while (posP != std::string::npos)
            {
                
                posP = str_buf.find(payload, posP + payload.size());
            }*/
            std::wstring filename = str_buf.substr(posN, posP);
            std::wcout << filename;
            pos$ = str_buf.find(file, pos$ + file.size());
            posN = str_buf.find(name, posN + name.size());
        }
    }
    in_file.close();
}
Last edited on
Palace321,
PLEASE USE CODE TAGS (the <> formatting button to the right of this box), when posting code.

Along with the proper indenting, it makes it easier to read your code, and thus also easier to respond to your post.

Tutorials on how to use code tags:

http://www.cplusplus.com/articles/jEywvCM9/
http://www.cplusplus.com/articles/z13hAqkS/

I found the second link to be the most help.

Hint: You can hit "edit post", highlight your code and then press the <> formatting button. This will not automatically indent your code. That part is up to you.

I've found it's easiest to copy and paste pre-indented code directly from the IDE, that way it is already properly formatted.

You can use the "preview" button at the bottom to see how it looks.

Thanks!
max
Last edited on
Post a file example and what you would expect as the output.

As formatted code which compiles:

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
48
49
50
51
52
53
54
55
56
#include <string>
#include <fstream>
#include <iostream>

int main()
{
	//initfs in;

	std::wstring str_buf;
	std::wstring head_buf;
	std::wstring head_data;

	std::wifstream in_file("initfs_Win32", std::ios::binary);

	in_file.seekg(0, 556);

	if (in_file.good()) {
		while (std::getline(in_file, head_data))
			head_buf += head_data + L"\r";
	}

	in_file.seekg(556, std::ios::beg);

	std::wstring in_data;
	std::wstring file = L"$file";
	std::wstring name = L"name";
	std::wstring payload = L"payload";

	if (in_file.good()) {
		while (std::getline(in_file, in_data))
			str_buf += in_data + L"\r";

		size_t pos$ = str_buf.find(file);
		size_t posN = str_buf.find(name);
		size_t posP = str_buf.find(payload);

		std::wofstream out_file("initfs");

		out_file << head_buf + str_buf;

		while (pos$ != std::string::npos) {
			/*while (posP != std::string::npos)
			{

			posP = str_buf.find(payload, posP + payload.size());
			}*/

			std::wstring filename = str_buf.substr(posN, posP);

			std::wcout << filename;

			pos$ = str_buf.find(file, pos$ + file.size());
			posN = str_buf.find(name, posN + name.size());
		}
	}
}

Sorry for the formatting issue, the code tag didn't work when i was writing the post and i forgot to edit it when i posted. Here is an example file: https://www.mediafire.com/file/qvsn5d7mwzn1cyk/initfs_Win32/file

What the program currently does is it reads the whole file into a wstring and then im using the find function to find all of the text between the words "$file" and "payload" but this method doesn't seem to work if either of the words have other characters at the start or end of them so the program just takes the next whole word it finds.
Does it have to be "$file" and "payload?" Can it be something else? Like, for instance, an asterisk *? Or a dollar sign $? I think that would be easier.

The only other option that I can think of would be to read through the file beforehand and make sure the keywords are separated from the rest of the text.

Edit:
Try @seeplus's code. I didn't test it, but it looks like it should work.
Last edited on
Is this what you're after:

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
#include <iostream>
#include <fstream>
#include <string>
#include <cctype>

int main()
{
	const std::string start {"$file"};
	const std::string end {"payload"};

	std::ifstream ifs("initfs_Win32", std::ios::binary);

	std::ofstream ofs("initfs");

	if (!ifs || !ofs)
		return (std::cout << "Cannot open file\n"), 1;

	ifs.seekg(0, std::ios::end);

	const auto flen {ifs.tellg()};

	std::string data(flen, 0);

	ifs.seekg(0);
	ifs.read(data.data(), flen);

	for (size_t pos = 0, pos1 = 0; (pos = data.find(start, pos)) != std::string::npos; pos = pos1) {
		pos1 = data.find(end, pos);

		const std::string ext {data.substr(pos + start.size(), pos1 != std::string::npos ? pos1 - pos - start.size() : pos1)};

		for (const auto& s : ext)
			if (std::isprint(static_cast<unsigned char>(s)))
				ofs << s;

		ofs << '\n';
	}
}



Which produces:


tnamedefault_settings.cfgfsinitfs_win32
name*XP0/Levels/Valley/Valley_01/Valley_01.cfgfsinitfs_win32
name*XP0/Levels/Valley/Valley_02/Valley_02.cfgfsinitfs_win32
name'XP4/Levels/Beach/Beach_01/Beach_01.cfgfsinitfs_win32
name'XP4/Levels/Beach/Beach_02/Beach_02.cfgfsinitfs_win32
name'XP4/Levels/Beach/Beach_03/Beach_03.cfgfsinitfs_win32
name'XP3/Levels/Space/Space_01/Space_01.cfgfsinitfs_win32
name'XP3/Levels/Space/Space_02/Space_02.cfgfsinitfs_win32
name'XP3/Levels/Space/Space_03/Space_03.cfgfsinitfs_win32
nameAXP_Offline/Levels/Arctic/Arctic_01_Offline/Arctic_01_Offline.cfgfsinitfs_win32
nameAXP_Offline/Levels/Arctic/Arctic_04_Offline/Arctic_04_Offline.cfgfsinitfs_win32
nameAXP_Offline/Levels/Forest/Forest_01_Offline/Forest_01_Offline.cfgfsinitfs_win32
nameAXP_Offline/Levels/Forest/Forest_06_Offline/Forest_06_Offline.cfgfsinitfs_win32
nameAXP_Offline/Levels/Desert/Desert_01_Offline/Desert_01_Offline.cfgfsinitfs_win32
nameAXP_Offline/Levels/Desert/Desert_02_Offline/Desert_02_Offline.cfgfsinitfs_win32
nameGXP_Offline/Levels/Volcanic/Volcanic_01_Offline/Volcanic_01_Offline.cfgfsinitfs_win32
nameAXP_Offline/Levels/Valley/Valley_01_Offline/Valley_01_Offline.cfgfsinitfs_win32
name*XP2/Levels/Clouds/Clouds_01/Clouds_01.cfgfsinitfs_win32
name*XP2/Levels/Clouds/Clouds_02/Clouds_02.cfgfsinitfs_win32
name*XP2/Levels/Clouds/Clouds_03/Clouds_03.cfgfsinitfs_win32
name*XP2/Levels/Clouds/Clouds_04/Clouds_04.cfgfsinitfs_win32
name*XP2/Levels/Clouds/Clouds_05/Clouds_05.cfgfsinitfs_win32
name#XP1/Levels/Palace_01/Palace_01.cfgfsinitfs_win32
name#XP1/Levels/Palace_02/Palace_02.cfgfsinitfs_win32
name+XP1/Levels/Industrial_01/Industrial_01.cfgfsinitfs_win32
name+XP1/Levels/Industrial_02/Industrial_02.cfgfsinitfs_win32
name6Levels/Forest/Forest_Chapter_15/Forest_Chapter_15.cfgfsinitfs_win32
name6Levels/Desert/Desert_Chapter_24/Desert_Chapter_24.cfgfsinitfs_win32
name<Levels/Arctic/Arctic_Chapter_01_09/Arctic_Chapter_01_09.cfgfsinitfs_win32
name<Levels/Arctic/Arctic_Chapter_01_28/Arctic_Chapter_01_28.cfgfsinitfs_win32
nameBLevels/Volcanic/Volcanic_Chapter_07_14/Volcanic_Chapter_07_14.cfgfsinitfs_win32
name6Levels/Desert/Desert_Chapter_13/Desert_Chapter_13.cfgfsinitfs_win32
name&Levels/Forest/Forest_05/Forest_05.cfgfsinitfs_win32
name6Levels/Forest/Forest_Chapter_25/Forest_Chapter_25.cfgfsinitfs_win32
name0Levels/Arctic/Arctic_Initial/Arctic_Initial.cfgfsinitfs_win32
name8Levels/Arctic/Arctic_02_Survival/Arctic_02_Survival.cfgfsinitfs_win32
name8Levels/Desert/Desert_03_Survival/Desert_03_Survival.cfgfsinitfs_win32
|nameLevels/Frontend/Frontend.cfgfsinitfs_win32
name3Levels/Frontend/Frontend_Diorama_01/Diorama_01.cfgfsinitfs_win32
name&Levels/Arctic/Arctic_01/Arctic_01.cfgfsinitfs_win32
name&Levels/Forest/Forest_01/Forest_01.cfgfsinitfs_win32
name,Levels/Volcanic/Volcanic_01/Volcanic_01.cfgfsinitfs_win32
name&Levels/Desert/Desert_01/Desert_01.cfgfsinitfs_win32
name&Levels/Desert/Desert_02/Desert_02.cfgfsinitfs_win32
name&Levels/Forest/Forest_02/Forest_02.cfgfsinitfs_win32
name&Levels/Arctic/Arctic_02/Arctic_02.cfgfsinitfs_win32
name,Levels/Volcanic/Volcanic_02/Volcanic_02.cfgfsinitfs_win32
name&Levels/Desert/Desert_03/Desert_03.cfgfsinitfs_win32
name&Levels/Arctic/Arctic_03/Arctic_03.cfgfsinitfs_win32
name,Levels/Volcanic/Volcanic_03/Volcanic_03.cfgfsinitfs_win32
name&Levels/Forest/Forest_03/Forest_03.cfgfsinitfs_win32
name&Levels/Desert/Desert_04/Desert_04.cfgfsinitfs_win32
name,Levels/Desert/Desert_13_MP/Desert_13_MP.cfgfsinitfs_win32
name&Levels/Forest/Forest_06/Forest_06.cfgfsinitfs_win32
name&Levels/Arctic/Arctic_04/Arctic_04.cfgfsinitfs_win32
namedatabase.dbmanifestfsinitfs_win32
nameScripts/Game/BugCommands.luafsinitfs_win32
!nameScripts/Game/Configure.luafsinitfs_win32
nameScripts/Game/DebugSettings.luafsinitfs_win32
nameScripts/Game/Settings.luafsinitfs_win32
nameScripts/Game/Startup.luafsinitfs_win32
!nameScripts/GlobalSettings.luafsinitfs_win32
name Scripts/Packages/Frost/Core.luafsinitfs_win32
!name#Scripts/Packages/Frost/Logging.luafsinitfs_win32
name#Scripts/Pipeline/Configuration.luafsinitfs_win32
EnameScripts/Pipeline/Settings.luafsinitfs_win32
nameScripts/Pipeline/Startup.luafsinitfs_win32
nameScripts/Pipeline/Warnings.luafsinitfs_win32
nameScripts/Server/Master.luafsinitfs_win32
nameScripts/Server/Server.luafsinitfs_win32
nameScripts/Server/Session.luafsinitfs_win32
znameScripts/Server/Shutdown.luafsinitfs_win32
nameScripts/Server/Startup.luafsinitfs_win32
Cname&Scripts/UserOptions/DefaultValues.luafsinitfs_win32
name)Scripts/UserOptions/HardwareProfiles.luafsinitfs_win32
name-Scripts/UserOptions/HardwareProfiles/ATI.luafsinitfs_win32
4name/Scripts/UserOptions/HardwareProfiles/Intel.luafsinitfs_win32
name0Scripts/UserOptions/HardwareProfiles/nVidia.luafsinitfs_win32
name Scripts/UserOptions/Options.luafsinitfs_win32
name+Scripts/UserOptions/Options/Animations.luafsinitfs_win32
name)Scripts/UserOptions/Options/Graphics.luafsinitfs_win32
name(Scripts/UserOptions/Options/Physics.luafsinitfs_win32
name&Scripts/UserOptions/Options/Sound.luafsinitfs_win32
InameScripts/VRSettings.luafsinitfs_win32
nameScripts/FrostTest.cfgfsinitfs_win32
name!Scripts/FrostTestPerformance.cfgfsinitfs_win32
nameScripts/Game.cfgfsinitfs_win32
nameScripts/Local.cfgfsinitfs_win32
nameScripts/LocalEditor.cfgfsinitfs_win32
nameScripts/LocalGame.cfgfsinitfs_win32
nameScripts/ProtocolVersion.cfgfsinitfs_win32
nameScripts/Voyager.cfgfsinitfs_win32
tname$Scripts/PerfhudTimerCategories.yamlfsinitfs_win32
nameScripts/Tests/AutoCard.cfgfsinitfs_win32
nameScripts/Tests/AutoVehicle.cfgfsinitfs_win32
nameScripts/Tests/test.cfgfsinitfs_win32

Topic archived. No new replies allowed.