使用文件中的空白和数字数据读取文本

时间:2017-10-20 22:06:13

标签: c++ parsing

所以我在这样的文本中有数据:

Alaska         200 500
New Jersey     400 300
.
.

我正在使用ifstream打开它。

这是课程作业的一部分。我们不允许一次读取整行,并将其解析为各个部分。所以试图弄清楚如何阅读每一行的每一部分。

使用>>只能读取"新" "新泽西" ,因为空白区域/在该州名称中间留空。尝试了许多不同的内容,例如.get().read().getline()。我无法读入整个州名,然后读取给定行的数字数据的其余部分。

我想知道是否可以将整行直接读入structure。当然,structure是我们正在学习的新事物......

有什么建议吗?

4 个答案:

答案 0 :(得分:0)

这是一个逐行解析解决方案,它不使用任何c风格的解析方法:

SELECT 
         ITNBRV,
         month(
         substr(ODDTRV,4,2) ||'/'||
         substr(ODDTRV,6,2) ||'/'||
         substr(ODDTRV,2,2)) ||'/'||
         year(
         substr(ODDTRV,4,2) ||'/'||
         substr(ODDTRV,6,2) ||'/'||
         substr(ODDTRV,2,2)) AS Month_Year,
         SUM(OQTYRV) as OQTYRV_Total
FROM 
         ORDREVLA
WHERE 
         ITNBRV = '17000' OR ITNBRV = '19000'
GROUP BY (month(
             substr(ODDTRV,4,2) ||'/'||
             substr(ODDTRV,6,2) ||'/'||
             substr(ODDTRV,2,2))),
             ITNBRV

答案 1 :(得分:0)

你不能在循环中读取状态名称吗?

从cin读取一个字符串:如果字符串的第一个字符是数字,那么你已经到达下一个字段,你可以退出循环。否则只需将其附加到州名称并再次循环。

答案 2 :(得分:0)

如果您无法使用getline,请自行执行:阅读并存储在缓冲区中,直至找到' \ n'。在这种情况下,您可能也无法使用std::stringalgorithm中的所有常规内容,也可能使用好的ol'那时的C编程。

一旦你抓住一条线,从线的末尾向后读取你的方式

  1. 丢弃所有空格,直到找到非空格。
  2. 收集找到令牌3的字符,直到再次找到空白。
  3. 读取并丢弃空格,直到找到令牌2的结尾。
  4. 收集令牌2,直到找到更多空格。
  5. 丢弃空格直到找到令牌1的结尾。该行的其余部分都是令牌1。
  6. 将令牌2和令牌3转换为数字。我喜欢使用strtol
  7. 您可以将上述所有内容或丹尼尔的答案(尽可能使用他的答案)构建为operator>>的重载。这让你

    mystruct temp;
    while (filein >> temp)
    {
        // do something with temp. Stick it in a vector, whatever
    }
    

    执行此操作的代码类似于(从What are the basic rules and idioms for operator overloading?偷取批发< - 阅读本文。它可以挽救您的生命一天)

    std::istream& operator>>(std::istream& is, mystruct & obj)
    {
      // read obj from stream
    
      if( /* no valid object of T found in stream */ )
        is.setstate(std::ios::failbit);
    
      return is;
    }
    

答案 3 :(得分:-2)

这是另一个逐字阅读文件的例子。编辑以使用eof检查作为while循环条件删除示例。还包括一个结构,如你所提到的,这就是你刚刚学到的东西。我不确定你应该如何使用你的结构,所以我只是简单地使它包含3个变量,一个字符串和2个整数。为了验证它是否正确读取,它在读取结构变量之后会对结果变量的内容进行couts,其中包括将“New Jersey”打印为一个单词。

#include <iostream>
#include <fstream>
#include <string>
#include <stdlib.h> // for atoi
using namespace std;

// Not sure how you're supposed to use the struct you mentioned.  But for this example it'll just contain 3 variables to store the data read in from each line
struct tempVariables
{
        std::string state;
        int number1;
        int number2;
};

// This will read the set of characters and return true if its a number, or false if its just string text
bool is_number(const std::string& s)
{
    return !s.empty() && s.find_first_not_of("0123456789") == std::string::npos;
}


int main()
{
tempVariables temp;

ifstream file;
file.open("readme.txt");
std::string word;
std::string state;
bool stateComplete = false;
bool num1Read = false;
bool num2Read = false;
if(file.is_open())

{
  while (file >> word)
  {
      // Check if text read in is a number or not
      if(is_number(word))
      {
        // Here set the word (which is the number) to an int that is part of your struct
        if(!num1Read)
        {
           // if code gets here we know it finished reading the "string text" of the line
           stateComplete = true;
           temp.number1 = atoi(word.c_str());
           num1Read = true;  // won't read the next text in to number1 var until after it reads a state again on next line
        }
        else if(!num2Read)
        {

           temp.number2 = atoi(word.c_str());
           num2Read = true; // won't read the next text in to number2 var until after it reads a state agaon on next line
        }

      }
      else
      {
        // reads in the state text
        temp.state = temp.state + word + " ";
      }

      if(stateComplete)
      {
        cout<<"State is: " << temp.state <<endl;
        temp.state = "";
        stateComplete = false;
      }
      if(num1Read && num2Read)
      {
        cout<<"num 1: "<<temp.number1<<endl;
        cout<<"num 2: "<<temp.number2<<endl;
        num1Read = false;
        num2Read = false;
      }
  }
}

return 0;

}