2014-10-22 3 views
1

У меня есть программа, которая компилируется без предупреждений или ошибок, но попадает в Undefined Reference. Программа состоит из трех файлов. mybash.cc - это файл, который я написал. Два файла парсера были начальным кодом, предоставленным профессором. Программа должна отображать рабочий каталог в командной строке и принимать команду. Команда анализируется путем синтаксического анализа, а затем информация об этом печатается mybash. Все мои ошибки Undefined Reference - это не функции, а беспорядок символов. Я компилирую с помощью «gcc -g -Wall -Werror -O2 -c parser.c», «gcc -g -Wall -Werror -O2 parser.o mybash.cc -o mybash». Я предполагаю, что проблема связана с ошибкой компоновщика, или я не инициализирую/не объявляю что-то правильно. Однако у меня возникли проблемы с поиском проблемы.Нужна помощь в поиске Undefined Symbols

Edit: Вот неопределенные ошибки,

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

#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

#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

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; 
} 
+4

Используйте 'g ++', а не 'gcc', когда вы компилируете и связываете' mybash.cc' – molbdnilo

+1

. Какова фактическая ошибка messge. Эта _mess of characters_ содержит символ C++, который все еще содержит исходное имя символа. Thouroughly проверить для опечаток в вашем коде определения. –

+0

Попробуйте указать символы с подходящим [C++ name demangler] (http://demangler.com/). – Angew

ответ

1

Как заявлено molbdnilo, используя g ++ для компиляции и исправленных моих проблем. Однако для моего класса требуется использование gcc. Чтобы исправить это, я изменил parser.c на parser.cc и добавил -lstdC++ к моим флагам компилятора. Это позволило мне использовать gcc на обоих, и все еще его компилировать и запускать без ошибок.

Смежные вопросы