不断收到错误lnk2019

Posted

技术标签:

【中文标题】不断收到错误lnk2019【英文标题】:keep getting error lnk 2019 【发布时间】:2014-04-24 01:35:18 【问题描述】:

我正在尝试创建一个基本的登录页面,但是当我尝试构建程序时,出现语法错误。

这是我得到的错误:

Error   1   error LNK2019: unresolved external symbol "struct UserRecord __cdecl ReadData(class 
std::basic_ifstream<char,struct std::char_traits<char> > &,struct UserRecord)" (?ReadData@@YA?
AUUserRecord@@AAV?$basic_ifstream@DU?$char_traits@D@std@@@std@@U1@@Z) referenced in function _main  
c:\Users\Emerson\documents\visual studio 
2012\Projects\ConsoleApplication11\ConsoleApplication11\small_eas12d_p6.obj ConsoleApplication11

当程序从我能得到的内容中调用主函数时,我得到了两次相同的错误。但是我想不出办法来解决它。

#include <iostream>
#include <fstream>
#include <string>
using namespace std;

const int Max_Persons = 50, Max_Attempts = 3;

struct UserRecord

   string userID;
   string password;
   int PIN;

;

typedef struct UserRecord AccountInfo;

void PrintHeading();
void Login_Success();
void Kicked();
void Login_Failed(int);
void FileCheck(ifstream &);
UserRecord ReadData(ifstream &, AccountInfo);
bool checkData(bool, AccountInfo, int);




int main()

    int i = 0;
    bool passorfail = false;
    int attempts = 0;

    ifstream infile;



    AccountInfo Accounts[Max_Persons];

    FileCheck(infile);

    Accounts[Max_Persons] = ReadData(infile, Accounts[Max_Persons]);

    PrintHeading();

    do
    
        passorfail = checkData(passorfail, Accounts[Max_Persons], attempts);

     while (!passorfail || attempts < 3);

    if (attempts <= 3)
        Kicked();

    if(passorfail)
        Login_Success();

    infile.close();

    return 0;


AccountInfo ReadData(ifstream & infile, AccountInfo Accounts[Max_Persons])

    int UserNum;
    string str;


    getline(infile, str, '\n' );

     UserNum = atoi(str.c_str());


    for(int i = 0; i < UserNum; i++)
    
        infile >> Accounts[i].userID;

        infile >> Accounts[i].password;

        infile >> Accounts[i].PIN;

    



    return Accounts[Max_Persons];




void FileCheck(ifstream & infile)

    string FileName;

    cout << "Filenames must not contain blanks ." << endl;
    cout << "Please enter the file name to decode ->" << endl;
    cin >> FileName;


        infile.open(FileName.c_str());

        while(!infile)
        

                FileName.clear();

                cout << "Sorry \"" << FileName << "\" is not a valid file name. Please try again." << endl;

                cin >> FileName;
                infile.open(FileName.c_str());
        

        return;



bool checkData(bool passorfail, AccountInfo Accounts[Max_Persons], int attempts)


    string givenID;
    string givenPass;
    int givenPin;

    do
    
        cout << "Login" << endl;
        cout << "UserID: ";
        cin >> givenID;
        cout << endl << "Password: ";
        cin >> givenPass;
        cout << endl << "Pin: ";
        cin >> givenPin;

        for(int i = 0; i < Max_Persons; i++)
        
            if(givenID == Accounts[i].userID)
            
                if (givenPass == Accounts[i].password)
                
                    if (givenPin == Accounts[i].PIN)
                    
                        passorfail = true;
                    
                
            
        

        if(!passorfail)
            
                Login_Failed(attempts);
                attempts++;
            

     while (!passorfail || attempts < 3);

    return passorfail;


void PrintHeading()

    cout << "-----------------------------------------------------------\n";
    cout << "------         Welcome to MyGreatWebsite.com         ------\n";
    cout << "-----------------------------------------------------------\n";
    cout << "**Unauthorized access to this stie is strictly prohibited**";

    return;


void Login_Failed(int attempts)

    cout << "Sorry, that username and/or password was incorrect" << endl;
    cout << "You have used " << attempts << " of your attempts to login. " << endl;
    cout << "You only have 3 attempts total before you are automatically " << endl;
    cout << "kicked from the system" << endl; 

    return;


void Kicked()

    cout << "Sorry, you have reached the maximum number attempts " << endl;
    cout << "to access this site, please have a good day" << endl;

    return;


void Login_Success()

    cout << "Welcome to MyGeatWebsite.com" << endl;
    cout << "Enjoy your stay" << endl;

    return;

提前感谢您的帮助。

【问题讨论】:

【参考方案1】:

LNK2019 不是“语法错误”。这是链接器发出的诊断信息。这意味着某些已声明和使用的函数,在本例中为 ReadData,尚未定义,或者如果已定义,则尚未编译,或者如果已编译,则尚未传递给链接器。

您对ReadData 的前向声明与实现不匹配。

避免这种情况的一个简单方法是不使用前向声明。前向声明在语言中是有原因的(支持递归,支持单独编译),但作为一般约定,它们没有优势并且确实存在一些问题,包括额外的维护工作和您现在遇到的问题。而是将每个函数定义放在第一次使用之前。

【讨论】:

前向声明应该出现在大多数具有多个编译单元的非平凡的生产质量程序中。它们在减少耦合方面非常有用(紧密耦合通常表明设计不佳)并且还有助于封装。对递归和单独编译的支持是次要的,实际上是上述内容的派生。 @icepack:您能否详细说明对单独编译的支持是次要的以及使用多个编译单元的派生。 我的意思是 技术上 需要单独编译是 设计 决定实际创建多个编译单元(尽管主要部分我的评论是关于松散耦合)。 哦,有道理(不) 好吧,对于任何严肃的事情,我通常先从设计开始,然后再投入一堆代码。也许这只是我。无论如何,“作为一般惯例,他们没有优势”建议是一个糟糕的建议,恕我直言。【参考方案2】:

澄清一下,以 LNK 开头的 Visual Studio 错误是 Linker 错误。 现在对于此错误的原因,您似乎已将 ReadData 原型声明为

UserRecord ReadData(ifstream &, AccountInfo);

在函数定义中是:

AccountInfo ReadData(ifstream & infile, AccountInfo Accounts[Max_Persons])  

链接器可能假设有两个不同的函数,一个接收单个AccountInfo,另一个接收AccountInfo[] 的数组。更改ReadData 的原型以匹配函数定义,应该可以解决问题。

【讨论】:

更改了原型,但我仍然遇到同样的错误 你是怎么改的?您的main() 需要一个带有AccountInfo 的函数。因此,请确保将函数和原型都声明为 UserRecord ReadData(ifstream &amp; file, AccountInfo account); 或更改 main 上的函数调用并将数组传递给它。

以上是关于不断收到错误lnk2019的主要内容,如果未能解决你的问题,请参考以下文章

编译代码时出现 LNK2019 错误

QT Creator - LNK2019 和 LNK1120 错误 [重复]

尝试继承时Qt中的LNK错误?

混合 C 和 C++ 时继续出现 LNK2019 错误

错误 LNK2019 - 抽象类中的虚拟析构函数 [重复]

LNK2019“未解析的外部符号”错误(C++ OpenGL)