0

I wrote this code to find a word in a file and know its location with the help of tellg(), but I am not getting my desired output to display it.

This is my code:

#include <iostream>
#include <fstream>
using namespace std;

int main(){
    fstream file;
    string filename="stockk.txt";
    file.open(filename.c_str());
    string pro_name;
    cout<<"Enter the product name you want to display : ";
    cin>>pro_name;
    int flag=0;
    int pos=0;
    while(!file.eof()){
        file>>pro_name;
        cout<<pro_name<<endl;
        if(pro_name=="maaza"){
            flag=1;
            pos=file.tellg();
            break;
        }
    }
    
    if(flag==1){
        cout<<"product name matched\n";
        cout<<pos<<endl;
        // delay(1000);
        // system("cls");
        file.seekg(pos-4,ios::beg);
        while(!file.eof()){
            file>>pro_name;
            cout<<pro_name<<endl;
        }
    }
    if(flag==0){
        cout<<"Go Home\n"; 
    }
    return 0;
}

This is my txt file

Name : rasana
Cost : 300
Price : 400
Quantity : 5
         
Name : maaza
Cost : 300
Price : 400
Quantity : 1

Name : oats
Cost : 300
Price : 5000
Quantity : 1

Name : nutella
Cost : 300
Price : 5000
Quantity : 1

Name : jam
Cost : 300
Price : 5000
Quantity : 1

I want to display maaza and its cost, price, and quantity to the console. Can anyone explain to me why this is not working?

Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
Mahir Jain
  • 37
  • 7
  • If you want a program to read a file, create the file so that a program can easily read it. Human readable formats require so much extra work for very little payoff. – sweenish Aug 29 '21 at 17:36
  • you mean binary file? – Mahir Jain Aug 29 '21 at 17:38
  • @sweenish can u tell how to display this thing – Mahir Jain Aug 29 '21 at 17:40
  • Which operating system? Most operating systems have tools to display file contents, so you don't have to write programs. For example, Windows has (at least) `more` and `find`. Linux has `less`, `cat`, `sed` and `awk`. Prefer to use operating system tools when dealing with files; those tools have been tested more than your program ever will. – Thomas Matthews Aug 29 '21 at 18:12
  • 2
    See also [Why is iostream::eof inside a loop condition (i.e. `while (!stream.eof())`) considered wrong?](https://stackoverflow.com/questions/5605125/why-is-iostreameof-inside-a-loop-condition-i-e-while-stream-eof-cons) – Thomas Matthews Aug 29 '21 at 18:16
  • 1
    BTW, there is a new data type in C++ which is used for "yes/no" or "true/false" conditions. It's called `bool`. You should try it instead of the ancient antiquated art of integers and 0/1 values. BTW, the integer value of -1 means true also (anything that is not zero is true). – Thomas Matthews Aug 29 '21 at 18:18
  • 1
    You should use `std::pos_type` for stream positions, as the `int` type may not have the range capacity that a file has. – Thomas Matthews Aug 29 '21 at 18:20
  • 1
    @ThomasMatthews that's a pretty broad definition of "new" :) – Jeremy Friesner Aug 29 '21 at 18:27
  • 1
    @MahirJain, binary file is an option, but in my opinion a bad choice. I would use the current king JSON or it's predecessor Xml (but that's a design choice, not answering the question at hand) – Tomer W Aug 30 '21 at 03:58
  • oh thanks @ThomasMatthews for help that really helpful didnt knew this thing before – Mahir Jain Aug 30 '21 at 07:55

1 Answers1

1

I would want my main to look a bit like this:

int main()
{
    std::fstream file("stockk.txt");
    Unit        unit;

    // Read the file one product at a time.
    while (file >> unit) {
        // If I have found the item I am looking for.
        if (unit == "maaza") {
            // then print it our.
            std::cout << unit;
        }
    }
}

So would do something like this:

#include <string>
#include <iostream>
#include <fstream>
#include <sstream>

// Create a class to represent the thing you want to read
// from the file. This is your atomic piece of information.
class Unit
{
    // These are the properties of that atomic piece of information.
    std::string     name;
    int             cost;
    int             price;
    int             quantity;

    public:
        // I will leave you to add constructors if you need them


        // Add a simple swap function as that is useful in making
        // some code below simpler. But basically does an atomic
        // swap of two values.
        void swap(Unit& other) noexcept
        {
            using std::swap;
            swap(name,    other.name);
            swap(cost,    other.cost);
            swap(price,   other.price);
            swap(quantity,other.quantity);
        }
        friend void swap(Unit& lhs, Unit& rhs)   {lhs.swap(rhs);}


        // Need the ability to compare an object with a name.
        bool operator==(std::string const& testName) const   {return name == testName;}

        // External IO operators
        // We will use these to read/print objects from the file.
        // They simply call read/print methods on the object and return
        // the stream to allow for chaining.
        friend std::istream& operator>>(std::istream& str, Unit& data)
        {
            data.read(str);
            return str;
        }
        friend std::ostream& operator<<(std::ostream& str, Unit const& data)
        {
            data.print(str);
            return str;
        }
    private:

        // Read a single value from a file and check it is valid.
        // This is used by the main read() function below.
        template<typename T>
        T read(std::istream& str, std::string const& expectedPrefix)
        {
            // Steam read a line from the file and put it in
            // a stringstream. This makes it easy to handle for
            // processing of human readable text. Not worried if
            // it fails at this point as that will result in an empty
            // linestream which will fail at the next step.
            std::string     line;
            std::getline(str, line);    
            std::stringstream   lineStream(line);

            // Define the expected things you want from the line.
            bool            goodread = false;
            std::string     prefix;
            char            colon = '*';
            T               value{};

            // Try and read a line
            if (lineStream >> prefix >> colon >> value) {
                // Did we find what was expected.
                if (prefix == expectedPrefix && colon == ':') {
                    goodread = true;
                }
            }

            // If the read failed in some way
            // Then mark the stream as bad.
            if (!goodread) {
                str.setstate(std::ios::failbit);
            }

            return value;
        }
        void read(std::istream& str)
        {
            // Use a temporary value.
            // If the read works we will transfer to this.
            Unit    tmp;

            // Manually read each value.
            tmp.name    = read<std::string>(str, "Name");
            tmp.cost    = read<int>(str, "Cost");
            tmp.price   = read<int>(str, "Price");
            tmp.quantity= read<int>(str, "Quantity");

            // Ignore empty line
            std::string     line;
            std::getline(str, line);

            // If the read worked then swap this and the temporary value.
            if (str) {
                swap(tmp);
            }
        }
        void print(std::ostream& str) const
        {
            // Print the value in the same way that you would read it.
            str << "Name : "    << name     << "\n"
                << "Cost : "    << cost     << "\n"
                << "Price : "   << price    << "\n"
                << "Quantity : "<< quantity << "\n"
                << "\n";
        }
};
Martin York
  • 257,169
  • 86
  • 333
  • 562