Computer Science Canada

Multiple Definitions Problem

Author:  HRI [ Mon Oct 11, 2010 6:11 pm ]
Post subject:  Multiple Definitions Problem

I've read on this and tried things for quite a while now. Nothing is working, so I thought I'd post my code somewhere.

I'm using DevCpp.
I made a header file in the include folder that takes
c++:

#include <iostream>
#include <limits>
while ((std::cout << "Enter an integer: ") && (std::cin >> a))
{
std::cout << "That is not a valid integer.\n";
cin.clear();
cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
}

for checking whether an input (integer in this case) is valid, and makes it into a short function call, as well as adding a couple different options.

The problem is that I have a project in which both the implementation and main files include it, and it doesn't work because they're being defined more than once.

Here's my files:
valid.h (in include folder)
c++:

#ifndef valid
#define valid

#include <string>
using std::string;

#include <limits>
using std::numeric_limits;
using std::streamsize;

#include <iostream>
using std::cin;
using std::cout;


int validi (string output)
{
int input;
while ((cout << output) && !(cin >> input))
{
system ("msg * This is not a valid input.");
system ("cls");
cin.clear();
cin.ignore(numeric_limits<streamsize>::max(), '\n');
}
return input;
}

int validi (string output, string warning)
{
int input;
while ((cout << output) && !(cin >> input))
{
cout << warning << '\n';
system ("pause");
system ("cls");
cin.clear();
cin.ignore(numeric_limits<streamsize>::max(), '\n');
}
return input;
}

double validd (string output)
{
double input;
while ((cout << output) && !(cin >> input))
{
system ("msg * This is not a valid input.");
system ("cls");
cin.clear();
cin.ignore(numeric_limits<streamsize>::max(), '\n');
}
return input;
}

double validd (string output, string warning)
{
double input;
while ((cout << output) && !(cin >> input))
{
cout << warning << '\n';
system ("pause");
system ("cls");
cin.clear();
cin.ignore(numeric_limits<streamsize>::max(), '\n');
}
return input;
}

string validc (string output)
{
string input = "aa";
while (input.length() != 1)
{
cout << output;
cin >> input;
if (input.length() == 1) return input;
else
{
system ("msg * This is not a valid input.");
system ("cls");
cin.clear();
cin.ignore(numeric_limits<streamsize>::max(), '\n');
}
}
}

string validc (string output, string warning)
{
string input = "aa";
while (input.length() != 1)
{
cout << output;
cin >> input;
if (input.length() == 1) return input;
else
{
cout << warning << '\n';
system ("pause");
system ("cls");
cin.clear();
cin.ignore(numeric_limits<streamsize>::max(), '\n');
}
}
}

string valids (string output)
{
string input;
while ((cout << output) && !(cin >> input))
{
system ("msg * This is not a valid input.");
system ("cls");
cin.clear();
cin.ignore(numeric_limits<streamsize>::max(), '\n');
}
return input;
}

int validil (string output, int less)
{
int input;
while ((cout << output) && !(cin >> input) || input>=less)
{
system ("msg * This is not a valid input.");
system ("cls");
cin.clear();
cin.ignore(numeric_limits<streamsize>::max(), '\n');
}
return input;
}

int validil (string output, string warning, int less)
{
int input;
while ((cout << output) && !(cin >> input) || input>=less)
{
cout << warning << '\n';
system ("pause");
system ("cls");
cin.clear();
cin.ignore(numeric_limits<streamsize>::max(), '\n');
}
return input;
}

int validig (string output, int greater)
{
int input;
while ((cout << output) && !(cin >> input) || input<=greater)
{
system ("msg * This is not a valid input.");
system ("cls");
cin.clear();
cin.ignore(numeric_limits<streamsize>::max(), '\n');
}
return input;
}

int validig (string output, string warning, int greater)
{
int input;
while ((cout << output) && !(cin >> input) || input<=greater)
{
cout << warning << '\n';
system ("pause");
system ("cls");
cin.clear();
cin.ignore(numeric_limits<streamsize>::max(), '\n');
}
return input;
}

int validib (string output, int less, int greater)
{
int input;
while ((cout << output) && !(cin >> input) || input<less || input>greater)
{
system ("msg * This is not a valid input.");
system ("cls");
cin.clear();
cin.ignore(numeric_limits<streamsize>::max(), '\n');
}
return input;
}

int validib (string output, string warning, int less, int greater)
{
int input;
while ((cout << output) && !(cin >> input) || input<less || input>greater)
{
cout << warning << '\n';
system ("pause");
system ("cls");
cin.clear();
cin.ignore(numeric_limits<streamsize>::max(), '\n');
}
return input;
}

double validdl (string output, double less)
{
double input;
while ((cout << output) && !(cin >> input) || input>=less)
{
system ("msg * This is not a valid input.");
system ("cls");
cin.clear();
cin.ignore(numeric_limits<streamsize>::max(), '\n');
}
return input;
}

double validdl (string output, string warning, double less)
{
double input;
while ((cout << output) && !(cin >> input) || input>=less)
{
cout << warning << '\n';
system ("pause");
system ("cls");
cin.clear();
cin.ignore(numeric_limits<streamsize>::max(), '\n');
}
return input;
}

double validdg (string output, double greater)
{
double input;
while ((cout << output) && !(cin >> input) || input<=greater)
{
system ("msg * This is not a valid input.");
system ("cls");
cin.clear();
cin.ignore(numeric_limits<streamsize>::max(), '\n');
}
return input;
}

double validdg (string output, string warning, double greater)
{
double input;
while ((cout << output) && !(cin >> input) || input<=greater)
{
cout << warning << '\n';
system ("pause");
system ("cls");
cin.clear();
cin.ignore(numeric_limits<streamsize>::max(), '\n');
}
return input;
}

double validdb (string output, double less, double greater)
{
double input;
while ((cout << output) && !(cin >> input) || input<less || input>greater)
{
system ("msg * This is not a valid input.");
system ("cls");
cin.clear();
cin.ignore(numeric_limits<streamsize>::max(), '\n');
}
return input;
}

double validdb (string output, string warning, double less, double greater)
{
double input;
while ((cout << output) && !(cin >> input) || input<less || input>greater)
{
cout << warning << '\n';
system ("pause");
system ("cls");
cin.clear();
cin.ignore(numeric_limits<streamsize>::max(), '\n');
}
return input;
}

string validg (string output)
{
string input;
while ((cout << output) && !(getline(cin,input)))
{
system ("msg * This is not a valid input.");
system ("cls");
cin.clear();
cin.ignore(numeric_limits<streamsize>::max(), '\n');
}
return input;
}
#endif

Long and messy, yes. No class, yes. I'm not overly worried about those as it does its job wonderfully, reducing those earlier lines to just "validi ("Enter an integer: ");" for one example. For some reason, the #ifndef, #define, and #endif things aren't doing anything.

My project:
Account.h
c++:

// Account header file

class Account // create a class Account
{
      public:
             Account (int); // constructor
     
             void credit (); // adds to balance
             void debit (); // takes away from balance
             void setBalance (int); // sets balance
             int getBalance (); // displays balance
             
      private:
             int balance; // variable to represent balance
};

Account.cpp
c++:

// Account implementation file

#include <iostream> //necessary for I/O
using std::cout;

#include <valid.h>

#include "Account.h"

Account::Account (int amount) // constructor
{
                 setBalance (amount); // initialize the balance
                 cout << "Account successfully created with balance of " << getBalance() << '\n';
}

void Account::credit () // adds to balance
{
     int addend; // amount to add to balance
     addend = validib ("Enter amount to add to balance: ", 0, 2147483647 - getBalance()); // read how much to add to balance
     setBalance (getBalance() + addend); // increase balance
     cout << "Balance is " << getBalance();
}

void  Account::debit () // subtracts from balance
{
      int decrease; // amount to subtract from balance
      decrease = validib ("Enter amount to subtract from balance: ", 0, getBalance()); // read how much to subtract from balance
      setBalance (getBalance() - decrease); // decrease balance
      cout << "Balance is " << getBalance();
}

void Account::setBalance (int amount) // sets balance
{
     balance = amount;
}

int Account::getBalance () // gets balance
{
    return balance;
}

Account main.cpp
c++:

// Account source code file

#include <iostream> // necessary for I/O
using std::cout;

#include <valid.h> // necessary for validity check

#include "Account.h"

int main()
{
    int choice = 0;
    int amount = validig ("Enter starting balance for account 1: ", "The balance must be greater than 0", 0);
    Account account1 (amount);
   
    while (choice != -1)
    {
          system ("cls");
          cout << "1. Add to balance."
               << "2. Take from balance."
               << "3. Show balance."
               << "-1. Exit.\n";
         
          choice = validib (" ", -1, 3);
         
          system ("cls");
         
          if (choice == 1)
             account1.credit ();
         
          else if (choice == 2)
             account1.debit ();
             
          else if (choice == 3)
             cout << account1.getBalance() << '\n'
             
          else if (choice == -1)
             break;
         
          system ("pause");
    } 
   
    Account account2 (100000);
    system ("cls");
    account2.credit();
    account2.debit();
   
    system ("pause");
    return 0;
}


Even with the #ifndef and whatever, it's still giving me that error.
Just ask if you need help understanding a certain part and I'll tell you what it does.
The validity check lets me control what happens if they enter "a", 100000000000000000, etc for the input when it has to be an int between -2.147b and 2.147b.

Author:  OneOffDriveByPoster [ Mon Oct 11, 2010 10:33 pm ]
Post subject:  Re: Multiple Definitions Problem

The implementations of the functions can be moved to another implementation file and linked in from there. You could also mark the functions as "inline" to solve this problem; however, that may not be appropriate in this case.

Author:  HRI [ Tue Oct 12, 2010 9:33 am ]
Post subject:  RE:Multiple Definitions Problem

Okay, so after making all of my external header functions inline, it mostly fixes it, but has the same error with validig (string,string,int) and validib(string,int,int) :/

I guess I'll try the first suggestion.

EDIT:Oh, I see why it was those two -.-
Those were the two I used in my main function. So what exactly do you mean by the first part? I'm not overly experienced with OOP :s

EDIT:nvm Very Happy I got it working! Finally! At first I inlined the implementation ones, and after I deleted the "inline" part, there was still one with it on. It works perfectly now. Thank you very much.


: