I'm trying to read information from a text file and populate an array of structs using a pointer. I keep getting an error and I'm not sure how to fix it. Any help, comments, or tips are greatly appreciated! Thanks in advance for your time and help!

error: request for member 'budget_num'in 'ptr', which is of non-class type 'budget*'

struct budget
{
    int budget_num;
    string name;
    float budget_value;
};

//Declare file streams
ifstream inFile;
ofstream outFile;

int main()
{
    //Declare variables
    budget company[15];
    budget *ptr;
    //string MyString = "";

    ptr = &company[0];

    //Open inFile
    inFile.open("ledger.dat");

    while(!inFile)
    {
        cout << "Error opening the inFile." << endl;
        return 1;
    }

    while(!inFile.eof())
    {
        for(ptr = &company[0]; ptr < &company[15]; ptr++)
        {
        cin(inFile, ptr.budget_num);
        cin(inFile, ptr.name);
        cin(inFile, ptr.budget_value);
        //getline(inFile, MyString); //Used to test to see if the information was coming in
        }
    }

       //Close the files
    inFile.close();

    //Exit program
    return EXIT_SUCCESS;
}

Dani AI

Generated

The compiler message stems from treating a budget* like an object. With a pointer the member-access must be written as ptr->budget_num or by dereferencing first (*ptr).budget_num. Writing *ptr.budget_num is parsed incorrectly because . binds tighter than *. A second, very likely source of the “junk” values is using cin (standard input) instead of the file stream — all extractions must come from the ifstream (for example inFile >> ... or std::getline(inFile, ...)), and the file must be successfully opened before any reads.

File I/O and loop advice:

  • Use if (!inFile) to check open failure, not while(!inFile).
  • Avoid while (!inFile.eof()); prefer looping while an extraction succeeds (test the stream result) so partial/failed reads stop cleanly.
  • If names may contain spaces, read them with std::getline and consume the leftover newline after formatted reads (use ignore or read the whole record and parse).

Pointer vs index guidance: ’s suggestion to use a const SIZE and an indexed loop is sound — clearer and less error-prone. If pointers are preferred, initialize a budget* p = company; and loop while p != company + SIZE, using p->... to access members; never dereference the one-past-end pointer.

Quick troubleshooting checklist:

  • Confirm inFile actually opened (print an error and exit on failure).
  • Replace any cin >> ... with inFile >> ... (or std::getline(inFile, ...) for names).
  • Test with a tiny, known-format ledger.dat and print each token as it’s read before assigning it to the array.
  • Open outFile before writing, compile with warnings enabled, and check the stream state after each extraction.

As observed, pointer dereference is the key; combine that with the file-open and extraction fixes above and the behavior should become predictable and correct.

Recommended Answers

All 6 Replies

I think your ptr needs to be *ptr for it to work. I am a noob at programming, but that is what I would try next.

I tried that and I received the same error. Thanks for the suggestion.

I also tried the following code and it was unsuccessful:

    while(!inFile.eof())
    {
        for(ptr = &company[0]; ptr < &company[15]; ptr++)
        {
        cin >> *ptr.budget_num;
        cin >> *ptr.name;
        cin >> *ptr.budget_value;
        }
    }

there is no such index value as company[15], the indices are numbered 0, 1, 2, ... 14. A safer loop is to use integer, not pointer, in the for statement. Attempting to use ptr like you did is not safe because it depends on how the computer's memory is laid out

for(int i = 0, ptr = company; i < 15; i++, ptr++)
{

|

Finally, declare a const int to represent the number of elements in company so that you can easily change its value whenever you wish with little effort.

I have changed my code and I get the exact same junk out of each of them. At least it is reading something in, just not sure what it is... :(

  while(!inFile)
    {
        //Same junk output for this
        for(ptr = &company[0]; ptr < &company[SIZE]; ptr++)
        {
            cin >> (*ptr).budget_num;
            cin >> (*ptr).name;
            cin >> (*ptr).budget_value;
        }

        //As this
//        for ( int i = 0; i < SIZE; ++i )
//        {
//            cin >> (company[i].budget_num);
//            cin.ignore();
//            getline(cin, company[i].name);
//            cin >> company[i].budget_value;
//            cin.ignore();
//        }

    }

    for(int i = 0; i < SIZE; i++)
    {
    cout << "Number: " << company[i].budget_num << endl;
    cout << "Name:   " << company[i].name << endl;
    cout << "Value:  " << company[i].budget_value << endl;
    cout << endl;

    outFile << "Number: " << company[i].budget_num << endl;
    outFile << "Name:   " << company[i].name << endl;
    outFile << "Value:  " << company[i].budget_value << endl;
    outFile << endl;
    }

post the whole program. This works ok for me using vc++ 2012 RC

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

struct budget
{
    int budget_num;
    string name;
    float budget_value;
};

const int SIZE = 15;
int main()
{
     budget company[SIZE], *ptr;
     ifstream inFile("ledger.dat");
     ofstream outFile;
  //while(!inFile)
    {
        //Same junk output for this
        for(ptr = &company[0]; ptr < &company[SIZE]; ptr++)
        {
            cin >> (*ptr).budget_num;
            cin >> (*ptr).name;
            cin >> (*ptr).budget_value;
        }

        //As this
//        for ( int i = 0; i < SIZE; ++i )
//        {
//            cin >> (company[i].budget_num);
//            cin.ignore();
//            getline(cin, company[i].name);
//            cin >> company[i].budget_value;
//            cin.ignore();
//        }

    }

    for(int i = 0; i < SIZE; i++)
    {
    cout << "Number: " << company[i].budget_num << endl;
    cout << "Name:   " << company[i].name << endl;
    cout << "Value:  " << company[i].budget_value << endl;
    cout << endl;
    /*
    outFile << "Number: " << company[i].budget_num << endl;
    outFile << "Name:   " << company[i].name << endl;
    outFile << "Value:  " << company[i].budget_value << endl;
    outFile << endl;
    */
    }
}

ignore the above -- you started another thread.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.