如何用文本文件中的另一个数字替换特定数字(C ++)

时间:2019-07-16 11:40:12

标签: c++ replace floating-point text-files

首先,我想提一下,我是C ++的新手,所以有可能我忽略了任何明显的解决方案。

我的任务是将任何非零数字替换为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;
}

这回馈了

1;1;1;1;1;1.236223;1;1;1;1;1;1.312757;1;1;1;1;1;1;1;1;1;1.367119,...
  • 这与我想要的东西(并非完全相反)相反。因此,我认为将toreplacereplacewith声明为浮点并使用!= 0会很容易,这没有用,特别是因为我无法将text定义为浮动,因为其中包含“;”。 (是否需要删除此定界符?在最终的文本文件中仍然需要它。)

  • 该代码中的另一个问题是它替换了每个零,其中包括将“ 0.236223”变成“ 1.236223”。我认为当最终使用浮点数而不是字符串时,这无关紧要。

这是对给定任务的正确方法,还是采用其他方法会更好?感谢您提供的任何帮助。

编辑:有一个“;”在每行的结尾处,我并不需要,并使用string :: pop_back()函数来解决问题。

3 个答案:

答案 0 :(得分:0)

如果您能够简化输入文件,则解决方案可以是单行的。

userid = (null OR '')

如果您必须坚持使用';'分隔符可以用两行来完成:

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

答案 1 :(得分:0)

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

答案 2 :(得分: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,";"),

代替std :: ostream_iterator。