Question

User.h

#pragma once
#include <iostream>
#include <string>
#include <fstream>
#include <list>

class User
{
private:

char line1[50];
char line2[50];
char line3[50];
char line4[50];

public:

void getUser(std::string);
};

User.cpp

#include "User.h"

void getUser(std::string username)
{
std::ifstream fin(username + ".txt");
fin.getline(line1, 50);
fin.getline(line2, 50);
fin.getline(line3, 50);
fin.getline(line4, 50);
fin.close();

std::list<std::string> UserInfo;

UserInfo.push_back(line1);
UserInfo.push_back(line2);
UserInfo.push_back(line3);
UserInfo.push_back(line4);

return UserInfo;
}

main.cpp

#include "User.h"

std::string username;

User display;

std::cout << std::endl << "Please enter your username: ";
std::getline (std::cin, username);
display.getUser(username);

I want to access the list UserInfo in main - I'm assuming it has to be returned, however, I don't know what the return type would be? (void is just temporary until I know the return type).

The other problem I have is when accessing the char variables in User.cpp, line1, line2 etc, I am given the error:

Identifier "line1" is undefined.

Was it helpful?

Solution

Same as your list :

std::list<std::string> getUser(std::string username)
{

  return UserInfo ;
}

Or pass it as a reference :

void getUser(std::string username, std::list<std::string>& UserInfo)
{


}

Char arrays line1, etc are private members can be accessed inside the member functions of class or through friend functions only.

Defined your getUser outside class

void User::getUser(std::string username)
{

}

OTHER TIPS

Lets put everything together into one file so that we can make a stand-alone compilable version of it.

#include <string>
#include <list>
#include <iostream>

// make an alias for this type of list and call it 'UserInfo'.
typedef std::list<std::string> UserInfo;

class User
{
    // private is the default for class, it's the only way
    // it differs from using 'struct'.
    char m_line1[50];
    char m_line2[50];
    char m_line3[50];
    char m_line4[50];

public:
    UserInfo getUser(const std::string&);
};

UserInfo User::getUser(const std::string& username)
{
    std::ifstream fin(username + ".txt");
    fin.getline(m_line1, sizeof(m_line1));
    fin.getline(m_line2, sizeof(m_line1));
    fin.getline(m_line3, sizeof(m_line1));
    fin.getline(m_line4, sizeof(m_line1));
    fin.close();

    UserInfo info;

    info.push_back(m_line1);
    info.push_back(m_line2);
    info.push_back(m_line3);
    info.push_back(m_line4);

    return info;
}

int main()
{
    std::string username;
    User display;

    std::cout << std::endl << "Please enter your username: ";
    std::getline(std::cin, username);

    UserInfo info = display.getUser(username);
    for (auto it = info.begin(); it != info.end(); ++it) {
        std::cout << *it << "\n";
    }

    return 0;
}

Some remarks on your code:

Be consistent with your use of case. You're using what's called "UpperCamelCase" to denote types (User), use "lowerCamelCase" for variables and stick with it - otherwise you're going to run into collisions between variable names and types.

Secondly, you've chosen a std::list where a std::vector seems like it would be much better.

Next, you decouple the way you return your data and the way you store your data. Why not store the lines as std::strings?

Your "User" object is kind of vague and nebulous. It has some string fields, which you don't initialize when the object is created, and it has a function which goes and fetches data about a particular user, stores it in the object, and returns in a different format.

This is how I would implement the class:

#include <string>
#include <vector>
#include <iostream>

typedef std::vector<std::string> UserInfo;

class User
{
    std::string        m_username;
    UserInfo        m_info;

public:
    User(const std::string& name);

    enum { NumInfoLines = 4 };    // how many lines of info we use.

    // Accessor function to retrieve the userinfo
    // Instead of passing a copy, provide read-only access
    // to our internal copy - read-only so you have to go thru
    // the class to modify it.
    // Mark the function call as 'const' because it has no
    // side effects. This may allow the compiler to do some
    // optimizations for us.
    const UserInfo& getInfo() const { return m_info; }
};

User::User(const std::string& username)
    : m_username(username), m_info()
{
    std::ifstream fin(m_username + ".txt");
    std::string inputLine;
    m_info.reserve(NumInfoLines);
    for (size_t i = 0; i < NumInfoLines; ++i) {
        fin.getline(inputLine);
        m_info.push_back(inputLine);
    }
}

int main()
{
    std::string username;
    std::cout << std::endl << "Please enter your username: ";
    std::getline(std::cin, username);

    User user(username);
    const UserInfo& info = user.getInfo();
    for (auto line : info) {
        std::cout << line << "\n";
    }

/* or you could use
    const size_t numInfoLines = info.size();
    for (size_t i = 0; i < numInfoLines; ++i) {
        std::cout << i << ": " << info[i] << "\n";
    }
*/

    return 0;
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top