繁体   English   中英

使用ignore()通过getline跳过/ n的问题

[英]problem using ignore() to skip /n with getline

我注意到了一些关于ignore()的帮助。 我有一个包含三行文本的文本文件

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

我需要用这样的句子将它读入字符串 arrays :

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++;

     }

不像最初想象的那么容易。

而且,有许多可能的解决方案。 我向您展示了 3 个复杂度越来越高的解决方案,但它们都使用相同的算法。

  1. 我们将完整的文本文件读入std::string
  2. 我们将所有换行符 '\' 替换为空格 ' '
  3. 我们用“.\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

这是在代码中使用注释来解释这些步骤的一种方法。

#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 '<'
    }
}

Output:

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM