从C ++读取。文件

时间:2014-07-20 05:00:37

标签: c++ file-io

我们假设我有以下文件: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 ++编程语言(或一般的编程)很陌生, 所以对此有任何帮助将不胜感激。

1 个答案:

答案 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();