Я искал тысячи вопросов и ответов о том, что я собираюсь задать, но я все еще не нашел способ сделать то, что я собираюсь объяснить.
У меня есть текстовый файл, из которого я должен извлечь информацию о нескольких вещах, причем все они имеют следующий формат:
"string1":"string2"
И после этого есть больше информации, я имею в виду:
Текстовый файл выглядит примерно так:
LINE 1 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX "string1": "string2" XXXXXXXXXXXXXXXXXXXXXXXXXX "string3": "string4" XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX... ('\n')
LINE 2 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX "string5": "string6" XXXXXXXXXXXXXXXXXXXXXXXXX "string7": "string8" XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX...
XXX представляет ненужную информацию, которая мне не нужна, а theEntireString (строка, используемая в примере кода) хранит всю информацию одной строки, а не всю информацию текстового файла.
Я должен сначала найти содержимое строки1 и сохранить содержимое строки2 в другую строку без кавычек. Проблема в том, что я должен остановиться, когда я обновляю последнюю цитату, и я не знаю, как именно это сделать. Я полагаю, что мне нужно использовать функции find() и substr(), но, несмотря на неоднократные попытки, мне это не удалось.
Я сделал что-то вроде этого:
string extractInformation(string theEntireString)
{
string s = "\"string1\":\"";
string result = theEntireString.find(s);
return result;
}
Но таким образом я полагаю, что храню в строке последнюю цитату и остальную часть строки.
Предполагая, что ключ или значение содержит кавычку. Ниже выведено значение после ":". Вы также можете использовать его в цикле для многократного извлечения поля значения, если у вас есть несколько пар ключ-значение во входной строке, при условии, что вы сохраняете запись о позиции последнего найденного экземпляра.
#include <iostream>
using namespace std;
string extractInformation(size_t p, string key, const string& theEntireString)
{
string s = "\"" + key +"\":\"";
auto p1 = theEntireString.find(s);
if (string::npos != p1)
p1 += s.size();
auto p2 = theEntireString.find_first_of('\"',p1);
if (string::npos != p2)
return theEntireString.substr(p1,p2-p1);
return "";
}
int main() {
string data = "\"key\":\"val\" \"key1\":\"val1\"";
string res = extractInformation(0,"key",data);
string res1 = extractInformation(0,"key1",data);
cout << res << "," << res1 << endl;
}
Выходы:
val,val1
"XXXXX\"key\":\"val\"XXXXX\"key1\":\"val1\"XXXXXXX"
на диске станет string data = "XXXXX"key":"val"XXXXX"key1":"val1"XXXXXXX"
в коде cxx. Если вы измените код для чтения файла или из stdin, вы увидите.
Функция "найти" просто дает вам позицию согласованной строки, чтобы получить результирующую строку, необходимую для использования функции "subst". Попробуй это
string start,end;
start = theEntireString.substr(1,theEntireString.find(":")-2);
end = theEntireString.substr(theEntireString.find(":")+2,theEntireString.size()-1);
Это решит вашу проблему
Удачи...
Вам не нужна строковая операция. Я надеюсь, что XXXXX не содержит никаких "", поэтому вы можете прочитать обе строки непосредственно из файла:
ifstream file("input.txt");
for( string s1,s2; getline( getline( file.ignore( numeric_limits< streamsize >::max(), '"' ), s1, '"' ) >> Char<':'> >> Char<'"'>, s2, '"' ); )
cout << "S1=" << s1 << " S2=" << s2 << endl;
маленькая вспомогательная функция Char:
template< char C >
std::istream& Char( std::istream& in )
{
char c;
if( in >> c && c != C )
in.setstate( std::ios_base::failbit );
return in;
}
#include <regex>
#include <iostream>
using namespace std;
const string text = R"(
XXXXXXXXXXXXXXXXXXXXXXXXXXXX"string1":"string2"XXXXXXXXXXXXXXXXXXXXXXXXXX"string3" :"string4" XXXXXXXXXXXXXXXXXXXXXXXXXXXX...
XXXXXXXXXXXXXXXXXXXXXXXXXXXX"string5": "string6"XXXXXXXXXXXXXXXXXXXXXXXXXX"string7" : "string8" XXXXXXXXXXXXXXXXXXXXXXXXXXXX...
)";
int main() {
const regex pattern{R"~("([^"]*)"\s*:\s*"([^"]*)")~"};
for (auto it = sregex_iterator(begin(text), end(text), pattern); it != sregex_iterator(); ++it) {
cout << it->format("First: $1, Second: $2") << endl;
}
}
Output:
First: string1, Second: string2
First: string3, Second: string4
First: string5, Second: string6
First: string7, Second: string8
Два шага:
Сначала мы должны найти положение :
и соединить строку на две части:
string first = theEntireString.substr(0, theEntireString.find(":"));
string second = theEntireString.substr(theEntireString.find(":") + 1);
Теперь нам нужно удалить ""
:
string final_first(first.begin() + 1, first.end() - 1);
string final_second(second.begin() + 1, second.end() - 1);
std::string string1 = theEntireString.substr(1, theEntireString.find("\":\"")-1);