“对'main'的未定义引用 /tmp/ccTJnyB3.o:在函数”insertBack“中:crawler.c:(.text+0xf3):对”indexPage“的未定义引用 C 爬虫程序

"undefined reference to `main' /tmp/ccTJnyB3.o: In function `insertBack': crawler.c:(.text+0xf3): undefined reference to `indexPage" C Crawler Program

提问人:sallysal 提问时间:5/5/2023 最后编辑:Allan Windsallysal 更新时间:5/6/2023 访问量:46

问:

尝试编译crawler.c文件和indexPage.c文件时,我不断收到这些错误。我将添加所有内容,以便您看到。

[salisn02@diamond code]$ gcc -o crawler -Wall crawler.c
/usr/lib/gcc/x86_64-redhat-linux/8/../../../../lib64/crt1.o: In function `_start':
(.text+0x24): undefined reference to `main'
/tmp/ccTJnyB3.o: In function `insertBack':
crawler.c:(.text+0xf3): undefined reference to `indexPage'
/tmp/ccTJnyB3.o: In function `destroyList':
crawler.c:(.text+0x1a9): undefined reference to `freeTrieMemory'
crawler.c:(.text+0x1dd): undefined reference to `freeTrieMemory'
collect2: error: ld returned 1 exit status
[salisn02@diamond code]$ gcc -o indexPage -Wall indexPage.c
/usr/lib/gcc/x86_64-redhat-linux/8/../../../../lib64/crt1.o: In function `_start':
(.text+0x24): undefined reference to `main'
collect2: error: ld returned 1 exit status
[salisn02@diamond code]$ 

下面是 crawler.c 文件:

#include "crawler.h"
#include "indexPage.h"

int size (struct listNode *pNode)
{
  struct listNode *pCur = pNode;
  int count = 0;
  while(pCur != NULL)
  {
    count++;
    pCur = pCur->next;
  }
  return(count);
}
int contains(const struct listNode *pNode, const char *addr)
{
  if (pNode == NULL)
      return 0;
  else if (strcmp(pNode->addr, addr)==0)
      return 1;
  else
      return (contains(pNode->next, addr));
}

void insertBack(struct listNode *pNode, const char *addr, int *totalTerms)
{

  if (pNode->next == NULL)
  {
    struct listNode *nodeToAdd = (struct listNode*)malloc(sizeof(struct listNode));
    strcpy(nodeToAdd->addr,addr);
    nodeToAdd->next = NULL;
    nodeToAdd->root = indexPage(addr,totalTerms);
    nodeToAdd->score = 0.0000;

    pNode->next = nodeToAdd;
  }
  else
      return (insertBack(pNode->next, addr, totalTerms));
}

void printAddresses(const struct listNode *pNode)
{
  if(pNode == NULL)
    return;
  else
  {
    printf("%s\n",pNode->addr);
    printAddresses(pNode->next);
    return;
  }
}

void destroyList(struct listNode *pNode)
{
  if(pNode->next == NULL)
  {
    freeTrieMemory(pNode->root);
    free(pNode);
    return;
  }
  else
  {
    destroyList(pNode->next);
    freeTrieMemory(pNode->root);
    free(pNode);
    return;
  }
}

int getLink(const char* srcAddr, char* link, const int maxLinkLength){
  const int bufSize = 1000;
  char buffer[bufSize];

  int numLinks = 0;

  FILE *pipe;

  snprintf(buffer, bufSize, "curl -s \"%s\" | python getLinks.py", srcAddr);

  pipe = popen(buffer, "r");
  if(pipe == NULL){
    fprintf(stderr, "ERROR: could not open the pipe for command %s\n",
        buffer);
    return 0;
  }

  fscanf(pipe, "%d\n", &numLinks);

  if(numLinks > 0){
    int linkNum;
    double r = (double)rand() / ((double)RAND_MAX + 1.0);

    for(linkNum=0; linkNum<numLinks; linkNum++){
      fgets(buffer, bufSize, pipe);

      if(r < (linkNum + 1.0) / numLinks){
        break;
      }
    }

    /* copy the address from buffer to link */
    strncpy(link, buffer, maxLinkLength);
    link[maxLinkLength-1] = '\0';

    /* get rid of the newline */
    {
      char* pNewline = strchr(link, '\n');
      if(pNewline != NULL){
        *pNewline = '\0';
      }
    }
  }

  pclose(pipe);

  if(numLinks > 0){
    return 1;
  }
  else{
    return 0;
  }
}
struct listNode *getLast(struct listNode *pNode)
{
  if (pNode->next== NULL)
      return(pNode);
  else
  {
    return(getLast(pNode->next));
  }
}
void printList(const struct listNode *pNode)
{
  if (pNode == NULL)
      return;
  else
  {
    printf("%s\n",pNode->addr);
    printList(pNode->next);
  }
  return;
}
char *getAddrAt(struct listNode *pNode, int index)
{
    struct listNode *pCur = pNode;
    int i =0;

    while(i<index)
    {
      pCur = pCur->next;
      i++;
    }
    return(pCur->addr);

}
void resetScore(struct listNode *pNode)
{
  struct listNode *pCur = pNode;

  while(pCur != NULL)
  {
    pCur->score = 0.0;
    pCur = pCur->next;
  }
}

crawler.h 文件

#ifndef CRAWLER_H_
#define CRAWLER_H_

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

#define MAX_ADDR_LENGTH 1000

struct listNode{
  char addr[MAX_ADDR_LENGTH];
  struct trie *root;
  double score;

  struct listNode *next;
};

int size (struct listNode *pNode);
int contains(const struct listNode *pNode, const char *addr);
void insertBack(struct listNode *pNode, const char *addr, int *totalTerms);
void printAddresses(const struct listNode *pNode);
void destroyList(struct listNode *pNode);
int getLink(const char* srcAddr, char* link, const int maxLinkLength);
void printList(const struct listNode *pNode);
struct listNode *getLast(struct listNode *pNode);
char *getAddrAt(struct listNode *pNode, int index);
void resetScore(struct listNode *pNode);


#endif

index.c 文件:

#include "indexPage.h"

struct trie* indexPage(const char* url, int* pTotalNumTerms)
{
  struct trie* root = createNode();
  char* buffer = (char*)malloc(sizeof(char) * MAX_CHARACTERS);
  if (root == NULL || buffer == NULL)
    return NULL;

  int numOfBytes = getText(url, buffer, MAX_CHARACTERS);
  int isNewWord = 0; //boolean that signifies whether or not the current word has been added/printed
  int startIndex = 0;
  int endIndex = 0;

  printf("%s\n", url);
  int i, j;
  for (i = 0; i < numOfBytes; i++)
  {
    if (!isalpha(buffer[i]) && isNewWord)
    {
      endIndex = i;
      buffer[endIndex] = '\0';

      printf("\t");
      for (j = startIndex; j < endIndex; j++)
        printf("%c", buffer[j]);
      printf("\n");

      addWordOccurrence(root, buffer + startIndex);

      isNewWord = 0;
    }
    else if (isalpha(buffer[i]) && !isNewWord)
    {
      startIndex = i;
      (*pTotalNumTerms)++;
      isNewWord = 1;
    }

    buffer[i] = tolower(buffer[i]); //tolower ignores non-alphabetical characters
  }
  free(buffer);
  root->totalWords=(*pTotalNumTerms);
  return root;
}

int addWordOccurrence(struct trie* root, const char* word)
{
  if (root == NULL)
    return 0;

  int charIndex = *word - 'a';

  if(root->children[charIndex] == NULL)
  {
    root->children[charIndex] = createNode();

    if (root->children[charIndex] == NULL)
      return 0;
    else
    {
      root->children[charIndex]->character = *word;
      if(*(word+1) == '\0')
      {
        root->children[charIndex]->timesVisited++;
        root->children[charIndex]->isEndOfWord=1;

        return 1;
      }
      else
        return addWordOccurrence(root->children[charIndex], word+1);
    }
  }
  else
  {
    if(*(word+1) == '\0')
    {
      root->children[charIndex]->timesVisited++;
      root->children[charIndex]->isEndOfWord=1;

      return 1;
    }
    else
    {
        return addWordOccurrence(root->children[charIndex], word+1);
    }
  }
}

void printTrieContents(const struct trie *root, int level, char* word)
{
  if (root == NULL)
    return;

  if (root->isEndOfWord)
  {
   word[level] = '\0';
   //printf("%s: %d\n", word, root->timesVisited);
  }

  int i;
  for (i = 0; i < ALPHABET_SIZE; i++)
  {
    if (root->children[i] != NULL)
    {
        word[level] = i + 'a';
        printTrieContents(root->children[i], level+1, word);
    }
  }
}

int freeTrieMemory(struct trie* root)
{
  if (root == NULL)
    return 0;

  int i;
  for(i = 0; i < ALPHABET_SIZE; i++)
    if (root->children[i] != NULL)
      freeTrieMemory(root->children[i]);

  free(root);

  return 1;
}

/* You should not need to modify this function */
int getText(const char* srcAddr, char* buffer, const int bufSize){
  FILE *pipe;
  int bytesRead;

  snprintf(buffer, bufSize, "curl -s \"%s\" | python getText.py", srcAddr);

  pipe = popen(buffer, "r");
  if(pipe == NULL){
    fprintf(stderr, "ERROR: could not open the pipe for command %s\n",
     buffer);
    return 0;
  }

  bytesRead = fread(buffer, sizeof(char), bufSize-1, pipe);
  buffer[bytesRead] = '\0';

  pclose(pipe);

  return bytesRead;
}

struct trie* createNode(void) {
  struct trie *newNode = NULL;
  newNode = (struct trie*)malloc(sizeof(struct trie));

  if (newNode != NULL)
  {
    newNode->isEndOfWord = 0; //false
    newNode->timesVisited = 0;
    newNode->character = 0;

    int i;
    for (i = 0; i < ALPHABET_SIZE; i++)
      newNode->children[i] = NULL;
  }

  return newNode;
}

void getWordCount(const struct trie *root, int level, char* word, char *wordToFind, int *occurrence)
{
  if (root == NULL)
    return;

  if (root->isEndOfWord)
  {
   word[level] = '\0';
   if(strcmp(wordToFind,word)==0)
   {
     (*occurrence) = root->timesVisited;
     //printf("strlen of %s is: %d\n",wordToFind,(int)strlen(wordToFind));
     //printf("%s: %d\n", word, root->timesVisited);
   }
  // printf("Word to find is: %s\n",wordToFind);

  }

  int i;
  for (i = 0; i < ALPHABET_SIZE; i++)
  {
    if (root->children[i] != NULL)
    {
        word[level] = i + 'a';
        getWordCount(root->children[i], level+1, word, wordToFind, occurrence);
    }
  }
}

indexPage.h 文件:

#ifndef INDEX_PAGE_H_
#define INDEX_PAGE_H_

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

#define ALPHABET_SIZE 26 //size of alphabet
#define MAX_CHARACTERS 300000 //max amount of characters the program can handle per web page

struct trie {
  char character; //character of a word
  int timesVisited; //how many times a word was visited
  int isEndOfWord; //boolean
  int totalWords;

  struct trie *children[ALPHABET_SIZE];
};

struct trie* indexPage(const char* url, int* pTotalNumTerms);

int addWordOccurrence(struct trie *root, const char* word);

void printTrieContents(const struct trie *root, int level, char* word);

int freeTrieMemory(struct trie *root);

int getText(const char* srcAddr, char* buffer, const int bufSize);

struct trie* createNode(void);

void getWordCount(const struct trie *root, int level, char* word, char *wordToFind, int *occurrence);

#endif

最后是 Makefile:

CC  = gcc
CFLAGS = -g -Wall
OBJS = indexPage.o crawler.o tf_idf.o

all: webSearch
webSearch: webSearch.c $(OBJS)
    $(CC) $(CFLAGS) $(ObJS) $< -o $@ -lm
%.o: %.c $.h
    $(CC) $(CFLAGS) -c $< -o $@
clean:
    rm *.o webSearch

其中 main 函数位于 webSearch.c

}`#include "crawler.c"
#include "indexPage.c"
#include "tf_idf.c"

#define MAX_QUERY_SIZE 100

int main()
{
    char startAddr[MAX_ADDR_LENGTH];
    char destAddr[MAX_ADDR_LENGTH];
    char url[MAX_ADDR_LENGTH];
    char query[MAX_QUERY_SIZE];
    FILE *fp;

    long seed;
    int hopNum, hopLimit, MAX_N;
    int n=0;
    struct listNode *pListStart;

    if(argc != 4)
    {
        printf( "Not enough arguments were passed.\n" );
        return(-1);
    }
    else
    {
        fp=fopen(argv[1],"r");
        MAX_N = atoi(argv[2]);

        seed = atol(argv[3]);

        srand(seed);
    }

    pListStart = malloc(sizeof(struct listNode));
    if(pListStart == NULL)
    {
        fprintf(stderr, "ERROR: could not allocate memory\n");
        return -2;
    }
    else
    {
        pListStart->next = NULL;
        pListStart->root = NULL;
    }


    printf("Indexing...\n");
    while((fscanf(fp,"%s %d",url,&hopLimit) != EOF) && (n <MAX_N))
    {
        strncpy(startAddr,url,MAX_ADDR_LENGTH);
        hopNum = 0;
        while(1)
        {
            if(contains(pListStart->next, startAddr)==0)
            {
                int totalNumTerms = 0;

                insertBack(pListStart, startAddr, &totalNumTerms);
                char word[MAX_CHARACTERS];
                //printf("\"%s\n\n\"",getLast(pListStart)->root->)
                printTrieContents((getLast(pListStart))->root, 0, word);
                //(getLast(pListStart))->root->totalWords=totalNumTerms;
                //printf("Total number of words is: %d\n",totalNumTerms);
                n++;
            }
            hopNum++;
            if((hopNum <= hopLimit) && (n<MAX_N))
            {
                int res = getLink(startAddr, destAddr, MAX_ADDR_LENGTH);

                if(!res)
                {
                    break;
                }
                strncpy(startAddr, destAddr, MAX_ADDR_LENGTH);
            }
            else
            {
                break;
            }
        }
    }
    printf("\nEnter a web query: ");
    while(fgets(query,MAX_QUERY_SIZE,stdin))
    {
        if(query[0] == '\n')
            break;
        query[strlen(query)-1] = '\0';
        //printf("Length of query: %d\n",(int)strlen(query));
        if(validInput(query)==0)
        {
            printf("\nEnter a web query: ");
            continue;
        }
        printf("Query is \"%s\".\n",query);
        score(pListStart,query);

        printf("Web pages:\n");
        topThreeScores(pListStart->next);
        resetScore(pListStart->next);
        printf("\nEnter a web query: ");
    }
    printf("Exiting the program\n");
    fclose(fp);
    destroyList(pListStart);

    return 0;
}

有人请帮忙。

我什至不确定我是否正确编译。这是我第一次制作制作文件以及如何使用它。

c makefile 未定义引用

评论

2赞 Barmar 5/5/2023
您需要一个用于启动程序的函数。没有一个 .c 文件有这个。main()
2赞 Barmar 5/5/2023
为什么 makefile 是相关的?您没有用于编译程序。make
0赞 user253751 5/5/2023
你没有使用 make,而是告诉编译器将 crawler.c 编译成一个完整的程序,这不起作用,因为 crawler.c 没有所有功能。
0赞 sallysal 5/5/2023
有一个主要功能,我刚刚把它添加到帖子中
0赞 Tom Karzes 5/5/2023
问题在于你编译它的方式。有两个阶段:(1)编译和(2)链接。这些可以组合在一起,例如 ,或者您可以单独编译它们(例如 )以生成文件,然后将文件与 链接。由于您遗漏了该标志,因此您告诉尝试链接文件,这当然不起作用,因为您只指定了一个源文件。gcc f1.c f2.c f3.c -o myproggcc -c f1.c.o.ogcc f1.o f2.o f3.o -o myprog-cgcc

答:

0赞 Allan Wind 5/6/2023 #1

错误消息表明您正在尝试构建没有功能的二进制文件。从上下文来看,您似乎想要构建目标文件和二进制文件,因此您错了。crawlercrawler.cmain()crawler.owebSearchMakefile

我还没有测试过这个,但试试这个(确保你按 Tab 键缩进该行):Makefilerm ...

CFLAGS = -g -Wall

all: webSearch

webSearch: private LDLIBS=-lm
webSearch: indexPage.o crawler.o tf_idf.o webSearch.o

clean:
    rm -f *.o webSearch