如何用文本文件(C+;+;)中的另一个数字替换特定数字 首先,我想说的是,我对C++完全陌生,所以我可能忽略了任何显而易见的解决方案。

如何用文本文件(C+;+;)中的另一个数字替换特定数字 首先,我想说的是,我对C++完全陌生,所以我可能忽略了任何显而易见的解决方案。,c++,replace,floating-point,text-files,C++,Replace,Floating Point,Text Files,我的任务是将任何非零数字替换为1。 该文件如下所示: Some text 0;0;0;0;0;0.236223;0;0;0;0;0;0.312757;0;0;0;0;0;0;0;0;0;0.367119;... (multiple lines) 应该变成: Some text 0;0;0;0;0;1;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;1,... (multiple lines) 我的想法是从字符串替换代码开始。我尝试了以下方法: #include <i

我的任务是将任何非零数字替换为1。

该文件如下所示:

Some text    
0;0;0;0;0;0.236223;0;0;0;0;0;0.312757;0;0;0;0;0;0;0;0;0;0.367119;... (multiple lines)
应该变成:

Some text
0;0;0;0;0;1;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;1,... (multiple lines)
我的想法是从字符串替换代码开始。我尝试了以下方法:

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

int main()
{

  ifstream filein( "input.txt" );
  ofstream fileout( "output.txt" );

  string toreplace = "0";
  string replacewith = "1";

  string text;
  while ( getline( filein, text ) )
  {

    for ( size_t p = text.find( toreplace ); p != string::npos;
      p = text.find( toreplace , p ) )
      text.replace( p, toreplace.length(), replacewith );

    fileout << text << endl;
  }

  return 0;
}
  • 这与我想要的正好相反(并非完全相反)。因此,我认为将
    toreplace
    replacetwith
    声明为浮动并使用
    !=0
    ,它不起作用,特别是因为我无法将
    文本定义为浮点,因为它包含“;”。(是否需要删除此分隔符?在最终文本文件中仍然需要它。)

  • 该代码中的另一个问题是它会替换每一个零,其中包括“0.236223”变为“1.236223”。我想当最终使用浮点而不是字符串时,这并不重要

这是完成给定任务的正确方法,还是采用不同的方式更好?感谢您的帮助。


编辑:每行末尾都有一个“;”,这是我不想要的,我使用了string::pop_back()函数来解决问题。

如果您能够简化输入文件,那么解决方案可以是一行

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

int main()
{
    std::ifstream filein("./data/input.txt"); // Contains 1. 2.3 0. 3.2
    std::ofstream fileout("./data/output.txt"); // Should contain 1. 1. 0. 1.

    std::replace_copy_if(std::istream_iterator<double>(filein), std::istream_iterator<double>(), std::ostream_iterator<double>(fileout," "),
        [](auto v) {return v != 0.; }, 1.);

    return EXIT_SUCCESS;
}
#包括
#包括
#包括
#包括
int main()
{
std::ifstream filein(“./data/input.txt”);//包含1.2.3 0.3.2
std::ofstream fileout(“./data/output.txt”);//应该包含1.1.0.1。
std::replace_copy_if(std::istream_iterator(filein)、std::istream_iterator()、std::ostream_iterator(fileout)(“”),
[](自动v){return v!=0.},1.);
返回退出成功;
}
如果你必须坚持使用“;”分隔符可以使用两行程序完成:

#include <iostream>
#include <sstream>
#include <iterator>
#include <algorithm>
#include <fstream>

int main()
{
    std::ifstream filein("./data/input.txt"); // Contains 1. 2.3 0. 3.2
    std::ofstream fileout("./data/output.txt"); // Should contain 1. 1. 0. 1.
    std::stringstream replaced;
    std::replace_copy_if(
        std::istream_iterator<char>(filein), 
        std::istream_iterator<char>(),
        std::ostream_iterator<char>(replaced), 
        [](auto v) { return v == ';'; }, 
        ' ');

    std::replace_copy_if(
        std::istream_iterator<double>(replaced), 
        std::istream_iterator<double>(),
        std::ostream_iterator<double>(fileout,";"),
        [](auto v) {return v != 0.; }, 
        1.);

    return EXIT_SUCCESS;
}
#包括
#包括
#包括
#包括
#包括
int main()
{
std::ifstream filein(“./data/input.txt”);//包含1.2.3 0.3.2
std::ofstream fileout(“./data/output.txt”);//应该包含1.1.0.1。
std::stringstream被替换;
std::如果需要,则替换副本(
std::istream_迭代器(filein),
std::istream_迭代器(),
std::ostream_迭代器(已替换),
[](自动v){return v==';';},
' ');
std::如果需要,则替换副本(
std::istream_迭代器(已替换),
std::istream_迭代器(),
std::ostream_迭代器(fileout,“;”),
[](自动v){返回v!=0;},
1.);
返回退出成功;
}
#包括
#包括
#包括
使用名称空间std;
int main()
{
ifstream filein(“input.txt”);
流文件输出(“output.txt”);
字符串toreplace=“0”;
字符串替换为=“1”;
字符串文本,新文本=”;
while(getline(filein,text))
{
新文本=”;
双数;
while(sscanf_s(text.c_str(),%lf;,&num))
{
if(num)
新文本+=“1;”;
其他的
新文本+=“0;”;
while(text.length()&&text.at(0)!=';')
{
文本。擦除(0,1);
}
文本。擦除(0,1);
if(text.empty())
打破
}

fileout和,只是为了完整。带有正则表达式的解决方案。正则表达式使您能够更精确地指定要搜索的内容:

结果也是一行(一条语句)

请参阅:

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

const std::string testData{"0;0;0;0 ; 0;0.236223;0;0;0;0;0;0.312757;0;0;0;0;0;0;0;0;0;0.367119"};

// This is, what we would like to match. Any number, int or double
const std::regex re{"([-+]?[0-9]*\\.?[0-9]+([eE][-+]?[0-9]+)?)"};

int main()
{
    std::transform(
        std::sregex_token_iterator(testData.begin(), testData.end(), re, 1),
        std::sregex_token_iterator(),
        std::ostream_iterator<int>(std::cout,";"),
        [](const std::string& s) -> int { double d=stod(s); return d==0.0 ? 0 : 1; }
    );
    return 0;
}

而不是STD::OfLealTyrBuix.< /P>而我通常不建议使用正则表达式,这可能是一种可以很好地使用的情况。请参见使用标准C++替换的信息。这里的一个根本问题是不能将浮点值进行比较。您可以在数据中读取数字,然后替换。值为1.0的接近零值。正则表达式必须小心前导零浮点(0.5)或带零的数字,如1024。非常感谢您的建议。我将研究正则表达式。但这有一个问题,因为它假设值仅用空格分隔。问题中的示例不是这样,值用分号分隔。这段代码为我生成了一个空文件,我将有一个她后来看了看。但是它似乎对原始的2行csv文件有效,希望它忽略了第2行。谢谢,这段代码工作得很好。但是它对原始csv文件工作得更好,因为它删除了txt文件中包含的文本。然而,最终使用csv文件是我的目标。我只是认为使用txt文件可能更容易开始使用。我注意到的唯一问题是每行末尾的“;”,这是我不想要的。我现在正在研究这个问题以找到解决方案。在将其写入文件之前,只需使用string::pop_back():这是一个方便的函数。我可能会尝试将“\n”替换为“\n”,但这更有效。它似乎工作得很好。谢谢。我会记住这个正则表达式解决方案。我只需要编辑它就可以读取/输出文件。

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

int main()
{

    ifstream filein("input.txt");
    ofstream fileout("output.txt");

    string toreplace = "0";
    string replacewith = "1";

    string text, new_text="";
    while (getline(filein, text))
    {
        new_text = "";
        double num;

        while (sscanf_s(text.c_str(), "%lf;", &num))
        {
            if (num)
                new_text += "1;";
            else
                new_text += "0;";

            while (text.length() && text.at(0) != ';')
            {
                text.erase(0,1);
            }

            text.erase(0,1);

            if (text.empty())
                break;
        }

        fileout << new_text << endl;
    }

    return 0;
}
#include <iostream>
#include <sstream>
#include <regex>
#include <iterator>

const std::string testData{"0;0;0;0 ; 0;0.236223;0;0;0;0;0;0.312757;0;0;0;0;0;0;0;0;0;0.367119"};

// This is, what we would like to match. Any number, int or double
const std::regex re{"([-+]?[0-9]*\\.?[0-9]+([eE][-+]?[0-9]+)?)"};

int main()
{
    std::transform(
        std::sregex_token_iterator(testData.begin(), testData.end(), re, 1),
        std::sregex_token_iterator(),
        std::ostream_iterator<int>(std::cout,";"),
        [](const std::string& s) -> int { double d=stod(s); return d==0.0 ? 0 : 1; }
    );
    return 0;
}
std::experimental::make_ostream_joiner(std::cout,";"),