将C ++文件包含到另一个C ++文件中

时间:2011-02-09 01:28:24

标签: c++ header include

我在包含我的文件时遇到了问题。我有3个C ++文件,所有这些文件都是int main(void)。

问题在于,每当我包含其中一个时,就会说:

function'int main(void)'已经有一个正文

但如果我将int main(void)删除到其他两个C ++文件,则此错误现在会提示。

'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    

等等

这是我得到的代码:

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;
}
*/

我怎么能链接所有这些文件。我希望他们成为一个图书馆。我怎么能这样做呢?

5 个答案:

答案 0 :(得分:7)

通常,在.cpp文件中包含另一个.cpp文件是不好的做法。正确的方法是将声明分解为.h个文件,并将定义放在.cpp个文件中。确保在每个.h文件的顶部放置一个虚假的定义,以防止意外重新包含,如:

#ifndef MYFILE_H_
#define MYFILE_H_

// your code goes here

#endif

编译程序时,需要将所有.cpp文件编译成.o个文件(或Windows上的.obj),然后将它们链接在一起。例如(Linux / Mac):

g++ -c foo.cpp
g++ -c bar.cpp
g++ foo.o bar.o -o theMainExecutable

答案 1 :(得分:3)

您不能包含.cpp文件,您需要使用.h文件,它们是函数的定义。在头文件中定义东西,然后在.cpp文件中实现它们(为它们编写代码)。

int main()只能放在一个.cpp文件中,需要将代码放在函数中,在头文件中定义,然后包含到主文件中,然后在int main()中执行。

答案 2 :(得分:3)

我没有阅读所有代码,但我猜你在两个模块中定义了相同的功能。首先,您不应该在所有三个文件中都有main。只有其中一个。如果您打算创建一个库,那么这些文件都不应该有main - 这应该在导入您的库的程序中。

至于convertInt,我怀疑它是在多个文件中定义的。如果不是,则可能是在头文件中定义的。您只应将声明放在头文件中,例如:

string convertInt(int number);

(注意分号)

定义应始终出现在相应的CPP文件中,如下所示:

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

如果定义出现在头文件中,则会出现问题,因为#includes该头文件的每个CPP文件都将包含重复的定义。

答案 3 :(得分:2)

如果不仔细检查你的大量代码,似乎你试图将不同的源文件合并到同一个项目中,从而导致名称冲突。

我认为您只需要找到一种方法来构建代码,这样就不会出现冲突的符号。显然,您的应用程序中不能有三个不同的入口点。你想叫哪一个?例如,如果您希望用户选择,则必须为此编写代码,并相应地命名您的函数。

例如使用convertInt,如果您需要在应用程序中包含此功能的不同变体,则需要正确命名以区分它。

convertInt的可能解决方案包括:

  1. 在命名空间中包装convertInt(以及可能的其他函数),并将其称为Variation1::convertInt(x)
  2. 只要给出独特的名字。 convertInt1convertInt2
  3. 花时间合并相关功能。我怀疑在同一个项目中,具有相同签名的两个名为convertInt的函数实际上做了不同的事情。合并它们,这样只需要考虑一个功能。
  4. 如果我的回答与您的问题无关,请道歉。

答案 4 :(得分:0)

我用来从其他文件导入类和变量的技术是:(据我所知)

  • 导入Raw C ++文件。 [不是最优选的方法。]

假设我有两个C ++文件:

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 [说驱动程序文件]

#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;
}

注意:

  1. main()方法仅应存在于驱动程序中。在其他文件中定义main()方法将破坏您的驱动程序代码。
  2. 您可以替换由.cpp [Interface]导入的文件的.h扩展名,这是比直接导入原始.cpp更好的做法。
  3. 这样做,您无需编译要导入的其他文件。因此,基本上,您只需运行驱动程序代码即-
  4. ,就可以一起访问和运行所有文件。
g++ file_2.cpp -o file_2
./file_2