使用ignore()跳过n与getline的问题。

问题描述 投票:0回答:1

I heed some help with ignore(). 我有一个文本文件,里面有三行文字。

AMBITIONI DEDISSE SCRIPSISSE IUDICARETUR. ARAS\n
MATTIS IUDICIUM PURUS SIT AMET FERMENTUM. AONEC\n
SED ODIO OPERAE, EU VULPUTATE FELIS RHONCUS.\n

我需要把它读成字符串数组,像这样的句子。

AMBITIONI DEDISSE SCRIPSISSE IUDICARETUR.\n
ARAS MATTIS IUDICIUM PURUS SIT AMET FERMENTUM.\n
AONEC SED ODIO OPERAE, EU VULPUTATE FELIS RHONCUS.\n

我得到的是这样的:

AMBITIONI DEDISSE SCRIPSISSE IUDICARETUR\n
TIS IUDICIUM PURUS SIT AMET FERMENTUM\n
D ODIO OPERAE, EU VULPUTATE FELIS RHONCUS\n

有什么想法吗?

 void sakiniais(){
 sak=0;
  ifstream fv;
  fv.open("tekstas.txt");
  if(fv.fail()) cout<<"Nerastas failas.";
  else{
    while(getline(fv,sakiniai[sak],'.')){
        fv.ignore('\n');
        cout<<sakiniai[sak]<<endl;



       //sak++;

     }
c++
1个回答
0
投票

没有最初想象的那么容易。

而且,有很多可能的解决方案的原因。我向你展示了3个复杂度越来越高的解决方案,但都是使用相同的算法。

  1. 我们将完整的文本文件读入 std::string
  2. 我们将所有的新行''用空格''代替。
  3. 我们用".\n "代替所有点空格". "序列用".\n "代替。
  4. 我们使用定界符""将完整的文本分割成句子。

请注意,第3种解决方案不需要任何循环,而且使用的是现代C++语言元素和算法。但是,没有必要在这里解释它,因为没有人会使用它。

请看。


#include <iostream>
#include <string>
#include <sstream>
#include <iterator>
#include <regex>
#include <algorithm>

std::istringstream fv{ R"(AMBITIONI DEDISSE SCRIPSISSE IUDICARETUR. ARAS
MATTIS IUDICIUM PURUS SIT AMET FERMENTUM. AONEC
SED ODIO OPERAE, EU VULPUTATE FELIS RHONCUS.
)" };

// either 1 or 2 or 3
#define COMPLEXITY 1

#if COMPLEXITY == 1

void replace(std::string& text, const std::string search, const std::string& replace) {
    // Search, if the search string is in the text at all
    size_t pos = text.find(search);

    // Could we find it?
    while (pos != std::string::npos) {

        // We found it. Replace found text
        text.replace(pos, search.length(), replace);

        // Check, if there are more search strings in the text
        pos = text.find(search, pos);
    }
}
int main() {

    // Here we will store the content of the complete text file
    std::string text;
    char c;

    // Read all characters from the text file and store them in one strinf
    while (fv.get(c)) 
        text.push_back(c);

    // Replace all '\n' by space
    replace(text, "\n", " ");

    // Replace all ". " by ".\n"
    replace(text, ". ", ".\n");

    // Put in stringstream for extraction with getline
    std::istringstream iss(text);

    // Here we will store all sentences
    std::vector<std::string> sentences;

    // Read all sentences from stringstream
    std::string line;
    while(std::getline(iss,line)) 
        sentences.push_back(line);

    // Show output
    for (const std::string& s : sentences) 
        std::cout << s << "\n";

    return 0;
}

#elif COMPLEXITY == 2


std::string& replace(std::string& text, const std::string search, const std::string& replace) {
    for (size_t pos{ text.find(search) }; pos != std::string::npos; pos = text.find(search, pos)) {
        text.replace(pos, search.length(), replace);
    }
    return text;
}

int main() {

    // Here we will store the content of the complete text file
    std::string text;

    // Read all characters from the text file and store them in one string
    for (char c{}; fv.get(c); text.push_back(c)) ; // Empty loop body

    // Replace all '\n' by space and replace all ". " by ".\n"
    replace(replace(text, "\n", " "), ". ", ".\n");

    // Put in stringstream for extraction with getline
    std::istringstream iss(text);

    // Here we will store all sentences
    std::vector<std::string> sentences;

    // Read all sentences from stringstream
    for (std::string line; std::getline(iss, line); sentences.push_back(line));  // Empty body

    // Show output
    for (const std::string& s : sentences)  std::cout << s << "\n";

    return 0;
}

#elif COMPLEXITY == 3

std::regex dotSpace(R"(\. )");

int main() {

    // Read the complete text file into one string
    std::string text(std::istreambuf_iterator<char>(fv), {});

    // Replace all '\n' by space andf replace all ". " by ".\n"
    text = std::regex_replace(std::regex_replace(text, std::regex("\n"), " "), dotSpace, ".\n");

    // Get sentences
    std::vector<std::string> sentences(std::sregex_token_iterator(text.begin(), text.end(), dotSpace, -1), {});

    // Show debug output
    std::copy(sentences.begin(), sentences.end(), std::ostream_iterator<std::string>(std::cout);

    return 0;
}
#endif


0
投票

这里有一种方法,用代码中的注释来解释步骤。

#include <algorithm> // replace_copy
#include <iostream>
#include <iterator>  // istreambuf_iterator, back_inserter
#include <string>
#include <vector>

#include <sstream> // istringstream for demo

std::vector<std::string> sakiniais(std::istream& fv) {
    std::vector<std::string> retval;
    std::string all;

    // copy chars from the istream "fv" into the string "all", replacing '\n' with ' '
    std::replace_copy(
        std::istreambuf_iterator<char>(fv), std::istreambuf_iterator<char>{},
        std::back_inserter(all), '\n', ' ');

    // find '.' and store substrings in the vector<string> "retval"
    for(size_t begin=0, end = all.find(".");
        end < all.size();
        begin = end, end = all.find(".", begin))
    {
        ++end; // include '.' in substring

        // store substring
        retval.emplace_back(all.substr(begin, end - begin));

        // skip space following a '.'
        if(end < all.size() && all[end] == ' ') ++end;
    }

    return retval;
}

int main () {
    std::istringstream file(
        "AMBITIONI DEDISSE SCRIPSISSE IUDICARETUR. ARAS\n"
        "MATTIS IUDICIUM PURUS SIT AMET FERMENTUM. AONEC\n"
        "SED ODIO OPERAE, EU VULPUTATE FELIS RHONCUS.\n"
    );

    auto strs = sakiniais(file);

    for(const std::string& s : strs) {
        std::cout << '>' << s << "<\n"; // show string enclosed with '>' and '<'
    }
}

输出。

>AMBITIONI DEDISSE SCRIPSISSE IUDICARETUR.<
>ARAS MATTIS IUDICIUM PURUS SIT AMET FERMENTUM.<
>AONEC SED ODIO OPERAE, EU VULPUTATE FELIS RHONCUS.<
© www.soinside.com 2019 - 2024. All rights reserved.