重新排列分割字符串的顺序并放入变量

时间:2018-11-19 03:13:05

标签: c++ variables split

我有一个文本文件,该文件具有来自3个域的http请求(第一部分来自reddit.com,第二部分来自stackoverflow.com,最后一个来自google.com)。我的任务是在txt文件中重新排列http请求的顺序。例如,顺序将变为,google在第一个,reddit在下,stackoverflow是txt文件中的最后一个数据。

我的想法是使用CreateFile函数打开文件,并使用ReadFile函数读取内容。然后,我将使用定界符“ ------”分割字符串。然后将3个拆分字符串放在3个变量中,以便处理数据。

我的想法可行吗,或者还有其他方法可以解决这个问题? 还要如何将3个拆分后的字符串放入3个变量

提前谢谢!

在文本文件内部

HTTP/1.1 301 Moved Permanently
Retry-After: 0
Location: https://www.reddit.com/
Content-Length: 0
Accept-Ranges: bytes
Date: Mon, 19 Nov 2018 01:47:39 GMT
Via: 1.1 varnish
Connection: close
X-Served-By: cache-pao17440-PAO
X-Cache: HIT
X-Cache-Hits: 0k
X-Timer: S1542592059.341058,VS0,VE0
Cache-Control: private, max-age=3600
Server: snooserv

----------------------------------------
HTTP/1.1 301 Moved Permanently
Content-Type: text/html; charset=UTF-8
Location: https://stackoverflow.com/
Content-Length: 149
Accept-Ranges: bytes
Date: Mon, 19 Nov 2018 01:47:41 GMT
Via: 1.1 varnish
Connection: close
X-Served-By: cache-pao17443-PAO
X-Cache: MISS
X-Cache-Hits: 0
X-Timer: S1542592061.319674,VS0,VE69
Vary: Fastly-SSL
X-DNS-Prefetch-Control: off
Set-Cookie: prov=27060b9e-21ce-fcb4-5b43-bf2f40747e6c;        domain=.stackoverflow.com; expires=Fri, 01-Jan-2055 00:00:00 GMT; path=/; HttpOnly

<head><title>Document Moved</title></head>
<body><h1>Object Moved</h1>This document may be found <a      HREF="https://stackoverflow.com/">here</a></body>
----------------------------------------
HTTP/1.0 411 Length Required
Content-Type: text/html; charset=UTF-8
Referrer-Policy: no-referrer
Content-Length: 1564
Date: Mon, 19 Nov 2018 01:47:48 GMT

<!DOCTYPE html>
<html lang=en>
  <meta charset=utf-8>
  <meta name=viewport content="initial-scale=1, minimum-scale=1, width=device-width">
  <title>Error 411 (Length Required)!!1</title>
  <style>

1 个答案:

答案 0 :(得分:0)

这是我从文件中读取数据时使用的一些常用函数,以及用于解析该特定数据类型或集合的自定义函数。在本示例中,此处未直接使用某些功能,但是无论如何我还是提供了它们,因为这是从文件中检索数据的三种常见方法,以及从长字符串创建一组令牌的两种不同方法。

#include <exception>
#include <string>
#include <vector>
#include <sstream>
#include <iostream>
#include <fstream>
#include <algorithm>

// A basic method to split a string based on a single char delimiter
std::vector<std::string> splitString( const std::string& s, char delimiter ) {
    std::vector<std::string> tokens;
    std::string token;
    std::istringstream tokenStream( s );
    while( std::getline( tokenStream, token, delimiter ) ) {
        tokens.push_back( token );
    }    
    return tokens;
}

// Similar to above but with the ability to use a string as a delimiter as opposed to just a single char
std::vector<std::string> splitString( const std::string& strStringToSplit, const std::string& strDelimiter, const bool keepEmpty = true ) {
    std::vector<std::string> tokens;
    if( strDelimiter.empty() ) {
        tokens.push_back( strStringToSplit );
        return tokens;
    }

    std::string::const_iterator itSubStrStart = strStringToSplit.begin(), itSubStrEnd;
    while( true ) {
        itSubStrEnd = search( itSubStrStart, strStringToSplit.end(), strDelimiter.begin(), strDelimiter.end() );
        std::string strTemp( itSubStrStart, itSubStrEnd );
        if( keepEmpty || !strTemp.empty() ) {
            tokens.push_back( strTemp );
        }

        if( itSubStrEnd == strStringToSplit.end() ) {
            break;
        }
        itSubStrStart = itSubStrEnd + strDelimiter.size();
    }
    return tokens;
}

// This function will open a file, read a single line
// closes the file handle and returns that line as a std::string
std::string getLineFromFile( const char* filename ) {
    std::ifstream file( filename );
    if( !file ) {
        std::stringstream stream;
        stream << "failed to open file " << filename << '\n';
        throw std::runtime_error( stream.str() );
    }

    std::string line;
    std::getline( file, line );

    file.close();

    return line;
}

// This function will open a file and read the file line by line
// storing each line as a string and closes the file then returns
// the contents as a std::vector<std::string>
void getAllLinesFromFile( const char* filename, std::vector<std::string>& output ) {
    std::ifstream file( filename );
    if( !file ) {
        std::stringstream stream;
        stream << "failed to open file " << filename << '\n';
        throw std::runtime_error( stream.str() );
    }

    std::string line;
    while( std::getline( file, line ) ) {
        if( line.size() > 0 )
            output.push_back( line );
    }

    file.close();
}

// This function will open a file and read all of the file's contents and store it into
// a large buffer or a single string and returns that as its output.
void getDataFromFile( const char* filename, std::string& output ) {
    std::ifstream file( filename );
    if( !file ) {
        std::stringstream stream;
        stream << "failed to open file " << filename << '\n';
        throw std::runtime_error( stream.str() );
    }

    std::stringstream buf;
    buf << file.rdbuf();
    output.clear();
    output.reserve( buf.str().length() );
    output = buf.str();
}

// A function to parse the data based on your data types or data sets
// and the criteria that is needed for its layout, format etc. 
void parseDataFromFile( const std::string& fileContents, std::vector<std::string>& output ) {
    std::string delimiter( "----------------------------------------" );
    output = splitString( fileContents, delimiter );

    // More parsing may need to be done here, but this would be according
    // to your specific needs and what you intend to do from this point on.
}

int main() {
    try {
        std::string fileContents;
        getDataFromFile( "test.txt", fileContents );
        std::vector<std::string> tokens;
        parseDataFromFile( fileContents, tokens );

        // This is just temp code to display the file as
        // a vector of strings that were split by your delimiter
        // This is where you would reorder your data and rewrite it
        // back to some file, log, stream, cout, etc. 
        std::cout << "First Token:\n\n";
        for( auto& s : tokens ) {
            if( s != tokens.back() )
                std::cout << s << "\n\nNext Token:\n";
            else
                std::cout << s << '\n';
        }

    } catch( std::runtime_error& e ) {
        std::cerr << e.what() << std::endl;
        return EXIT_FAILURE;
    }
    return EXIT_SUCCESS;
}

从输出中可以看到该程序生成的内容,我已经成功展示了如何根据您的情况所需的分隔符类型分割字符串。从这里开始,您要做的就是根据您的条件对数据进行排序。然后将您的内容记录到流,控制台或其他文件中。