无法弄清楚如何在C ++中打印字母序列

时间:2014-01-26 20:12:22

标签: c++

我正在开展一个项目,在那里我将能够读取包含任何文本的文件,如下面的示例文本。然后,逐个字符,它将能够输出n个字符的长序列(在下面表示为用户沿着1,2,3,4 ......给出的读入值)沿着整个长度文本。所以,例如:

  一天早上,格雷戈尔·萨姆沙(Gregor Samsa)从不安的梦中醒来,发现自己在床上变成了一只巨大的昆虫。

如果用户提供2作为序列长度,则程序应吐出:“As”“s”“G”“Gr”“re”“例如”“go”“或”“r”等等。 ..

我已编写此代码,但不知道为什么它不起作用。现在,它没有吐出序列的每个可能的变化。任何建议都会非常有帮助。感谢。

#include "genlib.h"
#include <iostream>
#include <fstream>
#include "simpio.h"
#include "random.h"
#include "vector.h"
#include "map.h"

/* Private Instance Variables */
int seed_length;
string line;
string seed_string;
string next_string;
char ch;

/* Function Prototypes */
string promptUserForFile(ifstream & infile);

int main() {

ifstream infile;
promptUserForFile(infile);

// Ask what order of Markov model to use.
cout << "What order of Markov model should we use? ";
cin >> seed_length;

while (infile.eof() == false) {

    ch = infile.get();

    for (int i = 0; i < seed_length - 1; i++) {

        cout << "ch up here is " << ch << endl;

        if (isspace(ch) && i == 0) {
            seed_string += ch;

        } else {

            seed_string += ch;
            ch = infile.get();

        }
    }

    next_string = ch;

    if (isspace(ch)) {
        next_string = " ";
    } else {
        char trythis = infile.get();
        next_string += trythis;
    }


    cout << seed_string << endl;
    cout << next_string << endl;

    seed_string = "";
    next_string = "";

}

cout << "TEST" << endl;

// Close the file when you're done storing all of the scores.
infile.close();


return 0;
}


string promptUserForFile(ifstream & infile) {

string prompt = "Please input your filename: ";

while(true) {

    cout << prompt;
    string filename;
    getline (cin, filename);
    infile.open(filename.c_str());
    if(!infile.fail()) return filename;
    infile.clear();
    cout << "Unable to open that file. Try again." << endl;
    if (prompt == "") prompt == "Input file: ";

}

return 0;
}

1 个答案:

答案 0 :(得分:0)

代码有两个问题。

  1. isspace的特殊处理已被破坏:

    if (isspace(ch) && i == 0) {
        seed_string += ch;
    } else {
        seed_string += ch;
        ch = infile.get();
    }
    

    这实质上意味着如果此循环中的第一个字符是空格,它将被添加两次。

  2. infile.get()收到的每个字符只会添加到seed_string一次(isspace个字符除外)。

  3. 更好的代码编码方法是识别:

    1. 您必须忽略连续的isspace个字符。
    2. 可以通过删除前一个序列的第一个字符并附加文件中的下一个字符来获取每个序列。
    3. 这是一个更好的实施;它采用Markov模型在第一个命令行参数中的顺序,并从标准输入中获取文本。通过在单独的函数中封装重复空格的跳过,您不必在算法的主体中处理它。

      #include <iostream>
      #include <cstdlib>
      
      char next_character() {
          static bool was_space = false;
          char ret = 0;
      
          do {
              ret = std::cin.get();
          } while (was_space && std::isspace(ret));
      
          if (std::isspace(ret)) {
              was_space = true;
              ret = ' ';
          } else {
              was_space = false;
          }
          return ret;
      }
      
      int main(int argc, char **argv) {
      
          if (argc != 2) return 0;
          int mlen = std::atoi(argv[1]);
      
          std::string seq;
          for (unsigned i = 0; i < mlen; ++i) {
              seq += next_character();
          }
          std::cout << seq << '\n';
      
          while (true) {
              seq.erase(0, 1);
              char c = next_character();
              if (std::cin.eof()) break;
              seq += c;
              std::cout << seq << '\n';
          }
          return 0;
      }
      

      示例输入:

      This  is a    test
      

      示例输出:

      This 
      his i
      is is
      s is 
       is a
      is a 
      s a t
       a te
      a tes
       test