C ++从文本文件中查找不完整的字符串

时间:2016-01-20 16:55:56

标签: c++ string

我有一个程序可以读取文本文件并从中解析信息,我正在尝试完成这样的任务:

一个文本文件,其中包含大约500个字符的数据,在这个数据中有如下用户名:

this_just_some_random_data_in_the_file_hdfhehhr2342t543t3y3y
_please_don't_mind_about_me(username: "sara123452")reldgfhfh
2134242gt3gfd2342353ggf43t436tygrghrhtyj7i6789679jhkjhkuklll

问题是我们只需要查找和编写 sara123452来自该文本文件的字符串。用户名当然是未知的,并且没有固定的长度。

这是我到目前为止所做的事情:

std::string Profile = "http://something.com/all_users/data.txt";
std::string FileName = "profileInfo.txt";
std::string Buffer, ProfileName;
std::ifstream FileReader;

DeleteUrlCacheEntryA(Profile .c_str());
URLDownloadToFileA(0, Profile .c_str(), FileName.c_str(), 0, 0);

FileReader.open(FileName);
if (FileReader.is_open()) 
{
    std::ostringstream FileBuffer;
    FileBuffer << FileReader.rdbuf();
    Buffer= FileBuffer.str();
    if (Buffer.find("(username: ") != std::string::npos) {
       cout << "dont know how to continue" << endl;
    }
    FileReader.close();
    DeleteFileA(FileName.c_str());
}
else {
}
cin.get();

那么如何获取用户名字符串并将其分配/复制到ProfileName字符串?

2 个答案:

答案 0 :(得分:1)

我相信您正在寻找的内容类似于下面的代码 - 可能需要进行少量调整才能解释所引用的用户名。这里的关键是要记住你的Buffer变量是一个std :: string,一旦你有明确的开始和结束就可以使用substring。

std::size_t userNameStartIndex, userNameEndIndex

...

userNameStartIndex = Buffer.find("(username: ")) + 11;

if (userNameStartIndex != std::string::npos) {
   userNameEndIndex = Buffer.find(")", userNameStartIndex);

   if (userNameEndIndex != std::string::npos)
   {
       ProfileName = Buffer.substr(userNameStartIndex, userNameEndIndex - userNameStartIndex)
   }
}

答案 1 :(得分:0)

还有很多其他方法可以做到这一点,但我觉得这个方法不那么痛苦。

#include <regex>
#include <iostream>
#include <string>
#include <fstream>
using namespace std;

struct Profile
{   // ...
    string name;
};

int main(int argc, const char * argv[])
{

    std::cout.sync_with_stdio(false); // optional

    // read from file
    string filename {"data1.txt"};
    ifstream in {filename};

    vector<Profile> profiles;
    // tweaks this pattern in case you're not happy with it
    regex pat {R"(\(username:\s*\"(.*?)\"\))"};

    for (string line; getline(in,line); ) {

        Profile p;
        sregex_iterator first(cbegin(line), cend(line), pat);
        const sregex_iterator last;

        while (first != last) {
            // By dereferencing a first, you get a smatch object.
            // [1] gives you the matched sub-string:
            p.name = (*first)[1]; // (*first)[1] = sara123452
            profiles.push_back(p);
            ++first;
        }
    }

    // Test
    for (const auto& p : profiles)
       cout << p.name << '\n';

}