我们假设我有以下文件:wow.txt,其中包含
4 a 1 c
我想做的是我想输出以下内容:
d 1 a 3
将整数更改为相应的字母(d是第4个字母,a是第1个字母 在字母表中),并将字母写入相应的整数 (a是字母表中的第一个字母,c是字母表中的第3个字母)
我从C ++开始使用以下代码。
int main()
{
ifstream inFile;
inFile.open("wow.txt");
ofstream outFile;
outFile.open("sample.txt");
int k, g;
char a, b;
inFile>>k>>a>>g>>b;
outFile<<(char)(k+96)<<(int)a-96<<(char)(g+96)<<(int)b-96
}
inFile.close();
outFile.close();
}
但是在这里,我只能这样做,因为我知道wow.txt中的文字 去整数,字符,整数,字符。 而且,即使我知道模式,如果wow.txt中的文本超长,那么 我无法使用我手动使用的方法解决问题 输入每个输入(定义k,g为整数,a,b为字符,和 然后做inFile&gt;&gt; k&gt;&gt; a&gt;&gt; g&gt;&gt; b;)
另外,我不知道模式,但没有办法 我可以解决它。我想知道是否有C ++ 从给定文本文件中读取输入并确定其类型的函数,所以 我可以在更一般的情况下攻击这类问题。 我对C ++编程语言(或一般的编程)很陌生, 所以对此有任何帮助将不胜感激。
答案 0 :(得分:2)
您正在搜索的术语是解析。它是接受文本并将其转化为有意义的东西的想法。例如,您的C ++编译器与您的程序代码完全相同 - 它读入文本,将其解析为一系列内部表示,然后输出,然后输出二进制代码,运行时执行你写的代码的意图。
在你的情况下,你想要解决它的问题 - 而不是告诉输入流接下来从文件中得到什么,你只需将所有内容提取为文本,然后自己弄清楚(你让流告诉你那里有什么。如果您考虑它,它的文本(或者更确切地说,二进制数据,但足够接近)无论如何都要向下,即使您要求,例如,要从流中读取整数 - - 在这种情况下,流会为您执行整数解析,但它仍然只是正在解析的文本。
这里有一些示例代码(未经测试)可以帮助您入门:
std::ifstream fin("wow.txt");
// Read everything in (works well for short files; longer
// ones could be read incrementally (streamed), but this
// adds complexity
fin.seekg(0, fin.end);
std::size_t size = fin.tellg();
fin.seekg(0, fin.beg);
std::vector<char> text(size);
fin.read(&size[0], size);
fin.close();
// Now 'tokenize' the text (into words, in this case characters)
enum TokenType { Letter, Number };
struct Token {
const char* pos;
std::size_t length;
TokenType type;
};
std::vector<Token> tokens;
for (const char* pos = &text[0]; pos != &text[0] + text.size(); ++pos) {
if (*pos >= 'a' && *pos <= 'z') {
// Letter! (lowercase)
Token tok = { pos, 1, Letter };
tokens.push_back(tok);
// TODO: Validate that the next character is whitespace (or EOF)
}
else if (*pos >= '0' && *pos <= '9') {
Token tok = { pos, 1, Number };
while (*pos >= '0' && *pos <= '9') {
++pos;
++tok.length;
}
tokens.push_back(tok);
// TODO: Validate that the next character is whitespace (or EOF)
}
else if (*pos == ' ' || *pos == '\t' || *pos == '\r' || *pos == '\n') {
// Whitespace, skip
// Note that newlines are normally tracked in order to give
// the correct line number in error messages
}
else {
std::cerr << "Unexpected character "
<< *pos
<< " at position "
<< (pos - &text[0]) << std::endl;
}
}
// Now that we have tokens, we can transform them into the desired output
std::ofstream fout("sample.txt");
for (auto it = tokens.begin(); it != tokens.end(); ++it) {
if (it->type == Letter) {
fout << static_cast<int>(*(it->pos) - 'a') + 1;
}
else {
int num = 0;
for (int i = 0; i != tok.length; ++i) {
num = num * 10 + (tok.pos[i] - '0');
}
// TODO: Make sure number is within bounds
fout << static_cast<char>(num - 1 + 'a');
}
fout << ' ';
}
fout.close();