【问题标题】:C++ problems reading input file and outputting into an output file using getline()使用 getline() 读取输入文件并输出到输出文件的 C++ 问题
【发布时间】:2019-08-07 03:06:33
【问题描述】:

我有一个介绍 C++ 课程的作业,我很困惑为什么我的 getline 似乎在工作,但它没有将我的函数输出到 outfile.txt。我的老师说我的 getline 语法不正确,但是我很困惑如何。 我的infile.txt 写着:

T & 4
S @ 6
T x 5
R * 5 7
D $ 7
D + 5
R = 4 3
E

还有我的代码:

#include <iostream>
#include <fstream>
#include <cstdlib>
using namespace std;


void draw_rect (char out_char, int rows, int columns); // Draws a rectangle shape

void draw_square (char out_char, int rows); //Draws a square shape

void draw_triangle (char out_char, int rows);// Draws a triangle shape

void draw_diamond (char out_char, int rows); // Draws a diamond shape

int main()
{
    ofstream outfile;
    ifstream infile;
    int row, col;
    bool exit = false;
    char value;
    infile.open("infile.txt");
    outfile.open("outfile.txt");
    if(!infile.good())
    {
        cout << "failed to open\n";
    }else
    {
        string buffer;
        while(!infile.eof() || !exit)
        {
            getline(infile, buffer);
                switch(buffer[0])
                {
                case 'R':
                   value = buffer[2];
                   row = buffer[4];
                   col = buffer[6];
                   draw_rect(value, row, col);
                   break;
                case 'T':
                    value = buffer[2];
                    row = buffer [4];
                    draw_triangle(value, row);
                    break;
                case 'D':
                    value = buffer[2];
                    row = buffer[4];
                    draw_diamond(value, row);
                    break;
                case 'S':
                    value = buffer[2];
                    row = buffer[4];
                    draw_square(value, row);
                    break;
                case 'E':
                    cout << "Files Written.\nExiting." << endl;
                    exit = true;
                    break;
                default:
                    cout << "Invalid input, try again" << endl;
                }
        }
    }
    return  0;

}

void draw_diamond (char out_char, int rows)
{
    ofstream outfile;
    int space = 1;
    space = rows - 1;
    for (int i = 1; i <= rows; i++)
    {
        for (int k = 1; k <= space; k++)
        {
            outfile << " ";
        }
        space--;
        for( int k = 1; k <= 2*i-1; k++)
        {
            outfile << out_char;
        }
        outfile << endl;
    }
    space = 1;
    for (int i = 1; i <= rows; i++)
    {
       for(int k = 1; k <= space; k++)
       {
           outfile << " ";
       }
       space++;
       for(int k = 1; k <= 2*(rows-i)-1; k++)
       {
           outfile << out_char;
       }
       outfile << endl;
    }
}

void draw_triangle (char out_char, int rows)
{
    ofstream outfile;
     for (int i = 0; i < rows; i++)
    {
        for (int j = 0; j <= i; j++)
        {
            outfile << out_char;
        }
        outfile << endl;
}
}

void draw_square (char out_char, int rows)
{
    ofstream outfile;
    for (int i = 0; i < rows; i++)
    {
        for (int j = 0; j < rows; j++)
        {
            outfile << out_char;
        }
        outfile << endl;
    }
}

void draw_rect (char out_char, int rows, int columns)
{
    ofstream outfile;
    for (int i = 0; i < rows; i++)
    {
        for (int j = 0; j < columns; j++)
        {
            outfile << out_char;
        }
        outfile << endl;
    }
}

【问题讨论】:

  • 真诚地,奇怪的是你的老师没有指出问题出在哪里。我只是不明白这种教学是如何运作的。好吧。您不能假设在 main 函数中定义对象会神奇地初始化在本地函数中定义的对象。看draw_diamond函数,你期望ofstream outfile会怎么初始化?
  • C++ 很难学,因为它是。像这里描述的那样,完全不称职的教练不会让事情变得更容易。

标签: c++ file-io getline shapes


【解决方案1】:

以你的一个函数为例:

void draw_rect (char out_char, int rows, int columns)
{
    ofstream outfile;

这会在您的 draw_rect() 函数中声明一个新的 std::ofstream 对象。 draw_rect() 不会打开此 std::ofstream 对象,因此此 draw_rect() 尝试将任何内容写入此 outfile 绝对没有任何作用。

您在您的main() 中创建了一个同名的std::ofstream 对象,并且您确实打开了这一事实,这绝对没有任何意义。仅仅因为您在不同的函数中有同名的同一个对象并不意味着它们是同一个对象。 C++ 不能以这种方式工作。

您需要更改您的main() 函数,以通过引用将其outfile 作为参数传递给每个函数,而不是在每个函数中声明另一个具有相同名称的对象。上述函数将是,例如:

void draw_rect (ofstream &outfile, char out_char, int rows, int columns)
{

您需要更改每个函数以通过引用接收outfile 参数,就像这样,更改它们的前向声明,并在每个函数调用中显式传递outfile 作为main() 的第一个参数.

最后,关于你声称你的老师告诉你你使用getline有问题:

你的困惑是完全有道理的。如果您的“getline 语法不正确”,那么您将遇到编译失败。由于您的问题没有提到任何编译错误,即使在调查和确定实际问题之前,也可以合理地得出以下结论:1)getline 语法是正确的,2)编译的程序,3)您需要找到更好的老师,如果您的意图是真正学习 C++ 而不会受到不良教师的阻碍。

从表面上看,您的问题与 getline 无关。您的老师根本不称职,并且对C ++知之甚少。当然,这不是你的错,但你需要明白这一点。

附:

while(!infile.eof() || !exit)

This is a small bug。在这种情况下,错误被隐藏了,因为最终exit 会正确设置您的示例输入,但您应该在阅读并理解此链接中给出的解释后修复此问题。

【讨论】:

  • 我正在搜索此错误的参考。感谢您链接它+1
  • 谢谢,感谢你,这个程序终于输出到了 outfile 的好消息,但唯一的问题是形状看起来很大,比它们的参数应该允许的大得多,我是什么在这里做错了吗? void draw_rect (ofstream &amp;outfile, char out_char, int rows, int columns) 是我的函数定义,当我调用它时,它看起来像 draw_rect(outfile, value, row, col);
  • 您正确地传递了这个参数,否则您的程序将无法编译。至于你的巨大形状的原因,这很简单。例如,您将row = buffer[4]; 传递给draw_square(),而您的输入是S @ 6bufferstd::string,在这种情况下,它的第 4 个字符是 '6',它是 ASCII 码 54。字符“6”是 ASCII 码 54。所以你在这里传递 54 作为行数,这就是你最终绘制的,一个 54x54 的正方形。你需要打开你的 C++ 书籍,里面应该会向你解释如何在字符和整数之间进行转换。
  • 好的,我明白了,所以设置 row = buffer[4]; 对于我正在尝试做的事情是不正确的,我将如何将第 4 个字符读取为 int?我会使用static_cast&lt;int&gt; 吗?如果是这样,我会在我将参数设置为等于它们的缓冲区值的地方使用它吗?另外关于关于该错误的 P.S,当我将我的 while 循环更改为 while (infile &gt;&gt; buffer)while(!infile &gt;&gt; buffer).eof() 它只是无限期地循环我的默认 switch 语句,我在这里做错了什么?
  • 应该有很多不同的方法将字符输入转换为ints,在你的 C++ 书中有很多例子。有关更多信息,请参阅您的 C++ 书籍。您还应该花一些时间学习如何使用调试器,它可以让您一次运行一行程序,并在所有变量的值发生变化时检查和检查它们的值。了解如何有效地使用调试器是每个 C++ 开发人员的必备技能。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-08-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多