首页 文章

C,无限循环

提问于
浏览
-1

我的C项目目的是输出一个文件,其中包含由简单字符组成的图片 .

我的项目的第一部分要求我“包含一个从输入文件中读取命令并返回表示已读取命令的整数值的函数” . 这是我的takeCommand函数 . 看起来非常低效,但我认为必要,如果我理解正确的话 .

目前的问题是我的main函数中的while循环运行无限循环 . 当输出文本“Works”时,它会不断重复 . 我的目的是制作一个End-of-File控制循环 . 在takeCommand函数内部,当它读取最后一行时,takeCommand函数停止运行,因此while循环结束 .

我需要关于如何让while循环工作而不经常重复的想法 .

我现在拥有的是:

int takeCommand(int& num, int& cmd);

    ifstream infile;
    ofstream outfile;

    int main()
    {
         const int MAX_FOR = 3;
         string str;
         int num, cmd;
         infile.open("DrawingInput_01.txt");
         outfile.open("DrawingOutput_01.txt");

         for (int i = 0; i < MAX_FOR; i++)
         {
             getline(infile,str);
         }

         takeCommand(num,cmd);
         while(infile)
         {
           cout << "Works";
           /*switch(cmd)
           {
               case '1': printSpace(infile, outfile); break;
               case '2': printChar(infile, outfile); break;
               case '3': printNewline(infile, outfile); break;
               case '0': break;
           }*/
           takeCommand(num, cmd);
         }

         infile.close();
         outfile.close();
         return 0;
     }

     int takeCommand(int& num, int& cmd)
     {
         string str;
         char firstChar;
         infile.open("DrawingInput_01.txt");
         for (int i = 0; i < 3; i++)
         {
             getline(infile.str);
         }
         infile >> firstChar >> str >> num;
         switch(firstChar)
         {
             case 's': cmd = 1; break;
             case 'p': cmd = 2; break;
             case 'n': cmd = 3; break;
             case 'q': cmd = 0; break;
         }
         return cmd;
     }

其中一个输入文件如下所示:

; CS 1044 Fall 2010
; Project 4
; Basic Cat
space 1
print 1 /
print 1 \
print 1 _
print 1 /
print 1 \
newline
print 1 (
space 1
print 1 o
print 1 .
print 1 o
space 1
print 1 )
newline
space 1
print 1 >
space 1
print 1 ^
space 1
print 1 <
newline
quit

输出文件应该是一个兔子 .

void函数在我的代码中,它现在不是问题 .

2 回答

  • 0

    好吧,让我们先用你的 takeCommand 函数开始:你使用循环机制和 getline 来忽略文件中的前三行(因为它是一个简单的 Headers ) . 似乎合乎逻辑,但有一点需要注意 . 当您在 while 循环内多次调用此函数时,每次调用将忽略3行 . 怎么回事"horribly inefficient"? :)

    你不需要这样做 . 此外,您最初忽略 main 函数内部的前三行(在while循环之外),那么为什么在 takeCommand 内再次需要它?解决方案是删除for循环,以便之后的函数如下所示:

    int takeCommand(int& num, int& cmd)
    {
        char firstChar;
        infile.open("DrawingInput_01.txt");
    
        infile >> firstChar >> str >> num;
    
        switch (firstChar)
        {
            case 's': cmd = 1; break;
            case 'p': cmd = 2; break;
            case 'n': cmd = 3; break;
            case 'q': cmd = 0; break;
        }
        return cmd;
    }
    

    我的另一个宠儿是不必要的呼叫 . 如果您在构造文件流时已经知道文件的名称,则只需在创建文件流时提供该文件 . 这意味着从函数中删除该调用,而是执行:

    ifstream infile("DrawingInput_01.txt");
    

    另外,文件流不需要静态存储持续时间,并且它们不需要作为全局变量,因此您应该获取输入和输出文件流并将它们放在main中 .

    while循环条件都是错误的 . 应在检查流之前执行I / O.所以你可以将你的功能改为:

    std::basic_ios<char>& takeCommand(int& cmd)
    {
        char firstChar;
        if (!inFile.get(firstChar))
        {
            return inFile;
        }
    
        inFile.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
    
        // ...
    
        return inFile;
    //  ^^^^^^^^^^^^^^
    }
    

    这允许流返回到下面的while循环条件,以便它检查输入是否成功:

    while (takeCommand(cmd))
    

    注意我是如何检查成功的输入操作(如果有的话,我们忽略了该行的其余部分)并且我已经取出了不需要的参数 .

    在您完成这些更改之后(这些更改),这是您的程序应该是这样的:

    #include <iostream>
    #include <fstream>
    #include <limits>
    
    std::ios& takeCommand(std::istream&, int&);
    
    int main()
    {
        std::ifstream inFile("DrawingInput_01.txt");
        std::ofstream outFile("DrawingInput_01.txt");
        std::string str;
    
        for (int i = 0; i < 3; ++i) std::getline(inFile, str);
    
        int cmd;
    
        while (takeCommand(inFile, cmd))
        {
            std::cout << "Command was " << cmd;
            outFile << cmd;
       }
    }
    
    std::ios& takeCommand(std::istream& is, int& cmd)
    {
        char firstChar;
        if (!is.get(firstChar))
        {
            return is;
        }
    
        is.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
    
        switch (firstChar)
        {
            case 's': cmd = 1; break;
            case 'p': cmd = 2; break;
            case 'n': cmd = 3; break;
            case 'q': cmd = 0; break;
        }
    
        return is;
    }
    
  • 0

    你的问题是 infile 在整个while循环的执行过程中是活着的,所以你的while循环总是正确的,因为即使文件关闭后对象仍然存在 .

    另外,在使用switch语句测试之前,您应该获取输入的字符串,并且当I / O操作指示文件已被完全读取时,您需要关闭while循环内的文件(即使用eof()函数,必须在读取数据后调用) . 你在第二个功能中再次打开文件 . 此代码需要严格修改 .

相关问题