7

I'm havin a problem in including my files. I got 3 C++ files and all of them got int main(void).

THe problem is whenever i include 1 of them it says that:

function 'int main(void)' already has a body

but if i will remove the int main(void) to other two C++ file this errors will prompt now.

'one or more multiply defined symbols found'

"class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > __cdecl convertInt(int)" (?convertInt@@YA?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@H@Z) already defined in FormatPosDataXml().obj

"class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > __cdecl convertInt(int)" (?convertInt@@YA?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@H@Z) already defined in FormatPosDataXml().obj    

and so forth

this is the codes that i've got:

FormatPosDataXml().cpp

#include <iostream>
#include <sstream>
#include <vector>
#include <string>
#include <cstring>
#include <stdio.h>
#include <conio.h>
#include <stdlib.h>



using namespace std;

#define nextline '\n'

inline bool TextContains(char *text, char ch) {
  while ( *text ) {
    if ( *text++ == ch )
      return true;
  }

  return false;
}

void Split(char *text, char *delims, vector<string> &words) {
  int beg;
  for (int i = 0; text[i]; ++i) {

    while ( text[i] && TextContains(delims, text[i]) )
      ++i;

    beg = i;

    while ( text[i] && !TextContains(delims, text[i]) )
      ++i;
        words.push_back( string(&text[beg], &text[i]) );
  }
}

string convertInt(int number)
{
   stringstream ss;//create a stringstream
   ss << number;//add number to the stream
   return ss.str();//return a string with the contents of the stream
}


string dateFormatChecker(const char *date){
    string strdate=date;
    char getdate[50];
    strcpy_s(getdate, strdate.c_str());

    vector<string> checkdate;
    Split( getdate, "-", checkdate );
    int year, month, day;
    year=atoi(checkdate[0].c_str());
    month=atoi(checkdate[1].c_str());
    day=atoi(checkdate[2].c_str());

    string checkyear, checkmonth, checkday, checkhour, checkminute, checksecond;

            checkyear = convertInt(year);
            if(month<10){
            checkmonth = "0" + convertInt(month);
            }
            else{
            checkmonth = convertInt(month);
            }
            if(day<10){
            checkday = "0" + convertInt(day);
            }
            else{
            checkday = convertInt(day);
            }

            /*
            cout << checkdate[0] << ' ' << checkyear << '\n'
                 << checkdate[1] << ' ' << checkmonth << '\n'
                 << checkdate[2] << ' ' << checkday << '\n';
            */
            if (checkyear.size() != checkdate[0].size()||
                checkmonth.size() != checkdate[1].size()||
                checkday.size() != checkdate[2].size()){
                return "";
            }
    return date;
}

string dateandtimeFormatChecker(const char *dateandtime){
        string strdate=dateandtime;
        char getdateandtime[50];
        strcpy_s(getdateandtime, strdate.c_str());

        vector<string> checkdateandtime;
            Split( getdateandtime, "-: ", checkdateandtime );
        int year, month, day, hour, minute, second;
            year=atoi(checkdateandtime[0].c_str());
            month=atoi(checkdateandtime[1].c_str());
            day=atoi(checkdateandtime[2].c_str());
            hour=atoi(checkdateandtime[3].c_str());
            minute=atoi(checkdateandtime[4].c_str());
            second=atoi(checkdateandtime[5].c_str());

            string checkyear, checkmonth, checkday, checkhour, checkminute, checksecond;

            checkyear = convertInt(year);
            if(month<10){
            checkmonth = "0" + convertInt(month);
            }
            else{
            checkmonth = convertInt(month);
            }
            if(day<10){
            checkday = "0" + convertInt(day);
            }
            else{
            checkday = convertInt(day);
            }
            if(hour<10){
            checkhour = "0" + convertInt(hour);
            }
            else{
            checkhour = convertInt(hour);
            }
            if(minute<10){
            checkminute = "0" + convertInt(minute);
            }
            else{
            checkminute = convertInt(minute);
            }
            if(second<10){
            checksecond = "0" + convertInt(second);
            }
            else{
            checksecond = convertInt(second);
            }


            if (checkyear.size() != checkdateandtime[0].size()||
                checkmonth.size() != checkdateandtime[1].size()||
                checkday.size() != checkdateandtime[2].size()||
                checkhour.size() != checkdateandtime[3].size()||
                checkminute.size() != checkdateandtime[4].size()||
                checksecond.size() != checkdateandtime[5].size()){
                return "";
            }

        //cout << year<< '/' << month << '/' << day << ' ' << hour << ':' << minute << ':' << second << '\n';

        return dateandtime;     
}

string transaction (const char * SequenceNumber, const char * RetailStoreID, const char * WorkStationID, const char * BusinessDayDate, const char * BeginDateTime, const char * StartTransTime, const char * EndTransTime, const char * EndDateTime, const char * RawData){

    string output;

    string bdd, bdt, stt, ett, edt;

    bdd = dateFormatChecker(BusinessDayDate);
    bdt = dateandtimeFormatChecker(BeginDateTime);
    stt = dateandtimeFormatChecker(StartTransTime);
    ett = dateandtimeFormatChecker(EndTransTime);
    edt = dateandtimeFormatChecker(EndDateTime);


    cout << "<Transaction>" << "\n\t<RetailStoreID>"
         << RetailStoreID   << "</RetailStoreID>\n\t<WorkStationID>"
         << WorkStationID   << "</WorkStationID>\n\t<SequenceNumber>"
         << SequenceNumber  << "</SequenceNumber>\n\t<BusinessDayDate>"
         << bdd             << "</BusinessDayDate>\n\t<BeginDateTime>"
         << bdt             << "</BeginDateTime>\n\t<StartTransTime>"
         << stt             << "</StartTransTime>\n\t<EndTransTime>"
         << ett             << "</EndTransTime>\n\t<EndDateTime>"
         << edt             << "</EndDateTime>\n\t<RawData>"
         << RawData         << "</RawData>\n</Transaction>";

    output = _getch();
    return output; 
}

int main(void) {
  vector<string> words;
  char * data = "1,1,SAMPLE,2010-01-31,2011-01-31 14:09:10,2011-01-31 14:42:10,2011-01-31 14:42:10,2011-01-31 14:42:10,JELLY-O RUBBERB\n\r               13.25V.¶üÁËO";

  Split( data, ",", words );

  char SN[11], RSI[200], WSI[200], BDD[100], BDT[100], STT[100], ETT[100], EDT[100], RD[100];

  strcpy_s(SN, words[0].c_str());
  strcpy_s(RSI, words[1].c_str());
  strcpy_s(WSI, words[2].c_str()); 
  strcpy_s(BDD, words[3].c_str());
  strcpy_s(BDT, words[4].c_str());
  strcpy_s(STT, words[5].c_str());
  strcpy_s(ETT, words[6].c_str());
  strcpy_s(EDT, words[7].c_str());
  strcpy_s(RD, words[8].c_str());

  string PosData;
  PosData = transaction(SN,RSI,WSI,BDD,BDT,STT,ETT,EDT,RD);


/* Checker 
  for (int i = 0; i != words.size(); i++){
      cout << words[i] << nextline;
  }
    cout << SN << nextline << RSI << nextline << WSI << nextline << BDD << nextline << BDT << nextline << STT << nextline << ETT << nextline << EDT << nextline << RD; 
*/
return 0;
}

FSNPC.cpp

#include <iostream>
#include <sstream>
#include <vector>
#include <string>
#include <cstring>
#include <stdio.h>
#include <conio.h>
#include <stdlib.h>
#include "FormatPosDataXml().cpp"

using namespace std;


string getstring(string holder){
    if (holder == "" || holder.size()>100){
        exit(1);
    }

    int i=0,ch=0;
    int size;
    char charInput[100];

        strcpy_s(charInput, holder.c_str());
        size = strlen(charInput);

        #define DATA_LENGTH 100
        #define BUFFER_LENGTH (DATA_LENGTH)

        char Buffer[BUFFER_LENGTH];

            while (i < DATA_LENGTH) {
                Buffer[i++] = charInput[i];
                Buffer[i] = '\0';
                if(size == i){
                        break;
                    }
            }
            holder = Buffer;

            strcpy_s(charInput, holder.c_str());
            size = strlen(charInput);

            i = 0;
            for(int j = 0;j<size;j++)
            {
                if (charInput[j] < 2) 
                {
                    if (charInput[j+i] > 2 && charInput[j+i] != 17){
                        charInput[j] = charInput[j+i];
                        charInput[j+i]='\0';
                        i=0;
                        }
                    else{
                        i++;
                        j--;
                    }
                }else if (charInput[j] == 17) 
                {
                    if (charInput[j+i] > 2 && charInput[j+i] != 17){
                        charInput[j] = charInput[j+i];
                        charInput[j+i]='\0';
                        i=0;
                        }
                    else{
                        i++;
                        j--;
                    }
                }
            }
            size = strlen(charInput);
            for(int remove = 0; remove<size ;remove++)
            {
                if (charInput[remove] < 2 || charInput[remove] == 17) 
                {
                    charInput[remove]='\0';
                }
            }

             string handler;
             handler = charInput;

             handler = handler.substr(0, handler.length() - 1);
             return (handler);
    }



/*
int main(void){

    string final;


    string input = "JELLY-O RUBBERB\n\r               13.25V.¶üÁË0";
    string input2 = "STIÁËCK-O CHOCO\n\r               10.52C.ÁË0¶ü";
    string input3 = "STICÁËK-O VANILLA\n\r               10.52C.ÁË0¶ü";


      final = getstring(input)+ "\n" +getstring(input2)+ "\n"
+getstring(input3);
        cout<<final;
        _getch();


    return 0;

}*/

keypress.cpp

#include <iostream>
#include <conio.h>
#include <stdio.h>
#include <string>
#include "FormatPosDataXml().cpp"

    using namespace std;

int c;
char temp[256];

    char getkeypress(char c){

        if (c==0x1b){
            exit(1);
         }

         else if (c==0||c==224)        
          {
                    c = _getch();

                    if (c==0x3b){
                        cout << "You typed: F1\n";
                    }
                    else if(c==0x3c){

                        cout << "You typed: F2\n";
                    }
                    else if(c==0x3d){
                        cout << "You typed: F3\n";
                    }
                    else if(c==0x3e){
                        cout << "You typed: F4\n";
                    }
                    else if(c==0x3f){
                        cout << "You typed: F5\n";
                    }
                    else if(c==0x40){
                        cout << "You typed: F6\n";
                    }
                    else if(c==0x41){
                        cout << "You typed: F7\n";
                    }
                    else if(c==0x42){
                        cout << "You typed: F8\n";
                    }
                    else if(c==0x43){
                        cout << "You typed: F9\n";
                    }
                    else if(c==0x44){
                        cout << "You typed: F10\n";
                    }
                    else if(c==133){
                        cout << "You typed: F11\n";
                    }
                    else if(c==134){
                        cout << "You typed: F12\n";
                    }
          }

          else
          { 
                while((cin.getline(temp, sizeof(temp), '\n'))&&(temp!="")){
                    cout << "You typed:" << temp << '\n';
                    break;
                }
          }

    }
/*  
int main(void){



    while (c^=0x1b){
            cout<<"Press any key:\n";
            c = getkeypress(_getch());
    } 
      _getch();
      return 0;
}
*/

how could I link all of these files. I want them to be a library. How could i do it then?

mgiuca
  • 20,958
  • 7
  • 54
  • 70
  • 5
    This code is way too hard to read. Perhaps you or someone else can format it better. Also you should not post complete code examples in a question. Try stripping it down to the bare minimum code required to generate the error. – mgiuca Feb 09 '11 at 01:31
  • 1
    Why do you want to include a cpp file into another one? What are you trying to accomplish (in abstract terms - don't think of code for now)? – Dave O. Feb 09 '11 at 01:33
  • @Andro, please accept my edit. Your code will be quite a bit more readable. – mgiuca Feb 09 '11 at 01:42
  • @mgiuca: You *should* post complete code examples in a question! You should also narrow down a test case to a manageable size before posting. (I've "voted" on your "edit suggestion", and it won't let me edit until that's either approved (needs more votes) or rejected; I'm unfamiliar with this system.) – Fred Nurk Feb 09 '11 at 01:43
  • @Fred Nurk Sorry, I meant ... well ... don't post three hundred lines of code when your question is about a linker error. Thanks for voting. I'm not sure how it works either, except I know the original asker can immediately approve the edit. – mgiuca Feb 09 '11 at 01:50
  • @Fred Nurk: I guess my vote to approve "put it over the top", so to speak. Unfortunately, while the code is much more nicely formatted now (thanks @mgiuca), it's still just a big bunch of code, with nothing to tell us what he really wants... – Jerry Coffin Feb 09 '11 at 01:51
  • @JerryCoffin: I completely agree; I just don't want people like Andro to post two lines of code without any context by following "you should not post complete code examples". – Fred Nurk Feb 09 '11 at 01:59

5 Answers5

12

In general, it is bad practice to include another .cpp file inside of a .cpp file. The right way is to break out declarations into .h files and put the definitions in .cpp files. Make sure to put a bogus define at the top of each of your .h files to prevent accidental re-inclusion, as in:

#ifndef MYFILE_H_
#define MYFILE_H_

// your code goes here

#endif

When you compile your program, you need to compile all the .cpp files into .o files (or .obj on Windows), and then link them together. For example (Linux/Mac):

g++ -c foo.cpp
g++ -c bar.cpp
g++ foo.o bar.o -o theMainExecutable
EmeryBerger
  • 3,897
  • 18
  • 29
3

You can't include .cpp files, you need to use .h files, which are definitions for functions. Define the stuff in the header files, then implement them (Write the code for them) in the .cpp files.

int main() can only go in one .cpp file, you need to put your code in a function, define it in a header, then include into your main file, then execute it in int main().

Chris
  • 515
  • 1
  • 6
  • 16
  • SO i need to put the codes of the other C++ files to the .h files? – Andro Miguel M. Bondoc Feb 09 '11 at 01:35
  • @Andro See my answer. You should always have one .h file for every .cpp file. Functions should **only** go in .cpp files, never in .h files. Each public function in the .cpp file should have a declaration (the same heading, but with a semicolon instead of a body) in the corresponding .h file. You should always #include .h files from other modules, never .cpp files. – mgiuca Feb 09 '11 at 01:36
  • Technically it is perfectly legal to #include whatever kind of file you want. –  Feb 09 '11 at 01:37
  • 1
    @Øystein Sure it is, but a) it is against all conventions and established practice of the past 30 years, and b) it is quite illegal to import a file which contains any function definition in multiple modules of a project. – mgiuca Feb 09 '11 at 01:41
  • 1
    @mgiuca inline functions (including templates) are extremely common in headers. In other words, "function body" is not the thing that distinguishes what should be in a .cpp vs .h, it's more about where the resulting code should be generated - inline or linked. – tenfour Feb 09 '11 at 01:43
  • I'd guess he's coming from a language such as Lua or Blitz where include means copy and paste the contents of that file into the file you are in now. – Chris Feb 09 '11 at 01:45
  • @mgiuca: Disagree with a) too, I use it, it's common for large aggregate-initialization lists. –  Feb 09 '11 at 01:45
  • @tenfour I am ignoring inline functions since this is a fairly basic mistake and it isn't helpful to go into all the exceptions -- better just to lay some initial ground rules. But yes, if you want to be technically correct, inline functions are an exception. – mgiuca Feb 09 '11 at 01:47
  • CPP uses a header system though, in good practice your 'final' file with everything included in it would have forward declarations, in Blitz at least (not completely sure about Lua) ALL of the code is imported into the 'final' file. – Chris Feb 09 '11 at 01:48
  • @Chris C/C++ #include *does* just copy and paste the contents of that file into the file you are in now. It's just different due to the linker. In Lua, for example, you do want to paste the entire contents of the file because the top-level module is not linked with the other ones later. In C/C++, you can't because you are going to separately link all the definition files later. – mgiuca Feb 09 '11 at 01:48
  • @mgiuca That was kind of what I was getting at, you would have the declarations in your 'final' file and then link the implementation later. – Chris Feb 09 '11 at 01:52
  • @Øystein: "A #include directive shall identify a header or source file that can be processed by the implementation." [§16.2p1] You cannot just name any file. – Fred Nurk Feb 09 '11 at 01:52
  • @Fred: Huh? *goes to get standard* –  Feb 09 '11 at 02:02
  • @Fred: You are right, it does say that. So the file must be processable by the implementation, I stand corrected. Then again, it does not make much sense to include a file that can not be processed. –  Feb 09 '11 at 02:05
  • @Øystein: I was also looking for a requirement that spelled out that a file must also not end with a partial line (missing a terminating newline), but I don't see it in the C++ standard; perhaps it's specified in C's. – Fred Nurk Feb 09 '11 at 02:20
  • @Fred: It's in C++ too, see 2.1.1.2 - no newline => UB. What I really meant with my comment was of course that you could #include anything as long as the file contained valid C++ code. –  Feb 09 '11 at 02:35
  • @Øystein: And I was nitpicking it, of course, because it's just bad advice. Don't include .cpp files. – Fred Nurk Feb 09 '11 at 02:37
  • @Fred: No problem with that, my whole role in this question so far has been nitpicking. –  Feb 09 '11 at 02:39
3

I haven't read all the code, but I would guess you are defining the same function in two modules. Firstly, you should not have a main in all three files. Only one of them. If you are planning to make a library, none of the files should have a main -- that should be in the program which imports your library.

As for convertInt, I suspect it is defined in multiple files. If it isn't, then perhaps it is defined in a header file. You should only put declarations in a header file, such as this:

string convertInt(int number);

(note the semicolon)

The definition should always appear in the corresponding CPP file, like this:

string convertInt(int number) { ... // Body of the function }

If the definition appears in the header file, you have a problem, because every CPP file which #includes that header will contain a duplicate definition.

mgiuca
  • 20,958
  • 7
  • 54
  • 70
  • Ah, having read Chris's answer, I see the problem: You are #including a CPP file, effectively causing it to be used as a header file. – mgiuca Feb 09 '11 at 01:35
  • Definitions may appear in headers as well, most commonly as inline. –  Feb 09 '11 at 01:39
  • @Øystein Well, only as inline (it's the only way to avoid an error). I was trying to lay some initial ground rules for beginning C++, not explain all the quirks of the language. – mgiuca Feb 09 '11 at 01:43
  • By "most commonly" I think you mean "always". – tenfour Feb 09 '11 at 01:44
  • @tenfour and mgiuca: No, I mean "most commonly". You write your whole program in a header and just include it in a .cpp file (or just compile the header, unless your compiler freaks out) if you wish. –  Feb 09 '11 at 01:51
  • @Øystein I think you are massively confusing the issue. First, it doesn't help to bring up all the possible special cases which you might use as an advanced user when the OP clearly has not gotten the fundamental concept of header files. Second, why would you ever write a program in a header file and include it in a .cpp file? It would break if you ever included it in multiple .cpp files and linked them. (Yes, inline is an exception, but it's the only exception.) Just because you *can* do something doesn't mean you should bring it up here, especially if it has no use ever. – mgiuca Feb 09 '11 at 01:57
  • @mgiuca: Knowledge does not hurt. Even though the OP won't have a use for it, you and tenfour should be happy at least :) And this does have its use, as I mentioned in a comment to another answer. –  Feb 09 '11 at 02:00
  • @Øystein Knowledge certainly can hurt. As someone who has taught this concept at university for the past five years, I know better than to offer students random advice, even if technically correct. If something *can* be done but shouldn't be with a handful of advanced exceptions, it is better to simply tell students *not* to do it, rather than say "sure you can do it" and then start a lengthy discussion about when and why. Students are then less likely to think it's okay. Even though, you *can*, I don't want to encourage people to go #including .cpp files or placing definitions in headers. – mgiuca Feb 09 '11 at 03:01
  • @mgiuca: I never offered any advice to the OP. As a programmer I naturally react to inaccuracies, and prefer not to see false facts. I think part of what makes this community good is the pedantry going on here, and the attention that is payed to being succinct and accurate. It has taught me a lot. –  Feb 09 '11 at 03:13
2

Without weeding through your huge jumble of code, it seems that you are trying to merge different source files into the same project resulting in conflicting names.

I think you will just need to find a way to structure your code so that you don't get conflicting symbols. You obviously cannot have three different entry-points in your application. Which one do you want to be called? If you want the user to choose, for example, then you have to write the code for this, and name your functions accordingly.

For example with convertInt, if you need to include different variations of this function in your application, then you will need to name it properly to distinguish it.

Possible solutions for convertInt include:

  1. Wrap convertInt (and possibly other functions) in a namespace, and call them like Variation1::convertInt(x)
  2. Just give things unique names. convertInt1, convertInt2, etc.
  3. Take the time to merge related functions. I doubt that two functions named convertInt, in the same project, with the same signature, actually do different things. Merge them so there is only 1 function to think about.

Apologies if my answer has nothing to do with your problem.

tenfour
  • 36,141
  • 15
  • 83
  • 142
  • 1
    He's not trying to define different versions of `convertInt`. Rather, there is only one version, but it is being #included into all three files. – mgiuca Feb 09 '11 at 01:45
1

The Technique I use as to import classes and variables from other files is : (as I know of)

  • Importing the Raw C++ File(s). [Tho not the most preferred method.]

Let's say I've two C++ Files :

file_1.cpp

#include<iostream>
using namespace std;

int x = 8;            // A Random Variable

class Math{           // A Random Class

    public:

        static int multiplyBy5(int x){
            return x * 5;
};

file_2.cpp [The Driver File let's Say]

#include<iostream>
#include "file_2.cpp"                // This can be the Relative/Absolute Path.
using namespace std;

int main()
{
    // Importing External Variable present in the imported File. [Tho we don't need to define `extern` as we're importing the whole file itself.]
    extern int x;                    
    cout<<x<<endl;
    cout<<Math::multiplyBy5(5)<<endl;
    return 0;
}

Note :

  1. The main() method should exist only in the Driver Program. Defining main() method in other files will break your driver code.
  2. You can replace the .cpp extensions of the files being imported by .h [Interface] which is considered a better practice then importing directly the raw .cpp.
  3. Doing so, you don't need to compile the other files you're importing. So, basically you can access and run all the files all together by simply running the driver code i.e. -
g++ file_2.cpp -o file_2
./file_2
Rahul Bordoloi
  • 145
  • 3
  • 9