Ho iniziato su Crea la tua lista e ho riscontrato lo stesso problema. Nessuna delle risposte di cui sopra ha funzionato per me. Dopo una piccola ricerca, ho scoperto che macOs non ha la libreria readline di gnu che fornisce le funzioni readline. Diverse versioni di MacO forniscono emulazione di readline usando una libreria chiamata editline. per cominciare ...
man editline
#include <histedit.h>
Ok, esiste EDITLINE vi dà alcuni le strutture per ingresso di linea e la storia, e funzioni per operare su di essi. Per prima cosa devi istanziare queste strutture. La documentazione per editline non è molto utile perché non contiene alcun esempio. Apple rende disponibile il file di intestazione in modo da aiutare un po '. http://www.opensource.apple.com/source/libedit/libedit-13/src/histedit.h
Sono nuovo di questo ed è stato ancora piuttosto confusionario per me. c'è una versione del codice sorgente per libedit disponibile come pacchetto debian. Fortunatamente qualcuno più saggio di me lo ha già scavato e ha implementato una riga di comando usando lbedit. Il suo codice è qui: https://www.cs.utah.edu/~bigler/code/libedit.html. Ho preso il codice di Mr Bigler e il codice da Crea il tuo elenco e li metto insieme per ottenere questo.
/* repl-macos.c
* Repl code example from builyourownlisp.com
* Modified by NB aug 2017
* Code example for editline from
* www.cs.utah.edu/~bigler/code/libedit.html
*/
#include <stdio.h>
#include <string.h>
#include <histedit.h>
char* prompt(EditLine *e){
return "lispy> ";
}
int main(int argc, char** argv){
EditLine *el; // Line editor state
History *herstory; // the rest is history
// Temp Variables
int count;
const char *usrin;
int keepreading = 1;
HistEvent ev;
// Initialize the editline state
el = el_init(argv[0], stdin, stdout, stderr);
el_set(el, EL_PROMPT, &prompt);
el_set(el, EL_EDITOR, "emacs");
// Initialize history
herstory = history_init();
if(!herstory){
fprintf(stderr, "Couldn't initialize history\n");
return 1;
}
//set history size
history(herstory, &ev, H_SETSIZE, 800);
// Set up the call back functions for history functionality
el_set(el, EL_HIST, history, herstory);
puts("Begin moLisp interpreter");
puts("Type 'exit' at prompt to exit");
while(keepreading){
usrin = el_gets(el, &count);
// add the command to the history, and echo it back to the user
if(count > 0){
history(herstory, &ev, H_ENTER, usrin);
if(strcmp(usrin, "exit\n"))
printf("No, You're a %s", usrin);
else{
puts("bye");
--keepreading;
}
}
}
// Clean up memory
// by freeing the memory pointed to within the structs that
// libedit has created.
history_end(herstory);
el_end(el);
return 0;
}
Avviso: L'istanziazione dei struct che vengono utilizzati avviene al di fuori del ciclo while, e così fanno le funzioni che liberano la memoria tali structs utilizzano. Per questo motivo, ho aggiunto il comando per uscire, altrimenti penso che ci sia una perdita di memoria se l'unico modo per uscire dal ciclo while è interrompere il programma. Per compilare:
gcc repl-macos.c -ledit -Wall -o repl-edit
-ledit è necessaria per collegare esiste EDITLINE
Se ha alcuna rilevanza, sto usando MacOs 10.4.11 ed ecco il mio compilatore, uscita di gcc --version
powerpc-apple-darwin8-gcc-4.0.0 (GCC) 4.0.0 20041026 (Apple Computer, Inc. build 4061)
Ora l'unico problema con questo e il libro lo fa notare, è che il codice C dovrebbe essere portatile e questo non lo è. Il prossimo passo sarebbe aggiungere le direttive del preprocessore in modo che utilizzi readline su linux e editline su macos.
Appena eseguito. Lo apprezzo davvero! Sono un C noob. Grazie :) – yburyug
Simboli indefiniti per architettura x86_64: "_add_history", referenziato da: _main in prompt-OYsOTI.o "_readline", riferito da: _main in pronta-OYsOTI.o ld: simbolo (s) non trovate in x86_64 clang: errore: comando linker non riuscita con codice di uscita 1 (uso -v per vedere invocazione) –
@Vinit: hai aggiunto "libedit.dylib" alle librerie di link del tuo progetto? (Questo è ciò che l'opzione '-ledit' è nella domanda.) –