简体   繁体   English

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

[英]How to replace specific numbers by another number in a text file (C++)

First, I want to mention that I'm completely new to C++, so it's possible that I've overlooked any obvious solutions.首先,我想提一下,我对 C++ 完全陌生,因此我可能忽略了任何明显的解决方案。

My task is to replace any non-zero number with 1.我的任务是用 1 替换任何非零数字。

The file looks like this:该文件如下所示:

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)

and should turn into:并且应该变成:

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)

My idea was to start out with a string replacement code.我的想法是从字符串替换代码开始。 I tried the following:我尝试了以下方法:

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

This gives back:这会返回:

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,...
  • which is the opposite of what I want (not entirely).这与我想要的相反(不完全)。 So, I thought it would be easy to declare toreplace and replacewith as floats and use != 0 , which didn't work, especially because I can't define text as float because it contains ";".所以,我认为很容易将toreplacereplacewith声明为浮点数并使用!= 0 ,这不起作用,特别是因为我无法将text定义为浮点数,因为它包含“;”。 (Do I need to remove this delimiter? I would still need it in the final text file.) (我需要删除这个分隔符吗?我仍然需要在最终的文本文件中使用它。)

  • The other problem in that code is that it replaces every zero, which includes "0.236223" turning into "1.236223".该代码中的另一个问题是它替换了每个零,其中包括“0.236223”变成“1.236223”。 I assume this wouldn't matter when eventually working with floats instead of strings.我认为这在最终使用浮点数而不是字符串时无关紧要。

Is this the right approach to the given task, or would it be better to do it a different way?这是完成给定任务的正确方法,还是以不同的方式执行它会更好? Thanks for any help given.感谢您提供的任何帮助。

EDIT: There was a ";"编辑:有一个“;” at the end of each line, which I didn't want and used the string::pop_back() function to resolve the problem.在每一行的末尾,我不想要并使用 string::pop_back() 函数来解决问题。

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

If you are able to simplify your input file the solution can be one-liner.如果您能够简化输入文件,则解决方案可以是单行的。

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

If you have to stick with the ';'如果你必须坚持使用';' delimiter it can be done with a two-liner:分隔符它可以用两行来完成:

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

And, just to be complete.而且,只是为了完成。 The solution with a regex.用正则表达式解决。 The regex gives you the ability to specify more precisely what you want to search:正则表达式使您能够更精确地指定要搜索的内容:

And the result is also an one-liner (one Statement)而且结果也是单行(one Statement)

Please see:请参见:

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

If you do not want to have the trailing ';'如果你不想有尾随的 ';' then you can use.那么你可以使用。

std::experimental::make_ostream_joiner(std::cout,";"),

instead of the std::ostream_iterator.而不是 std::ostream_iterator。

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

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