Closed. This question needs to be more
focused。它当前不接受答案。
想改善这个问题吗?更新问题,使其仅关注
editing this post的一个问题。
在10个月前关闭。
Improve this question
例如,我读取了一个文件:
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的基本代码,因此,如果有人可以帮助我,那就太好了。还有一种方法可以保存这些单词,并比较以A开头的数字,字母,符号还是逗号? (,)。
我知道请求时间很长,因此每条信息都会受到赞赏(> n <)
解决方案相当简单。
首先,我们打开文件并检查是否可行。我们在for
-loop中逐行读取源文件,并使用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++核心技术,可以使用regex和
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;
}
我是一名优秀的程序员,十分优秀!