【问题标题】:Reading in only letters from a text file仅从文本文件中读取字母
【发布时间】:2015-12-06 20:57:59
【问题描述】:

我正在尝试从文本文件中读入一首包含逗号、空格、句点和换行符的诗。我正在尝试使用 getline 读取每个单独的单词。我不想阅读任何逗号、空格、句点或换行符。当我读入每个单词时,我将每个字母大写,然后调用我的插入函数将每个单词作为单独的节点插入到二叉搜索树中。我不知道分隔每个单词的最佳方法。我已经能够用空格分隔每个单词,但逗号、句点和换行符会一直被读入。

这是我的文本文件:

玫瑰是红色的, 紫罗兰是蓝色的, 数据结构是最好的, 你和我都知道这是真的。

我使用的代码是这样的:

string inputFile;
    cout << "What is the name of the text file?";
    cin >> inputFile;

    ifstream fin;
    fin.open(inputFile);

    //Input once
    string input;
    getline(fin, input, ' ');
    for (int i = 0; i < input.length(); i++)
    {
        input[i] = toupper(input[i]);
    }
    //check for duplicates
    if (tree.Find(input, tree.Current, tree.Parent) == true)
    {
        tree.Insert(input);
        countNodes++;
        countHeight = tree.Height(tree.Root);
    }

基本上我使用 getline(fin,input, ' ') 来读取我的输入。

【问题讨论】:

  • 您可以使用getline(fin, input, '\n'); 来抓取每一行。然后 parse 单词的行。要解析一个单词,可以使用std::stringfind_first_of 成员函数。
  • 有没有在不使用外部类的情况下解决这个问题?我是学生,我们不应该这样做。
  • 您已经在使用getline 函数和std::string 类。

标签: c++ regex


【解决方案1】:

我想出了一个解决方案。我能够将整行代码读入变量行,然后搜索单词的每个字母,只保留字母并将其存储到单词中。然后,我能够调用我的插入函数来插入节点进入我的树。

const int MAXWORDSIZE = 50;
    const int MAXLINESIZE = 1000;
    char word[MAXWORDSIZE], line[MAXLINESIZE];
    int lineIdx, wordIdx, lineLength;
    //get a line
    fin.getline(line, MAXLINESIZE - 1);
    lineLength = strlen(line);
    while (fin)
    {
        for (int lineIdx = 0; lineIdx < lineLength;)
        {
            //skip over non-alphas, and check for end of line null terminator
            while (!isalpha(line[lineIdx]) && line[lineIdx] != '\0')
                ++lineIdx;

            //make sure not at the end of the line
            if (line[lineIdx] != '\0')
            {
                //copy alphas to word c-string
                wordIdx = 0;
                while (isalpha(line[lineIdx]))
                {
                    word[wordIdx] = toupper(line[lineIdx]);
                    wordIdx++;
                    lineIdx++;
                }
                //make it a c-string with the null terminator
                word[wordIdx] = '\0';

                //THIS IS WHERE YOU WOULD INSERT INTO THE BST OR INCREMENT FREQUENCY COUNTER IN THE NODE
                if (tree.Find(word) == false)
                {
                    tree.Insert(word);
                    totalNodes++;
                    //output word
                    //cout << word << endl;
                }
                else
                {
                    tree.Counter();
                }
            }

【讨论】:

    【解决方案2】:

    现在是我之前发布过几次技术的好时机:定义一个 ctype facet,它将除字母之外的所有内容都视为空格(搜索 imbue 将显示几个示例)。

    从那里开始,std::transformistream_iterators 在输入端,std::set 用于输出,lambda 用于大写第一个字母。

    【讨论】:

      【解决方案3】:

      您可以为多个分隔符制作自定义getline 函数:

      std::istream &getline(std::istream &is, std::string &str, std::string const& delims)
      {
          str.clear();
      
          // the 3rd parameter type and the condition part on the right side of &&
          // should be all that differs from std::getline
          for(char c; is.get(c) && delims.find(c) == std::string::npos; )
              str.push_back(c);
      
          return is;
      }
      

      并使用它:

      getline(fin, input, " \n,.");
      

      【讨论】:

        【解决方案4】:

        您可以使用std::regex 选择您的令牌

        根据文件的大小,您可以逐行阅读,也可以在std::string 中完全阅读。

        您可以使用read the file

        std::ifstream t("file.txt");
        std::string sin((std::istreambuf_iterator<char>(t)),
                         std::istreambuf_iterator<char>());
        

        这将匹配空格分隔的字符串。

        std::regex word_regex(",\\s]+");
        auto what = 
            std::sregex_iterator(sin.begin(), sin.end(), word_regex);
        auto wend = std::sregex_iterator();
        
        std::vector<std::string> v;
        for (;what!=wend ; wend) {
            std::smatch match = *what;
            V.push_back(match.str());
        }
        

        我认为用空格或换行分隔标记,你应该使用这个正则表达式:(,| \n| )[[:alpha:]].+。不过我还没有测试过,可能需要你检查一下。

        【讨论】:

          猜你喜欢
          • 2016-06-03
          • 2012-11-10
          • 2020-05-22
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多