简体   繁体   English

需要帮助找到未定义的符号

[英]Need help finding Undefined Symbols

I have a program that is compiling without warnings or errors but is hitting Undefined Reference problems. 我有一个正在编译的程序,没有警告或错误,但遇到未定义的引用问题。 The program consists of three files. 该程序包含三个文件。 mybash.cc is a file I wrote. mybash.cc是我编写的文件。 The two parser files were head start code given by a professor. 这两个解析器文件是教授给出的起始代码。 The program is to display the working directory as a shell prompt and take in a command. 该程序将工作目录显示为shell提示符并接受命令。 The command is analyzed by parse and then information about it is printed by mybash. 通过分析分析该命令,然后通过mybash打印有关该命令的信息。 All of my Undefined Reference errors are not functions but a mess of characters. 我所有的未定义参考错误都不是函数,而是一堆字符。 I am compiling using "gcc -g -Wall -Werror -O2 -c parser.c", "gcc -g -Wall -Werror -O2 parser.o mybash.cc -o mybash". 我正在使用“ gcc -g -Wall -Werror -O2 -c parser.c”,“ gcc -g -Wall -Werror -O2 parser.o mybash.cc -o mybash”进行编译。 I assume the problem is a linker error or I am not initializing/declaring something correctly. 我认为问题是链接器错误,或者我没有正确初始化/声明某些内容。 However, I am having trouble finding the problem. 但是,我很难找到问题所在。

Edit: Here are the undefined errors, 编辑:这是未定义的错误,

p1% make
gcc -g -Wall -Werror -O2  -c  parser.c
gcc -g -Wall -Werror -O2 parser.o mybash.cc -o mybash
Undefined                       first referenced
 symbol                             in file
_ZNKSt5ctypeIcE13_M_widen_initEv    /var/tmp//ccQT23cT.o
_Z16ParseCommandLinePcP11CommandData /var/tmp//ccQT23cT.o
_ZNSo3putEc                         /var/tmp//ccQT23cT.o
_ZNSolsEi                           /var/tmp//ccQT23cT.o
_ZSt16__throw_bad_castv             /var/tmp//ccQT23cT.o
_ZNSs4_Rep20_S_empty_rep_storageE   /var/tmp//ccQT23cT.o
_ZNKSs7compareEPKc                  /var/tmp//ccQT23cT.o
_ZNSo5flushEv                       /var/tmp//ccQT23cT.o
_ZSt4cout                           /var/tmp//ccQT23cT.o
_ZNSt9basic_iosIcSt11char_traitsIcEE5clearESt12_Ios_Iostate /var/tmp//ccQT23cT.o
_ZNSs4_Rep10_M_destroyERKSaIcE      /var/tmp//ccQT23cT.o
_ZNSt8ios_base4InitD1Ev             /var/tmp//ccQT23cT.o
_ZNSt8ios_base4InitC1Ev             /var/tmp//ccQT23cT.o
__gxx_personality_v0                /var/tmp//ccQT23cT.o
_ZNSs6assignEPKcj                   /var/tmp//ccQT23cT.o
_ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc /var/tmp//ccQT23cT.o
_ZSt16__ostream_insertIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_PKS3_i /var/tmp//ccQT23cT.o
_ZNSi7getlineEPcic                  /var/tmp//ccQT23cT.o
_ZSt3cin                            /var/tmp//ccQT23cT.o
_ZSt4endlIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_ /var/tmp//ccQT23cT.o
ld: fatal: symbol referencing errors. No output written to mybash
*** Error code 1
make: Fatal error: Command failed for target `mybash'
p1%

mybash.cc mybash.cc

#include <iostream> 
#include <stdio.h>
#include <stdlib.h>
#include <strings.h>
#include "parser.h"

using namespace std;
// an integer used for maximum values of command line arguments
static const int MAX = 128;

int main(int argc, char *argv[])
{
    //do this infinitely or until exit is entered
    while (true) {

        // display the current working directory and catch the value in holder because getcwd() doesnt work
        char holder[MAX];
        cout << getcwd(holder, MAX) << "> ";
        // get the commands from the user
        char commands[MAX];
        cin.getline(commands, 128);

        // create a CommandData object for use in ParseCommandLine
        struct CommandData parsedCommands;
        int catcher;

        // catch the return and fill data from ParseCommandLine by input from commands
        catcher = ParseCommandLine(commands, &parsedCommands);

        // if ParseCommandLine returns an error, stop and ask for new input
        if (catcher == 0) { cout << "Parsing Error, re-enter command" << endl << endl; }

        // if ParseCommandLine finishes correctly
        else {
            // string used to compare and display char[] easily
            string printIt;

            // display statements to describe the command input
            cout << endl << "Number of simple commands : " << parsedCommands.numcommands << endl;

            // if there are multiple commands, display all of them
            for (int i = 0; i < parsedCommands.numcommands; i++) {
                printIt = parsedCommands.TheCommands[i].command;
                cout << "command " << (i+1) << "   : " << printIt << endl;

                // if there are args display all of them
                for (int j = 0; j < parsedCommands.TheCommands[i].numargs; j++) {
                    printIt = parsedCommands.TheCommands[i].args[j];
                    cout << "arg[" << j << "]      : " << printIt << endl;
                }
            }

            // display the infile if there is one, otherwise NULL
            printIt = parsedCommands.infile;
            if (parsedCommands.infile) { cout << "Input file  : " << printIt << endl; }
            else { cout << "Input file  : NULL" << endl; }

            // display the outfile if there is one, otherwise NULL
            printIt = parsedCommands.outfile;
            if (parsedCommands.outfile) { cout << "Output file : " << printIt << endl; }
            else { cout << "Output file : NULL" << endl; }

            // display whether or not the command is to run in the foreground or background
            if (parsedCommands.background == 0) { cout << "Background option : OFF" << endl; }
            else { cout << "Background option : ON" << endl; }

            // the only current built in command is exit, so if exit, display yes and exit, otherwise display no
            printIt = parsedCommands.TheCommands[0].command;
            if (printIt == "exit") {
                cout << "Built-in command  : YES" << endl << endl;
                return 0;
            }
            else { cout << "Built-in command  : NO" << endl; }
        }

    }

  exit(0);
}

parser.h parser.h

#define COMMAND 1
#define ARG 2
#define INFILE 3
#define OUTFILE 4
#define UNDEF 5

struct Command {
  char *command;
  char *args[11];
  int numargs;
};

struct CommandData {
  struct Command TheCommands[20];  /* the commands to be
          executed.  TheCommands[0] is the first command
          to be executed.  Its output is piped to
          TheCommands[1], etc. */
  int numcommands; /* the number of commands in the above array */
  char *infile;   /* the file for input redirection, NULL if none */
  char *outfile;  /* the file for output redirection, NULL if none */
  int  background;  /* 0 if process is to run in foreground, 1 if in background */
};


extern int ParseCommandLine(char *, struct CommandData *);

parser.cc parser.cc

int ParseCommandLine(char *line, struct CommandData *data)
{
    int i, j;
    char token[256];
    int inaword;
    int state;

    i=0;
    j=0;
    inaword = 0;
    state = COMMAND;
    data->numcommands = 0;
    data->TheCommands[0].command=NULL;
    data->infile = data->outfile = NULL;
    data->background = 0;

    while (line[i] != '\0' && line[i] != '\n') {
        if (IsAlphaNum(line[i])) {
            if (inaword) {
            token[j++]=line[i];
            }
            else { /* starting a new word */
            j = 0;
                token[j++] = line[i];
                inaword = 1;
            }
        }
        else {  /* not an alphanumeric character */
            if (inaword) { /* we have found the end of a token */
            token[j]='\0';
                inaword = 0;
                if (CopyWord(token,data,&state)==0)
                 return 0;
         }

            switch (line[i]) {
                case ' ': 
                    break;
            case '>': 
                    if (state == OUTFILE || state == INFILE || state == COMMAND) {
                        fprintf(stderr, "Error, bad syntax on the command line\n");
                        return 0;
                }
                    state = OUTFILE;
                break;
                case '<': 
                    if (state == OUTFILE || state == INFILE || state == COMMAND) {
                        fprintf(stderr, "Error, bad syntax on the command line\n");
                        return 0;
                }
                    state = INFILE;
                break;
            case '|':
                  if (state == COMMAND || state == INFILE || state == OUTFILE) {
                        fprintf(stderr, "Error, bad syntax on the command line\n");
                        return 0;
                }
          data->numcommands++;
                  state = COMMAND;
                  data->TheCommands[data->numcommands].command = NULL;
                  data->TheCommands[data->numcommands].numargs = 0;
                  break;

                case '&': 
                    if (state == OUTFILE || state == INFILE || state == COMMAND) {
                        fprintf(stderr, "Error, bad syntax on the command line\n");    
                        return 0;
                }
                    data->background = 1;
                    break;
                default : 
                    fprintf(stderr,"Error, invalid character on command line %c\n",line[i]);
                    return 0;
            }; /* end of switch */
        } /* end of else */
        i++;
    } /* end of while loop */
    /* we have gotten to the end of the line, there may still be a
       string that has not been processed */

    if (inaword) {
        token[j]='\0';
        if (CopyWord(token,data,&state)==0) {
            return 0;
    }
    }

    /* do some final error checking */
    if (state == INFILE && data->infile == NULL) {
        fprintf(stderr,"Error, < but no filename\n");
        return 0;
    }
    if (state == OUTFILE && data->outfile == NULL) {
        fprintf(stderr,"Error, > but no filename\n");
        return 0;
    }
    if (state == COMMAND) {
      fprintf(stderr,"Error, bad syntax on command line\n");
      return 0;
    }

    if (data->TheCommands[0].command == NULL) {
        fprintf(stderr, "Error, no command\n");
        return 0;
    }
    data->numcommands++;
    return 1;
}

As molbdnilo stated, using g++ to compile both fixed my issues. 正如molbdnilo所说,使用g ++编译都解决了我的问题。 However, my class required use of gcc. 但是,我的课要求使用gcc。 To fix this, I changed parser.c to parser.cc and added -lstdc++ to my compiler flags. 为了解决这个问题,我将parser.c更改为parser.cc,并在编译器标志中添加了-lstdc ++。 This allowed me to use gcc on both and still have it compile and run without errors. 这使我可以在两者上使用gcc,并且仍然可以对其进行编译和运行而不会出错。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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