Как завершить l oop в конце строки? - PullRequest
0 голосов
/ 10 апреля 2020

Я пытаюсь взять все параметры из этого URL (oq, aqs, et c). Я использую функцию для извлечения каждого из них в отдельности. Тем не менее, я не могу понять, как прекратить l oop, как только он достигнет окончательного варианта. Я думаю, что устанавливаю res в текущую позицию, но я не уверен. Я пытался прекратить его, когда !(res == url.length()), но это не сработало. Кто-нибудь может помочь с этим?

Кроме того, я был бы признателен за совет о том, как масштабировать это для нескольких URL-адресов. Я предполагаю, что должен использовать другой l oop, но я все еще изучаю их.

#include <iostream>
#include <fstream>
#include <string>

using namespace std;

string getKey(const string keyval, size_t start, size_t& second);

using namespace std;

int main()
{
    int count = 0;
    size_t res;
    string url = "https://www.google.com/search?q=where+food+near+me&oq=where+food+near+me&aqs=chrome..69i57j0l5.8995j0j9&sourceid=chrome&ie=UTF-8";
    while(count < 20){
        cout << getKey(url,0, res) << endl;
        while (!(res == url.length()){
        cout << getKey(url,res, res) << endl;
            ++count;
        }
        cout<< res << endl;
        ++count;
   }

    return 0;
}

string getKey(const string keyval, size_t start, size_t& second)
{
    size_t first;
    string result;
    if(start == 0){
        first = keyval.find('&');
    }
    else{
        first = start;
    }
    first = first + 1;
    second = keyval.find('&' , first);
    result = keyval.substr(first, second - first);
    return result;
}

ОБНОВЛЕНИЕ

#include <iostream>
#include <fstream>
#include <algorithm>

using namespace std;

namespace helpers {
size_t getDomainName(const string str, string& result);
size_t getKeyVal(const string str, const size_t start_pos, string& result);
bool getKey(const string &keyval, size_t start, size_t& second, string &result);
string getVal(const string keyval);
}
using namespace helpers;


int main() {
    string fileName;
    int count = 0;
    int total_query = 0, total_length = 0, avg_length = 0;
    string URL,str;
    int total_Urls = 0;
    string line;
    string res,key,val;
    cout << "Please input the name of the file: " << endl;
    cin >> fileName;
    ifstream fin;
    fin.open (fileName);
    if (fin.is_open()){
        cout << "File opened successfully...\n";
    }
    else {
        cout << "File failed to open...\n";
        return 0;
    }

    // Finding total URL count...
    for (string URL; fin >> URL;){
       ++total_Urls;
    }
    //cout << total_Urls << endl;
    fin.close();
    fin.open(fileName);

    count = 0;

    //average length of URL
    while (count < total_Urls){
        fin >> str;
       // cout << "The length of the URL: "<<str.length() <<endl;
    total_length += str.length();
        ++count;
    }
    avg_length = total_length / total_Urls;
   // cout << "Average length: "<< avg_length << endl;

    fin.close();
    fin.open(fileName);



    count = 0;

    //average length of query
    while(count < total_Urls){
        fin >> URL;
        getKeyVal(URL, 0, res);
        res = res.substr(2);
        replace(res.begin(), res.end(), '+', ' ');
       // cout << "Test: " << res << endl;
       // cout << "Length of Query: " << res.length() << endl;
        total_query += res.length();
        ++count;

    }
    int avg_query_length = total_query / count;
    //cout << "Average length of query: " << avg_query_length << endl;

    fin.close();
    fin.open(fileName);

    //dealing with options

   /* while(count < 20){
         cout << getKey(url,0, res) << endl;
         while (count < 5){
         cout << getKey(url,res, res) << endl;
             ++count;
         }
         cout<< res << endl;
         ++count;
    } */

    count = 0;
    string value;
    size_t res2 = 0;
    while (count < total_Urls){
        fin >> URL;

    while ((count < 20) && getKey(URL, res2, res2, value)){
        cout << value << endl;
        ++count;
    }
    }

    cout << "Statistics for <" <<fileName << ">" << endl;
    cout << "--------------------------" << endl;
    cout << "Number of Queries: " << total_Urls << endl;
    cout << "Average length of URL: " << avg_length << endl;
//    cout << "Average length of Query String: " << avg_query;

    return 0;
}

namespace helpers {

size_t getDomainName (const string str, string& result){
size_t first, second;
first = str.find('/');
first = str.find('/', first + 1);
second = str.find('/', first + 1);
result = str.substr(first + 1, second - (first + 1));
return second;
}
size_t getKeyVal(const string str, const size_t start_pos, string& result){
    size_t first, second;
    if(start_pos == 0) {
        first = str.find('?');
    }
    else {
        first = start_pos;
    }
    second = str.find('&', first + 1);
    result = str.substr(first + 1, second - (first + 1));
    return second;
}
bool getKey(const string &keyval, size_t start, size_t& second, string &result)
{
    result = "";

    if (start == 0) {
        if ((start = keyval.find('?')) == string::npos)
            return false;
        ++start;
    }
    else if (start >= keyval.size())
        return false;

    size_t end = keyval.find('&', start);
    if (end != string::npos) {
        result = keyval.substr(start, end - start);
        second = end + 1;
    }
    else {
        result = keyval.substr(start);
        second = keyval.size();
    }
    return true;
}

}
string getVal(const string keyval){
    size_t first;
    string result;
    first = keyval.find('=');
    first = first + 1;
    result = keyval.substr(first);
    replace(result.begin(), result.end(), '+', ' ');
    return result;
}


1 Ответ

1 голос
/ 10 апреля 2020

Вы не учитываете, что при обнаружении последнего & последующий вызов find('&') вернет std::string::npos, то есть -1, а не длину строки, как вы ожидали. Таким образом, вы не можете правильно вернуть последнюю пару key=value.

Я бы предложил изменить функцию, чтобы она возвращала bool, если следующий ключ не найден. Затем вы можете разбить l oop, когда функция вернет false. При выходе res должно быть установлено в местоположение следующего токена после найденного &, а не в &.

Попробуйте что-то вроде этого:

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

bool getKey(const string &keyval, size_t start, size_t& second, string &value);

int main()
{
    int count = 0;
    string url = "https://www.google.com/search?q=where+food+near+me&oq=where+food+near+me&aqs=chrome..69i57j0l5.8995j0j9&sourceid=chrome&ie=UTF-8";
    string value;
    size_t res = 0;
    while ((count < 20) && getKey(url, res, res, value)) {
        cout << value << endl;
        ++count;
    }

    return 0;
}

bool getKey(const string &keyval, size_t start, size_t& second, string &result)
{
    result = "";

    if (start == 0) {
        if ((start = keyval.find('?')) == string::npos)
            return false;
        ++start;
    }
    else if (start >= keyval.size())
        return false;

    size_t end = keyval.find('&', start);
    if (end != string::npos) {
        result = keyval.substr(start, end - start);
        second = end + 1;
    }
    else {
        result = keyval.substr(start);
        second = keyval.size();
    }
    return true;
}

Вывод:

q=where+food+near+me
oq=where+food+near+me
aqs=chrome..69i57j0l5.8995j0j9
sourceid=chrome
ie=UTF-8

Live Demo

...