如何用 C 语言编写十六进制查看器?

问题描述 投票:0回答:1

我正在编写作业代码。我们的老师给我们举了这个例子。我们必须编写一个关于十六进制查看器的代码。这个必须写下线条、编辑、映射字符并编辑。

#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

这是我从老师那里得到的源代码。我应该添加更多功能,但我什至无法让原始代码正常工作。你能帮我吗?

谢谢。

Something like this is what the code must show

c linux terminal compiler-errors hex
1个回答
0
投票

具有未定义引用的函数是curses库的一部分,因此将该库添加到编译器命令中。

gcc -o hex hex.c gcc -o hex hex.c -lrt -lcurses
© www.soinside.com 2019 - 2024. All rights reserved.