例如,我用以下文件读取文件:
Cat Dog Monkey 1234
A,A #$%& No
而且我需要将每个单词保存在另一个(是另一个)文件中,例如:
word 1: cat
word 2: Dog
word 3: Money
word 4: 1234
word 1: A,A
word 2: #$%&
word 3:
word 4: No
我只是示例中的ofstream基本代码,因此,如果有人可以帮助我,那将很棒。还有一种方法可以保存这些单词并进行比较(如果以数字,字母,符号开头或有逗号)? (,)。我知道这是一个漫长的请求,因此每条信息都会受到赞赏(> n
解决方案相当简单。
首先,我们打开文件并检查是否可行。我们在for
循环中逐行读取源文件,并使用std::getline
提取完整的行。
为了方便处理和使用std::istream_iterator
,我们将其放入std::istringstream
。
为了将数据从源格式转换为目标格式,我们将使用(为此目的,专用功能std::transform
。
基本上就是它,
请参见下面的简单示例:
#include <iostream>
#include <fstream>
#include <iterator>
#include <string>
#include <sstream>
#include <algorithm>
const std::string sourceFileName{ "source.txt" };
const std::string resultFileName{ "result.txt" };
int main() {
// Open source file and check, if it could be opened
if (std::ifstream sourceStream(sourceFileName); sourceStream) {
// open destination file and check, if it could be opened
if (std::ofstream resultStream(resultFileName); resultStream) {
// Read the source file line by line
for (std::string line{}; std::getline(sourceStream, line); ) {
// Put the just read file into a istringstream for easier processing
std::istringstream iss(line);
// Read every sub-string in the istringstream and convert it to the expected result, using a stateful Lambda
std::transform(std::istream_iterator<std::string>(iss), {}, std::ostream_iterator<std::string>(resultStream, "\n"),
[i = 1U](const std::string& s) mutable { return "word " + std::to_string(i) + " " + s; });
resultStream << std::endl;
}
}
else std::cerr << "\n*** Error: Could not open source file '" << sourceFileName << "'\n\n";
}
else std::cerr << "\n*** Error: Could not open result file '" << resultFileName << "'\n\n";
return 0;
}
编辑
我刚刚指出,您也想分割两个连续的空格。为此,我创建了一个拆分功能。该函数将如下所示
#include <iostream>
#include <fstream>
#include <iterator>
#include <string>
#include <sstream>
#include <algorithm>
#include <vector>
const std::string sourceFileName{ "r:\\source.txt" };
const std::string resultFileName{ "r:\\result.txt" };
std::vector<std::string> split(std::string& s) {
// Result as vector of string
std::vector<std::string> splitted;
// Start searching at the beginning
size_t startPos{ 0U };
// Search all spaces
for (size_t foundPos{ 0U }; (foundPos = s.find(' ', startPos)) != std::string::npos; ) {
// And store the sub string before the found space
splitted.push_back(s.substr(startPos, foundPos - startPos));
startPos = foundPos+1;
}
// At the end of the string there is no space. So add last sub-string
splitted.push_back(s.substr(startPos));
return splitted;
}
int main() {
// Open source file and check, if it could be opened
if (std::ifstream sourceStream(sourceFileName); sourceStream) {
// open destination file and check, if it could be opened
if (std::ofstream resultStream(resultFileName); resultStream) {
// Read the source file line by line
for (std::string line{}; std::getline(sourceStream, line); ) {
std::vector vs = split(line);
// Read every sub-string and convert it to the expected result, using a stateful Lambda
std::transform(vs.begin(), vs.end(), std::ostream_iterator<std::string>(resultStream, "\n"),
[i = 1U](const std::string& s) mutable { return "word " + std::to_string(i) + " " + s; });
resultStream << std::endl;
}
}
else std::cerr << "\n*** Error: Could not open source file '" << sourceFileName << "'\n\n";
}
else std::cerr << "\n*** Error: Could not open result file '" << resultFileName << "'\n\n";
return 0;
}
并且,如果您想使用C ++核心技术,则可以使用正则表达式和std::sregex_token_iterator
。这个东西是用来分割字符串的,也可以使用。
这导致了一个优雅的C ++解决方案:
#include <iostream>
#include <fstream>
#include <iterator>
#include <string>
#include <sstream>
#include <algorithm>
#include <vector>
#include <regex>
const std::string sourceFileName{ "r:\\source.txt" };
const std::string resultFileName{ "r:\\result.txt" };
const std::regex re{R"([ ]{1})"};
int main() {
// Open source file and check, if it could be opened
if (std::ifstream sourceStream(sourceFileName); sourceStream) {
// open destination file and check, if it could be opened
if (std::ofstream resultStream(resultFileName); resultStream) {
// Read the source file line by line
for (std::string line{}; std::getline(sourceStream, line); ) {
// Read every sub-string and convert it to the expected result, using a stateful Lambda
std::transform(std::sregex_token_iterator(line.begin(), line.end(), re, -1), {}, std::ostream_iterator<std::string>(resultStream, "\n"),
[i = 1U](const std::string& s) mutable { return "word " + std::to_string(i) + " " + s; });
resultStream << std::endl;
}
}
else std::cerr << "\n*** Error: Could not open source file '" << sourceFileName << "'\n\n";
}
else std::cerr << "\n*** Error: Could not open result file '" << resultFileName << "'\n\n";
return 0;
}