You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C语言十六进制查看器代码编译失败,请求技术协助

编译Curses十六进制查看器时出现未定义引用错误

我正在完成作业任务,需要编写具备行显示、编辑、字符映射功能的十六进制查看器并扩展更多特性。老师提供了一段带西班牙语注释的示例代码,但编译失败,错误提示大量Curses相关函数未定义。

老师提供的示例代码

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <ctype.h>
#include <string.h>
#include <curses.h>
#include <sys/stat.h>
#include <sys/mman.h>

/* Variable global para mejor legibilidad */
int fd; // Archivo a leer


char *hazLinea(char *base, int dir) {
    char linea[100]; // La linea es mas pequeña
    int o=0;
    // Muestra 16 caracteres por cada linea
    o += sprintf(linea,"%08x ",dir); // offset en hexadecimal
    for(int i=0; i < 4; i++) {
        unsigned char a,b,c,d;
        a = base[dir+4*i+0];
        b = base[dir+4*i+1];
        c = base[dir+4*i+2];
        d = base[dir+4*i+3];
        o += sprintf(&linea[o],"%02x %02x %02x %02x ", a, b, c, d);
    }
    for(int i=0; i < 16; i++) {
        if (isprint(base[dir+i])) {
            o += sprintf(&linea[o],"%c",base[dir+i]);
        }
        else {
            o += sprintf(&linea[o],".");
        }
    }
    sprintf(&linea[o],"\n");

    return(strdup(linea));
}

char *mapFile(char *filePath) {
    /* Abre archivo */
    fd = open(filePath, O_RDONLY);
    if (fd == -1) {
        perror("Error abriendo el archivo");
        return(NULL);
    }

    /* Mapea archivo */
    struct stat st;
    fstat(fd,&st);
    long fs = st.st_size;

    char *map = mmap(0, fs, PROT_READ, MAP_SHARED, fd, 0);
    if (map == MAP_FAILED) {
        close(fd);
        perror("Error mapeando el archivo");
        return(NULL);
    }

  return map;
}

int leeChar() {
  int chars[5];
  int ch,i=0;
  nodelay(stdscr, TRUE);
  while((ch = getch()) == ERR); /* Espera activa */
  ungetch(ch);
  while((ch = getch()) != ERR) {
    chars[i++]=ch;
  }
  /* convierte a numero con todo lo leido */
  int res=0;
  for(int j=0;j<i;j++) {
    res <<=8;
    res |= chars[j];
  }
  return res;
}


int edita(char *filename) {
    
    /* Limpia pantalla */
    clear();

    /* Lee archivo */
    char *map = mapFile(filename);
    if (map == NULL) {
      exit(EXIT_FAILURE);
      }
    
    for(int i= 0; i<25; i++) {
        // Haz linea, base y offset
        char *l = hazLinea(map,i*16);
        move(i,0);
        addstr(l);
    }
    refresh();

    int c = getch();
    
    while (c != 26) {
        switch (c) {
            case KEY_LEFT:
                break;
        }
        c = getch();
    }

    if (munmap(map, fd) == -1) {
      perror("Error al desmapear");
    }
    close(fd);
    
   return 0;

}

int main(int argc, char const *argv[])
{
    initscr();
    raw(); 
    keypad(stdscr, TRUE);   /* Para obtener F1,F2,.. */
    noecho();

    /* El archivo se da como parametro */
    if (argc != 2) {
        printf("Se usa %s <archivo> \n", argv[0]);
        return(-1);
    }

    edita((char *)argv[1]);

    endwin();
    
    return 0;
}

尝试的编译命令

gcc -o hex hex.c 
gcc -o hex hex.c -lrt

编译错误信息

$ gcc -o h hex.c 
/usr/bin/ld: /tmp/ccrFjiTL.o: en la función `leeChar':
hex.c:(.text+0x36a): referencia a `stdscr' sin definir
/usr/bin/ld: hex.c:(.text+0x377): referencia a `nodelay' sin definir
/usr/bin/ld: hex.c:(.text+0x37f): referencia a `stdscr' sin definir
/usr/bin/ld: hex.c:(.text+0x387): referencia a `wgetch' sin definir
/usr/bin/ld: hex.c:(.text+0x39a): referencia a `ungetch' sin definir
/usr/bin/ld: hex.c:(.text+0x3b5): referencia a `stdscr' sin definir
/usr/bin/ld: hex.c:(.text+0x3bd): referencia a `wgetch' sin definir
/usr/bin/ld: /tmp/ccrFjiTL.o: en la función `edita':
hex.c:(.text+0x422): referencia a `stdscr' sin definir
/usr/bin/ld: hex.c:(.text+0x42a): referencia a `wclear' sin definir
/usr/bin/ld: hex.c:(.text+0x475): referencia a `stdscr' sin definir
/usr/bin/ld: hex.c:(.text+0x487): referencia a `wmove' sin definir
/usr/bin/ld: hex.c:(.text+0x48e): referencia a `stdscr' sin definir
/usr/bin/ld: hex.c:(.text+0x4a2): referencia a `waddnstr' sin definir
/usr/bin/ld: hex.c:(.text+0x4b3): referencia a `stdscr' sin definir
/usr/bin/ld: hex.c:(.text+0x4bb): referencia a `wrefresh' sin definir
/usr/bin/ld: hex.c:(.text+0x4c2): referencia a `stdscr' sin definir
/usr/bin/ld: hex.c:(.text+0x4ca): referencia a `wgetch' sin definir
/usr/bin/ld: hex.c:(.text+0x4dd): referencia a `stdscr' sin definir
/usr/bin/ld: hex.c:(.text+0x4e5): referencia a `wgetch' sin definir
/usr/bin/ld: /tmp/ccrFjiTL.o: en la función `main':
hex.c:(.text+0x543): referencia a `initscr' sin definir
/usr/bin/ld: hex.c:(.text+0x548): referencia a `raw' sin definir
/usr/bin/ld: hex.c:(.text+0x54f): referencia a `stdscr' sin definir
/usr/bin/ld: hex.c:(.text+0x55c): referencia a `keypad' sin definir
/usr/bin/ld: hex.c:(.text+0x561): referencia a `noecho' sin definir
/usr/bin/ld: hex.c:(.text+0x5a1): referencia a `endwin' sin definir
collect2: error: ld returned 1 exit status

解决方法

1. 问题根源

错误提示的"未定义引用"全部来自ncurses库的函数(如initscr、getch、stdscr等),你之前用的-lrt是链接实时库,和ncurses无关,编译时没有正确链接ncurses库导致这些函数找不到。

2. 安装ncurses开发库

首先确保系统上安装了ncurses的开发包:

  • Debian/Ubuntu 系列:
    sudo apt install libncurses5-dev libncursesw5-dev
    
  • RHEL/CentOS 系列:
    sudo yum install ncurses-devel
    
  • Arch Linux:
    sudo pacman -S ncurses
    

3. 正确编译命令

编译时添加-lncurses参数链接ncurses库:

gcc -o hex hex.c -lncurses

如果需要支持宽字符,可替换为-lncursesw。

4. 修复代码中的潜在错误

代码中munmap(map, fd)存在逻辑错误:munmap的第二个参数需要是映射的内存大小,不是文件描述符fd。同时需要释放strdup分配的内存避免泄漏,修改后的edita函数:

int edita(char *filename) {
    
    clear();

    char *map = mapFile(filename);
    if (map == NULL) {
      exit(EXIT_FAILURE);
    }

    // 获取文件大小
    struct stat st;
    fstat(fd, &st);
    long fs = st.st_size;
    
    for(int i= 0; i<25; i++) {
        char *l = hazLinea(map,i*16);
        move(i,0);
        addstr(l);
        free(l); // 释放strdup分配的内存
    }
    refresh();

    int c = getch();
    
    while (c != 26) {
        switch (c) {
            case KEY_LEFT:
                break;
        }
        c = getch();
    }

    if (munmap(map, fs) == -1) { // 用文件大小替换fd
      perror("Error al desmapear");
    }
    close(fd);
    
   return 0;
}

内容的提问来源于stack exchange,提问作者Miguel Salazar

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.25 16:32:01