简体   繁体   中英

C++ undefined symbols for architecture x86_64

I know there are many questions with the same issue but I did not find anything close to my problem.

I am using Xcode for a C++ project and I get the following errors:

Undefined symbols for architecture x86_64:
  "Decrypt::printEncryptedString()", referenced from:
      _main in main.o
  "Decrypt::Decrypt()", referenced from:
      _main in main.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)

My main file is the folowing:

#include <iostream>
#include "Decrypt.hpp"

int main(int argc, const char * argv[]) {
    Decrypt decryption = Decrypt();
    decryption.printEncryptedString();
    std::cout << "Hello, World!\n";
    return 0;
}

My header:

#ifndef Decrypt_hpp
#define Decrypt_hpp

#include <stdio.h>

#endif /* Decrypt_hpp */
#include <string>

class Decrypt{
    std::string toDecrypt;
    std::string encrypted;

    int keyLength; // key between 2 and 12
public:
    Decrypt();
    void printEncryptedString();

};

and the .cpp file:

#include <stdio.h>
#include <string>
#include <stdlib.h>
#include <iostream>

class Decrypt{
    std::string toDecrypt;
    std::string encrypted;

    int keyLength;

public:
    Decrypt(){
        int i;
        unsigned char ch;
        FILE *fpIn;
        fpIn = fopen("ctext.txt", "r");

        i=0;
        while (fscanf(fpIn, "%c", &ch) != EOF) {
            /* avoid encrypting newline characters */
            /* In a "real-world" implementation of the Vigenere cipher,
             every ASCII character in the plaintext would be encrypted.
             However, I want to avoid encrypting newlines here because
             it makes recovering the plaintext slightly more difficult... */
            /* ...and my goal is not to create "production-quality" code =) */
            if (ch!='\n') {
                i++;
                encrypted += ch;

            }
        }

        fclose(fpIn);
    }
    //void CalculateKeyLength(){}

    void printEncryptedString(){
        std::cout << encrypted << '\n';
    }

};

I do not understand what causes the errors. Can someone help me please?

You are allowed to define the Decrypt class multiple times in your project (otherwise inclusion of header files would be a problem!), but each definition must be exactly the same.

You have two definitions that are different from each other. One has inline definitions of its member functions; the other does not.

This has undefined behaviour and, here, that is apparently manifesting as your compiler ignoring the definition in the .cpp , which it'll "see" second. That second definition contains your member function definitions, so they're not making it into the build.

In your .cpp file, define your member functions individually like this:

Decrypt::Decrypt()
{
    int i;
    unsigned char ch;
    FILE *fpIn;
    fpIn = fopen("ctext.txt", "r");

    i=0;
    while (fscanf(fpIn, "%c", &ch) != EOF) {
        /* avoid encrypting newline characters */
        /* In a "real-world" implementation of the Vigenere cipher,
         every ASCII character in the plaintext would be encrypted.
         However, I want to avoid encrypting newlines here because
         it makes recovering the plaintext slightly more difficult... */
        /* ...and my goal is not to create "production-quality" code =) */
        if (ch!='\n') {
            i++;
            encrypted += ch;

        }
    }

    fclose(fpIn);
}

void Decrypt::printEncryptedString()
{
    std::cout << encrypted << '\n';
}

Just like that. Not inside a second class definition.

The chapter on member functions in your C++ book will explain all this to you, and more.

Also note that your header guard in Decrypt.hpp has been "closed" in the middle of the file rather than at the end, which cannot be intentional?

Your definition of Decrypt::printEncryptedString() is different than your declaration. In your declaration, it is named void Decrypt::printEncryptedString and your definition defines the function inline void Decrypt::printEncryptedString . If you remove the inline keyword from your function definition, it should compile.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM