hi, i have problems with static member function
the compiler's problems = "undefined reference"

**Design a class Numbers that can be used to translate whole dollar amounts in the
range 0 through 9999 into an English description of the number. For example, the
number 713 would be translated into the string seven hundred thirteen, and 8203
would be translated into eight thousand two hundred three. The class should have a
single integer member variable:
int number;
and a static array of string objects that specify how to translate key dollar amounts
into the desired format. For example, you might use static strings such as
string lessThan20[20] = {"zero", "one", ..., "eighteen", "nineteen"};
string hundred = "hundred";
string thousand = "thousand";
The class should have a constructor that accepts a nonnegative integer and uses it to
initialize the Numbers object. It should have a member function print() that prints
the English description of the Numbers object
**
first time i make this program, i make w/o static std::string, i use normal string and it works, but then i tried to use static std::string for class varables teh compiler keep telling errors

here's the main.cpp:

#include "Account.h"
#include <iostream>
#include <cctype>
#include <fstream>


int main()
{
    int num;
    Account write;
    char choice;
    std::string input;
    std::fstream file("below20.txt", std::ios::in);
    for(int count = 0; count < 20; count++)
    {
        getline(file, input);
        Account::setlessThan20(count, input);
    }
    file.close();

    file.open("thousand.txt", std::ios::in);
    for(int count = 0; count < 10; count++)
    {
        getline(file, input);
        Account::setThousand(count, input);
    }
    file.close();

    file.open("hundred.txt", std::ios::in);
    for(int count = 0; count < 10; count++)
    {
        getline(file, input);
        Account::setHundred(count, input);
    }
    file.close();

    file.open("tens.txt", std::ios::in);
    for(int count = 0; count < 9; count++)
    {
        getline(file, input);
        Account::setTens(count, input);
    }
    file.close();

    file.open("ones.txt", std::ios::in);
    for(int count = 0; count < 10; count++)
    {
        getline(file, input);
        Account::setOnes(count, input);
    }
    file.close();

    do
    {
        std::cout<<"enter number = ";
        std::cin>>num;
        write.setNum(num);
        write.print();

        std::cout<<"do you want to print again? ";
        std::cin>>choice;
    }while(toupper(choice) != 'N');
}

here's the Account.h

#ifndef ACCOUNT_H
#define ACCOUNT_H

#include <string>


class Account
{
    private:
    static std::string lessThan20[20];
    static std::string thousand[9];
    static std::string hundred[9];
    static std::string tens[8] ;
    static std::string ones[9] ;
    char data[10];

    public:

    void setNum(int);
    void print();
    void set();

    static void setlessThan20(int, std::string);
    static void setThousand(int, std::string);
    static void setHundred(int, std::string);
    static void setTens(int, std::string);
    static void setOnes(int, std::string);
};

#endif

here's the Account.cpp

#include "Account.h"
#include <string>
#include <cstdlib>
#include <iostream>

void Account::setlessThan20(int a, std::string x)
{
    lessThan20[a] = x;
}

void Account::setThousand(int a, std::string x)
{
    thousand[a] = x;
}

void Account::setHundred(int a, std::string x)
{
    hundred[a] = x;
}

void Account::setTens(int a,std::string x)
{
    tens[a] = x;
}

void Account::setOnes(int a, std::string x)
{
    ones[a] = x;
}
void Account::setNum(int a)
{
    itoa(a, data, 10);
    data[5] = '\0';
}
void Account::print()
{

    int num;
    char temp[3];
    temp[0] = data[0];
    temp[1] = '\0';
    num = atoi(temp);
    std::cout<<data<<std::endl;

    if(num > 0)
    {
        num--;
        std::cout<<thousand[num]<<" ";
    }

    temp[0] = data[1];
    temp[1] = '\0';
    num = atoi(temp);

    if(num > 0)
    {
        num -=1;
        std::cout<<std::endl<<hundred[num]<<" ";
    }

    temp[0] = data[2];
    temp[1] = '\0';
    num = atoi(temp);
    if(num >= 2)
    {
        num -=2;
        std::cout<<tens[num]<<" ";
        temp[0] = data[3];
        temp[1] = '\0';
        num = atoi(temp);
        num--;
        std::cout<<ones[num]<<std::endl;
    }
    else
    {
        temp[0] = data[2];
        temp[1] = data[3];
        temp[2] = '\0';
        num = atoi(temp);
        std::cout<<lessThan20[num]<<std::endl;
    }

}

erm, whats wrong with my code? anyone can tell?

Edited 4 Years Ago by Sendy Hipo

erm, whats wrong with my code? anyone can tell?

erm, not if you don't tell us where the errors are...

erm i tell it in my first post , inside the static member function said "undefined reference to account::lessThan20"

edit:
i believe the problem is inside the Account.cpp, all of these functions have problems D:

  void Account::setlessThan20(int a, std::string x)
    {
        lessThan20[a] = x;
    }

    void Account::setThousand(int a, std::string x)
    {
        thousand[a] = x;
    }

    void Account::setHundred(int a, std::string x)
    {
        hundred[a] = x;
    }

    void Account::setTens(int a,std::string x)
    {
        tens[a] = x;
    }

    void Account::setOnes(int a, std::string x)
    {
        ones[a] = x;
    }

Edited 4 Years Ago by Sendy Hipo

Try to use like this:

#ifndef ACCOUNT_H
#define ACCOUNT_H
#include <string>
using namespace std;

instead of typing std::string.
And it's better to include those things only in the Account.h header, like put it there:

#include <iostream>
#include <fstream>
#include <vector>
#include <string>
#include <stdlib.h>
#include <cctype.h>
//etc.
using namespace std;

And than, the Account.h is included in the main and .cpp version so there is no need for duplicate includes.

Later edit:
static std::string lessThan20[20]; Do you know something about the static thing?
If not, I would suggest taking a look over this:
http://www.cprogramming.com/tutorial/statickeyword.html
http://www.learncpp.com/cpp-tutorial/811-static-member-variables/
http://publib.boulder.ibm.com/infocenter/comphelp/v8v101/index.jsp?topic=%2Fcom.ibm.xlcpp8a.doc%2Flanguage%2Fref%2Fcplr038.htm

Edited 4 Years Ago by Lucaci Andrew

lucaciandrew: I have to disagree with you on this - the fully qualified std::string is generally preferable to using namespace std;, especially inside headers. Headers get included in multiple locations, some of which could present namespace collisions if you have the std namespace (or any other, for that matter) used in them will-nilly, and when the collision occurs because of a header, it can cause bugs that are especially hard to track down. It goes against the entire purpose of having discrete namespaces to then turn around and have a blanket using on them everywhere you have a need for something within them.

The same applies to headers; you actually want to limit the number of headers you #include within other headers, as any client programmer who then uses that header may be unaware of all the things the header adds to their code.

As a rule, you want to restrict the visibility of exernal code, not broaden it.

BTW, <stdlib.h> and <ctype.h> are the C forms of the headers; in C++ one should always use <cstdlib> and <cctype> instead. As for <cctype.h>, there is no such thing; I assume that you either got confused, or it was a typo.

I hope you take these critiques in the spirit they were intended.

Edited 4 Years Ago by Schol-R-LEA

static std::string lessThan20[20]; Do you know something about the static thing?

erm actually i do, i think the problem is because i dont set any value to my static? if i remember correctly, static variables set defaul value with = 0 right?

im a bit confuse how to set value for my static string array, so i came up withh the idea to set those static variables with static member functions, but i think i have prbolems with my static member functions(actually i dont really know whats the main problem), because i dont understand why my compiler tells "undefined reference to Account::lessThan20, Account::thousand" , and so on on to all my static variables, is this because i dont set value of static variables inside my header (outside class declaration)?

static void setlessThan20(int, std::string);
static void setThousand(int, std::string);
static void setHundred(int, std::string);
static void setTens(int, std::string);
static void setOnes(int, std::string);

Edited 4 Years Ago by Sendy Hipo

Yeah, well static members should always be initialized outside the class.
You see, you put there static string lessThan20[20] but you didn't allocate memory for it. Static members are allocated when the program starts, and are deallocated when the program ends. So, after you have put the static string lessThan20[20] you have to allocate memory for it, and that must be done outside the class and the main() function.

Here's a quick example of what I want to say:

#include <iostream>
#include <string>
using namespace std;
class s{
    static string a[20];
public:
    static void seta(string b, int pos){
        a[pos]=b;
    }
    static string geta(int pos){
        return (a[pos]);
    }
};
string s::a[]={"","","","","","","","","","","","","","","","","","","",""};

int main(){
    s ss;
    string b="abcdefgh";
    ss.seta(b, 0);
    cout<<ss.geta(0);
    return (0);
}

You see, I have allocated space for my static string a[20] here in string s::a[]={"","","","","","","","","","","","","","","","","","","",""};
You already noticed that there are 20 x "" because I said that it's size should be 20 in my class.
Hope you understood my example.

So in your case, you have in the class:

    static std::string lessThan20[20];
    static std::string thousand[9];
    static std::string hundred[9];
    static std::string tens[8] ;
    static std::string ones[9] ;

try to do an initialization outside the class, and the main:

std::string Account::lessThan20[]={"","","","","","","","","","","","","","","","","","","",""};
std::string Account::thousand[]={"","","","","","","","",""};
std::string Account::hundred[]={"","","","","","","","",""};
std::string Account::tens[]={"","","","","","","",""};
std::string Account::ones[]={"","","","","","","","",""};

ps. I know, it looks kinda ugly.

If you have further questions, just post them, and we will try to answer to them.

Edited 4 Years Ago by Lucaci Andrew

i changed my code to:
Account.h

    #ifndef ACCOUNT_H
    #define ACCOUNT_H
    #include <string>
    class Account
    {
    private:
    static std::string lessThan20[20];
    static std::string thousand[9];
    static std::string hundred[9];
    static std::string tens[8] ;
    static std::string ones[9] ;
    char data[10];
    public:
    void setNum(int);
    void print();
    void set();

    };
std::string Account::lessThan20[] = {"zero","one","two","three","four","five","six","seven","eight",
                                    "nine","ten","eleven","twelve","thirteen","fourteen","fifteen","sixteen",
                                    "seventeen", "eightteen", "nineteen"};

std::string Account::thousand[] = {"one thousand", "two thousand","three thousand", "four thousand","five thousand","six thousand", "seven thousand","eight thousand","nine thousand"};

std::string Account::hundred[] = {"one hundred","two hundred","three hundred","four hundred","five hundred","six hundred","seven hundred","eight hundred","nine hundred"};

std::string Account::tens[] = {"twenty","thirty","forty","fifty","sixty","seventy","eighty","ninety"};

std::string Account::ones[] = {"one","two","three","four","five","six","seven","eight","nine"};

 #endif

Account.cpp

    #include "Account.h"
    #include <string>
    #include <cstdlib>
    #include <iostream>

    void Account::setNum(int a)
    {
        itoa(a, data, 10);
        data[5] = '\0';
    }
    void Account::print()
    {
    int num;
    char temp[3];
    temp[0] = data[0];
    temp[1] = '\0';
    num = atoi(temp);
    std::cout<<data<<std::endl;
    if(num > 0)
    {
    num--;
    std::cout<<Account::thousand[num]<<" ";
    }
    temp[0] = data[1];
    temp[1] = '\0';
    num = atoi(temp);
    if(num > 0)
    {
    num -=1;
    std::cout<<std::endl<<Account::hundred[num]<<" ";
    }
    temp[0] = data[2];
    temp[1] = '\0';
    num = atoi(temp);
    if(num >= 2)
    {
    num -=2;
    std::cout<<tens[num]<<" ";
    temp[0] = data[3];
    temp[1] = '\0';
    num = atoi(temp);
    num--;
    std::cout<<Account::ones[num]<<std::endl;
    }
    else
    {
    temp[0] = data[2];
    temp[1] = data[3];
    temp[2] = '\0';
    num = atoi(temp);
    std::cout<<Account::lessThan20[num]<<std::endl;
    }

  }

then compiler tells "multiple definition of Account::lessThan20, thousand, hundred" and so on to all my static variables

Edited 4 Years Ago by Sendy Hipo

Yeah, well, you should check your includes, maybe you have double included a file, and that takes on as double definition.
Later edit:
Nah, silly me, it was something else:

#include "Account.h"
 #include <iostream>
#include <cctype>
#include <fstream>
std::string Account::lessThan20[]={"","","","","","","","","","","","","","","","","","","",""};
std::string Account::thousand[]={"","","","","","","","",""};
std::string Account::hundred[]={"","","","","","","","",""};
std::string Account::tens[]={"","","","","","","",""};
std::string Account::ones[]={"","","","","","","","",""};

int main(){
    int num;
    Account write;
    char choice;
    std::string input;
    std::fstream file("below20.txt", std::ios::in);
    for(int count = 0; count < 20; count++){
        getline(file, input);
        Account::setlessThan20(count, input);
    }
    file.close();

    file.open("thousand.txt", std::ios::in);
    for(int count = 0; count < 10; count++){
        getline(file, input);
        Account::setThousand(count, input);
    }
    file.close();

    file.open("hundred.txt", std::ios::in);
    for(int count = 0; count < 10; count++){
        getline(file, input);
        Account::setHundred(count, input);
    }
    file.close();

    file.open("tens.txt", std::ios::in);
    for(int count = 0; count < 9; count++){
        getline(file, input);
        Account::setTens(count, input);
    }
    file.close();

    file.open("ones.txt", std::ios::in);
    for(int count = 0; count < 10; count++){
        getline(file, input);
        Account::setOnes(count, input);
    }
    file.close();

    do{
        std::cout<<"enter number = ";
        std::cin>>num;
        write.setNum(num);
        write.print();

        std::cout<<"do you want to print again? ";
        std::cin>>choice;
    }
    while(toupper(choice) != 'N');
}

You have to put them in the same file as the int main() function is.
Told you: static variables are allocated at the start up of the program, and are deallocated at the end of the program. So, the int main() is the start point in your program, so when it pharshes through the int main(), it will then call for those static functions, but they aren't (yet) initialized, because you initialized after your class. So, when putting them before the int main(), it will search for them, it will get the allocation first, than set them accordingly to your input functions.
If you do have further questions, post them here.

Edited 4 Years Ago by Lucaci Andrew

oh! thx! my mistake too, i put it iniside the main function before, and now i put it before main function and it works, thankyou very much, really appreciate your help!

This question has already been answered. Start a new discussion instead.