【问题标题】:Read 11th coloumn of numbers from a file and average it?(c++)从文件中读取第 11 列数字并取平均值?(c++)
【发布时间】:2015-02-25 07:52:26
【问题描述】:

这是我的初学者 C++ 作业, 我有一个包含 12 列数字和 50 行的文件。

我被要求找到第 11 列数字的平均值并将其显示在标准输出中。

它是初学者课程,因此不允许使用矢量等高级主题。

我试图为每个列创建 12 个变量并使用 while 循环读取第 11 列,但不知道如何将第 11 列的所有数字添加到该变量中。

我使用的while循环是这样的:

while(inputfile >> col1 >> col2>> col3>> col4>> col5>> col6>> col7>>
     col8>> col9>> col10>> col11>> col12 ) 
{ cout<< col11 << endl; }

旁注:上面的所有 col 都是 int 变量。而inputfileifstream 文件对象

上面的循环会打印出整列 11,但我不知道如何将 50 行(即 50 个数字)的整列 11 相加来求平均值(将总数除以 50)

上面的方法也可能是错误的

我们将不胜感激。

希望尽快回复。

提前致谢。 :)

【问题讨论】:

  • 使用变量来保存总和。最初为 0,然后在每个循环中将第 11 列的值添加到它。

标签: c++ c++11 text-files filestream ifstream


【解决方案1】:

由于唯一的答案是错误的,并且评论可能缺少重要线索...

您需要保留第 11 列值的总和。我还会跟踪计数,尽管在您的情况下,您可以跳过该计数并硬编码值50。所以你需要的位是:

int total = 0;
int count = 0;

然后在你的阅读循环中:

while (...) {
    total += col11; // keep a running total
    ++count; // add 1 to count
}

然后为了计算平均值,你将一个除以另一个。

但是,这有点棘手。如果直接这样做,则将一个int 除以另一个int,然后将结果截断为int。例如。 1/2 会给你0,这不是你的意思(0.5)。

您需要使用强制转换将至少一个值转换为double除法完成之前:

double average = static_cast<double>(total) / count;

查看完整代码here

解决除法问题的其他方法是首先将totalcount 存储为double,尽管我发现这具有误导性,因为它们实际上是整数,或者如果您坚持直接使用50 ,你可以只做average = total / 50.050.0 是一个double 值)。

由于您是初学者,我也将花一点时间建议您不要使用 using namespace std;use of endl,这不仅是出于性能原因,也是为了通过分离编写换行符的不相关操作来使代码更清晰并刷新一个流。

【讨论】:

  • 嗨,非常感谢,但我想知道,在这种情况下,为什么我更喜欢预增量而不是后增量?
  • 在这种特殊情况下,它并没有太大的区别。也就是说,编译器将优化掉差异。 ++i 只是在适当位置增加 ii++ 增加 i,但返回其原始值的副本。既然你不使用以前的值,为什么还要创建它呢? ints 不会太贵,而且几乎可以肯定已经优化了,但对于复制成本高或处于紧密循环中的对象来说,这可能很重要。因此我更喜欢++i,除非我有实际理由使用i++。是的,语言名称是wrong
  • 我也想知道 cerr 对象,它是什么,何时何地使用它,它与 cout obj 有什么不同,还有 while 循环必须在这里或它可以是也完成了其他循环??
  • @LovePatel std::cerrstd::cout 基本相同,只是它写入 stderr 输出(通常与 stdout 相同的终端,除非您已重定向其中一个)并且它在每个写操作。它旨在立即向用户报告错误。 for while循环是等价的,你总是可以把一个改成另一个,它们只是语法上的方便。
【解决方案2】:

使用变量存储总和和计数并得到平均值

int sum = 0;
int count = 0;
double average = 0;
cout << "Calculating Average for: \n";
while(inputfile >> col1  >> col2  >> col3 >> col4 >> col5
                >> col6  >> col7  >> col8 >> col9 >> col10 
                >> col11 >> col12 )  { 
    cout << col11 << " ";
    sum += col11;
    ++count;
}
cout << " \n";
average = static_cast<double>(sum)/count;
cout << "Sum: "     << sum << "\n";
     << "Count: "   << count << "\n";
     << "Average: " << average << endl;

【讨论】:

  • 由于这是一个针对初学者的答案,我强烈建议您编辑您的答案以遵循良好做法,例如using std:: explcitlyavoiding endl,而且我个人更喜欢前后对比count 的增量 - 在这种情况下没什么大不了的,但对于复制成本更高的对象来说是一个好习惯。此外,是否最好只为家庭作业问题提供完整的代码答案?您可以给出必要的部分,并附上解释,然后让提问者整合。
  • (还值得指出的是,虽然我确实同意 Dietmar 的论点。endl,但出于代码清晰而不是性能原因,我更多地避免使用它;它经常被误解和误用,我更喜欢当我真正的意思时,只需明确flush。)
  • 更令人担忧的是,您的代码完全错误地计算了平均值。 sum/count 是一个整数除法,因此会将结果截断为 int 之前转换为 double!
  • 我同意你的观点@BoBTFish 进行了一些编辑,但有一件事,对于除std 之外没有任何命名空间的代码使用std:: 是不必要的。
  • 仍然是一个非常糟糕的习惯:在大多数情况下这是一个问题,并且在没有当前名称冲突风险的情况下没有任何好处。除了最琐碎的 3 行代码示例之外,所有应该都使用命名空间,因此您的代码将来很有可能会有命名空间或者它是一个适合初学者的代码示例,我们不想学习坏习惯的人。当您知道函数的来源时,它会使代码更容易阅读。人们了解标准库函数的语义,但可能不会假设您使用的是没有 std:: 前缀的函数。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-02-08
  • 1970-01-01
  • 2018-07-06
  • 1970-01-01
  • 1970-01-01
  • 2015-09-10
  • 2020-07-11
相关资源
最近更新 更多