0

I'm writing a basic chess program to calculate how many sets you can make with the given chess figures. The data file:

4
22 3 5 6 2 0
1 1 1 1 1 1
8 4 4 4 1 2
5 3 3 3 0 2

The code:

#include <iostream>
#include <fstream>
#include <vector>

int main
(int argc, char *argv[])
{
    std::fstream data_file;
    size_t i, k;
    std::vector<long> chess;
    long t, n;

    data_file.open("U1.txt", std::ios::in);

    data_file >> n;

    for (i = 0; i < n; i++)
        chess.push_back(0);

    for (i = 0; i < n; i++) {
        for (k = 0; k < 6; k++) {
            data_file >> t;
            std::cout << t << " ";
            chess[k] += t;
        }
        std::cout << std::endl;
    }

    data_file.close();

    for (int i = 0; i < 6; i++)
        std::cout << chess[i] << " ";
    std::cout << std::endl;

    data_file.open("U1rez.txt", std::ios::out);
    data_file << n;
    std::cout << n << std::endl;
    data_file.close();

    return EXIT_SUCCESS;
}

The output:

22 3 5 6 2 0 
1 1 1 1 1 1 
8 4 4 4 1 2 
5 3 3 3 0 2 
36 11 13 14 3 4 
4

Why am I getting 3 and 4 at the end result just after 36, 11, 13 and 14 at line 5? When I print the test values I seem to get the right numbers but something goes terribly wrong in the addition of them in the vector container.

4

2 回答 2

5
for (i = 0; i < n; i++)
    chess.push_back(0);

. . .

    for (i = 0; i < n; i++) {
    for (k = 0; k < 6; k++) {
        data_file >> t;
        std::cout << t << " ";
        chess[k] += t;
    }
    std::cout << std::endl;
}

在这里,您在向量中初始化了 n(=4) 个位置,但在这里您正在访问导致加法问题的向量国际象棋的索引 4 和 5。

于 2012-05-04T08:55:11.413 回答
1

顺便说一句,如果你放弃 C 强加的一些规则,你会更轻松地使用 C++。

  • C++ API 使用范围有界的资源管理;也就是说,这里不需要显式关闭文件句柄,因为当在声明的作用域的末尾调用它的析构函数时,该类会为您执行此操作。
  • 首选std::cout << "\n"std::cout << std::endl除非您实际上打算插入换行符并刷新缓冲区。许多 C++ 程序员仍在使用printf,我个人认为它比 C++ 对 IO 的丑陋标准解决方案要优雅得多——随意使用printf
  • for (size_type i = 0; ... ; ...)当您在使用变量的位置(例如)而不是在方法的开头声明变量时,您是否发现代码更易于管理和阅读?这也允许编译器对寄存器的使用做出更好的选择,因为它有更多关于临时变量范围的信息。

以下是 C++11 的一些功能,它们也可以为您节省一些时间:

  • 自动类型推断:当编译器可以推断出变量的类型时,您不必显式指定它;您可以auto改用(例如auto x = parse_data();)。
  • Range-for:如果您在提供全局定义begin()end()(例如任何标准容器)的容器上进行操作,则不要这样:

typedef typename container_type::const_iterator iter;
for (iter i = begin(container), iter l = end(container); i != l; ++i) { ... }

你可以这样做:

for (const auto& x : container) { ... }

我只是想给你一些快速的指示,可以节省你一些时间。

于 2012-05-04T09:42:39.083 回答