#Reading and parsing the contents of the given input stream

57 messages · Page 1 of 1 (latest)

ashen urchin
#

Hi, I have an assignment where I am supposed to read input from the given stream, but I am getting a throwing error when I'm not supposed to while reading the contents. I'm not sure if it is because I am reading them in wrong or testing the throwing errors incorrectly.

bitter muskBOT
#

When your question is answered use !solved to mark the question as resolved.

Remember to ask specific questions, provide necessary details, and reduce your question to its simplest form. For tips on how to ask a good question use !howto ask.

ashen urchin
#
#include "customparser.h"
#include <iostream>
#include <sstream>

using namespace std;

const char* error_msg_1 = "Cannot read integer n";
const char* error_msg_2 = "Error in content parsing";
const char* error_msg_3 = "Error in user parsing";

// To Do - Complete this function
void CustomFormatParser::parse(std::istream& is, std::vector<Content*>& content, std::vector<User*>& users)
{
  // Erase any old contents
  content.clear();
  users.clear();

  // TO DO - Add your code below.
  int n;
  if(!(is >> n))
    throw ParserError(error_msg_1);

  for(int i = 0; i < n; i++)
  {
    int id, type, reviews, stars, rating ;
    std::string name;
    
    is >> id >> type;
    cout << id << " " << type;

    if(is.fail())
      throw ParserError(error_msg_2);

    std::getline(is >> std::ws, name);

    if(!(is >> reviews >> stars >> rating))
      throw ParserError(error_msg_2);
    
    std::string viewerLine;
    std::getline(is >> std::ws, viewerLine);
    std::istringstream viewerStream(viewerLine);
    std::string viewer;
    std::vector<std::string> viewers;
    
    while(viewerStream >> viewer)
      viewers.push_back(viewer);
  
    if(type == 0)
    {
      content.push_back(new Movie(id, name, reviews, stars, rating));
    }
    else if(type == 1)
    {
      int episodes;
      if(!(is >> episodes))
        throw ParserError(error_msg_2);
      
      content.push_back(new Series(id, name, reviews, stars, rating, episodes));
    }
    else
    {
      throw ParserError(error_msg_2);
    }
  }```
#

  while(std::getline(is >> std::ws, userLine))
  {
    if(userLine.empty())
      break;

    std::istringstream userStream(userLine);
    std::string username;
    int ratingLimit;

    if(!(userStream >> username >> ratingLimit))
      throw ParserError(error_msg_3);

    std::string historyLine;
    std::getline(is >> std::ws, historyLine);
    std::istringstream historyStream(historyLine);
    int contentID;
    std::vector<int> history;

    while(historyStream >> contentID)
    {
      history.push_back(contentID);
    }
    users.push_back(new User(username, ratingLimit));
  }
}```
#

This is my code

#

Here is the .cus file for input:

3
0 0
    Black Panther: Wakanda Forever
    4
    18
    3
    user2 user3 
1 1
    Stranger Things 1
    3
    13
    3
    8
    user1 user2
2 1
    Stranger Things 2
    2
    5
    4
    9
    user2 user3
user1 3
1
user2 4
0 1 2
user3 4
0 2
patent willow
#

You've commented out the code that reads into type but you're still using type

ashen urchin
#

When it's uncommented the issue is still there, my bad

patent willow
#

The file for input doesn't match what you're reading tho

#

Like where is the leading 'n'

#

Also your didn't say what error is being given. But it'd be simplest for you to just debug and look at variable values close to where it's going wrong

ashen urchin
#

I did the with 3 hidden inside, my bad again 😭

#

This was the error I was given:

Parsing data1.cus with your custom parser should not throw. It does.

cusparse-gtest.cpp:389: Failure
Value of: compareContents(expContent, actContent, expContentTypes)
Actual: false (Expected parsed Content pointer vector size to be 3 but actual size was 1

patent willow
#

Look at how many type numbers you handle

#

Oh nm, I got type and id mixed up

#

Not sure just from looking at. You should debug

#

I don't think your episode parsing and viewers parsing are ordered correctly

ashen urchin
#

How do I loop through the viewers after parsing episodes?

patent willow
#

I might be getting the names wrong, but on the first movie you need to read those three numbers 4 18 3.
For the stranger things chunk you should read 4 numbers but you only read 3

ashen urchin
#

I see, I think I should have given the .json file instead 😭

#
    "content" : [
        {
            "id" : 0,
            "type" : 0,
            "name" : "Black Panther: Wakanda Forever",
            "reviews" : 4,
            "stars" : 18,
            "rating" : 3,
            "viewers" : ["user2", "user3"]
        },
        {
            "id" : 1,
            "type" : 1,
            "name" : "Stranger Things 1",
            "reviews" : 3,
            "stars" : 13,
            "rating" : 3,
            "episodes" : 8,
            "viewers" : ["user1", "user2"]
        },
        {
            "id" : 2,
            "type" : 1,
            "name" : "Stranger Things 2",
            "reviews" : 2,
            "stars" : 5,
            "rating" : 4,
            "episodes" : 9,
            "viewers" : ["user2", "user3"]
        }
    ],
    "users" : [
        {
            "uname" : "user1",
            "limit" : 3,
            "viewed" : [1]
        },
        {
            "uname" : "user2",
            "limit" : 4,
            "viewed" : [0, 1, 2]
        },
        {
            "uname" : "user3",
            "limit" : 4,
            "viewed" : [0, 2]
        }
    ]
}
#

It shows like where each content is being read into

#

But 3 would be correct

patent willow
#

Not for episodes

ashen urchin
#

The first content is Black Panther and it's a movie, so 4 18 3 would be right because there are no episodes in a movie

patent willow
#

Yeah, but you do the same thing for the TV show

#

And the next line you try to read as viewers

#

But it's the episode number

ashen urchin
#

The only thing different about the movie and series is that series has episodes

#

So that's why I read episodes right before pushing back the content

patent willow
#

But it's not the right order

ashen urchin
#

The Movie and Series objects don't have viewers inside of them though

patent willow
#

So?

ashen urchin
#
{
public:
    /**
     * @brief Construct a new Movie object
     * 
     * @param id Content ID 
     * @param name Content name (spaces are fine)
     * @param nr Number of reviews
     * @param ts Total stars of all reviews
     * @param rating Parental control rating
     */
    Movie(int id, std::string name, int nr, int ts, int rating);
    /**
     * @brief Destroy the Movie object
     * 
     */
    ~Movie();

    /// Add an override of the Content::display function, 
    /// if you deem it necessary

protected:
    // Do not alter this line
    const char** ratingStrings() const;

private:
    // Add more data members if you deem it necessary

};

class Series : public Content {
public:
    /**
     * @brief Construct a new Series object
     * 
     * @param id Content ID 
     * @param name Content name (spaces are fine)
     * @param nr Number of reviews
     * @param ts Total stars of all reviews
     * @param rating Parental control rating
     * @param numEpisode Numer of episodes in the series
     */
    Series(int id, std::string name, int nr, int ts, int rating, int numEpisodes);
    /**
     * @brief Destroy the Series object
     * 
     */
    ~Series();

    /**
     * @brief Accessor / getter to return the number of episodes in the series
     * 
     * @return int 
     */
    int numEpisodes() const;

    /// Add an override of the Content::display function, 
    /// if you deem it necessary

    virtual void display(std::ostream& ostr) const override;


protected:
    // Do not alter this line
    const char** ratingStrings() const;

private:
    // Add data members as needed
    int numEpisodes_;

};```
patent willow
#

You still need to find the correct data in the file for 'episodes'

ashen urchin
#

Ok, but do you know why it might throw before that because I've commented out everything but the if(!(is >> id >> type)... throw, and it throws from there even though they are being read in correctly?

patent willow
#

If you just randomly comment out things then it will break more, yes

ashen urchin
#

I commented out everything after that throw and ended the for loop, I used the test we were given and received the same error as I am now, which is that the vector size is incorrect

patent willow
#

I don't know how many different ways to say you're reading the data in the wrong order

ashen urchin
#
    std::getline(is >> std::ws, viewerLine);
    std::istringstream viewerStream(viewerLine);
    std::string viewer;
    std::vector<std::string> viewers;
    
    while(viewerStream >> viewer)
      viewers.push_back(viewer);```
#

So this block of code, it should go after I read episodes?

patent willow
#

Yes. But reading episodes is conditional.

ashen urchin
#

So after the if statements?

patent willow
#

I'll leave you to think about it

#

There is an alternative way to write this - make a separate parse function for movie/TV then you don't have if checks all over the place

ashen urchin
#

I'm not allowed to do that for this assignment

#

Ok thank you for your help

#

Now I just have to figure out the wrong content values parsed lol

patent willow
#

You're not allowed to make your own functions?

ashen urchin
#

Yeah 😭

patent willow
#

Are you sure you're just not allowed to change the interface?

ashen urchin
#

We're only supposed to use the functions they give us in the skeleton code

patent willow
#

Well at least you're allowed to use vector

ashen urchin
#

True

bitter muskBOT
#

@ashen urchin Has your question been resolved? If so, type !solved :)

ashen urchin
#

!solved