0

このプログラムはほぼ完了しました。公共のコンピューターに移動してコードを変更した後、リンカーエラーが発生していることに気付き、別のエラー(およびその理由)について質問することにしました。

問題の機能は以下のとおりです。何らかの理由で、最後の行「ValidTlds [transferString] ....」は、VSがValidTLDを認識しないことを示しており、その後ろにTldPart ::(ファイルの名前)を追加した場合にのみ認識します。これは他の名前と競合していますか?

また、関数にも関係していると私が信じるより重要なエラーは、未解決の外部シンボルです。正確な行:

Error   3   error LNK2001: unresolved external symbol "public: static class std::map<class String,class String,struct std::less<class String>,class std::allocator<struct std::pair<class String const ,class String> > > TldPart::ValidTlds" (?ValidTlds@TldPart@@2V?$map@VString@@V1@U?$less@VString@@@std@@V?$allocator@U?$pair@$$CBVString@@V1@@std@@@3@@std@@A)    V:\My Documents\Visual Studio 2010\Projects\EmailChecker_HW2\EmailChecker_HW2\TldPart.obj

外部シンボルに関するQ&Aページを読み、いくつかの提案を試みました(元々は2つありました)。クラスの外部で静的関数を宣言することで、1つのリンカーエラーに減らすことができました。何が悪いのか分かりますか?main.cppでは、関数を `TldPart :: PreloadTLDs;'として参照しましたが、その行を削除してもエラーは削除されませんでした(main.cppファイルの先頭に#include "TldPart.h"があります) 。これが関数です。完全なリファレンスとして、ヘッダーとcppファイルを下に投稿します。プロジェクト全体はかなり広範であるため(最後にチェックした1100行近く)、初心者向けにのみこれらを含めました。助けてくれてありがとう、感謝します。

static void PreloadTLDs()

static void PreloadTLDs()
{
    bool initialized = false;
    bool fileStatus = false;
    string tldTest = ""; // used for getline() as allowed.
    char * transferString = " "; // used to transfer chars from string to String

    ifstream infile;

    infile.open("ValidTLDs.txt");

    fileStatus = infile.good();

    if(fileStatus != true)
        cout << "Cannot read ValidTLD's file. Please check your file paths and try again.";
    else
    {
        while(!infile.eof())
        {
            getline (infile, tldTest); // sets the current TLD in the list to a string for comparision

            // converts TLD to lowercase for comparison.
            for(unsigned int x = 0; x<tldTest.length(); x++)
            {
                tldTest[x] = tolower(tldTest[x]);
                transferString[x] = tldTest[x];

                ValidTlds[transferString] = String(transferString);
            }
        }
    }
}

main.cpp(短縮)

#include <iostream>
#include <fstream>
#include "String.h"
#include <map>
#include <string> // used for the allowed getline command
#include "Email.h"
#include "TldPart.h"

using namespace std;

void main()
{
    string getlinetransfer; // helps transfer email from getline to c string to custom String
    double emailTotal = 0.0; // Used to provide a cool progress counter
    double emailCounter = 0.0; // Keeps track of how many emails have been verified.
    int x = 0; // used to set c-string values, counter for loop
    char * emailAddress = new char[getlinetransfer.size() + 1]; // c string used for getting info from getline.

    cout << "Welcome to email validation program!" << endl;
    cout << "Pre-Loading Valid TLD's..... \n" << endl;

    TldPart::PreloadTLDs;
}

TldPart.h

// TldPart.h - TldPart validation class declaration
// Written by ------

#pragma once

#include "String.h"
#include <map>
#include "SubdomainPart.h"
#include <string>
#include <fstream>
#include <iostream>

using namespace std;



class TldPart
{
public:
    // MUST HAVE a defualt constructor (because TldPart is a member of Domain)
    TldPart() {}

    // Takes the address and stores into the Address data member
    void Set(const String& address);

    static void PreloadTLDs();

    // Returns true when the Address is valid or false otherwise
    bool IsValid();

    static map<String, String> ValidTlds;
private:
    String Address; 
};

TldPart.cpp

// TldPart.cpp - TldPart validation class implementation
// Written by Max I. Fomitchev-Zamilov

#pragma once

#include "TldPart.h"
using namespace std;

void TldPart()
{

}

// Takes the address and stores into the Address data member
void TldPart::Set(const String& address)
{
    Address = address;
}

static void PreloadTLDs()
{
    bool initialized = false;
    bool fileStatus = false;
    string tldTest = ""; // used for getline() as allowed.
    char * transferString = " "; // used to transfer chars from string to String

    ifstream infile;

    infile.open("ValidTLDs.txt");

    fileStatus = infile.good();

    if(fileStatus != true)
        cout << "Cannot read ValidTLD's file. Please check your file paths and try again.";
    else
    {
        while(!infile.eof())
        {
            getline (infile, tldTest); // sets the current TLD in the list to a string for comparision

            // converts TLD to lowercase for comparison.
            for(unsigned int x = 0; x<tldTest.length(); x++)
            {
                tldTest[x] = tolower(tldTest[x]);
                transferString[x] = tldTest[x];

                ValidTlds[transferString] = String(transferString);
            }
        }
    }
}

// Returns true when the Address is valid or false otherwise
bool TldPart::IsValid()
{   
    bool tldFound = false;

    map<String, String>::iterator it;

    String TLDMatch;

    TLDMatch = TldPart::ValidTlds.find(Address)->first;
    it = TldPart::ValidTlds.find(Address);

    if(it == ValidTlds.end())
        tldFound == false;
    else
        tldFound == true;

    return tldFound;
}
4

1 に答える 1

2

このコードは、単一の静的変数TldPart::ValidTldsがどこかに定義されることを約束します。

class TldPart
{
    static map<String, String> ValidTlds;
};

これをに追加すればTldPart.cpp、あなたは元気になります。

#include "TldPart.h"
using namespace std;

map<String, String> TldPart::ValidTlds;  // DECLARE YOUR STATIC VARIABLE

void TldPart()
{

}
于 2013-03-13T03:10:33.107 に答える