首先,我想提一下,我是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,...
这与我想要的东西(并非完全相反)相反。因此,我认为将toreplace
和replacewith
声明为浮点并使用!= 0
会很容易,这没有用,特别是因为我无法将text
定义为浮动,因为其中包含“;”。 (是否需要删除此定界符?在最终的文本文件中仍然需要它。)
该代码中的另一个问题是它替换了每个零,其中包括将“ 0.236223”变成“ 1.236223”。我认为当最终使用浮点数而不是字符串时,这无关紧要。
这是对给定任务的正确方法,还是采用其他方法会更好?感谢您提供的任何帮助。
编辑:有一个“;”在每行的结尾处,我并不需要,并使用string :: pop_back()函数来解决问题。
答案 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。