2016-04-04 13 views
0

Ich entwickle eine History-Funktion für eine benutzerdefinierte C-Shell für eine Klasse. Ich brauche den Verlauf, um die letzten zwanzig Befehle anzuzeigen, die in der Shell eingegeben wurden. Der Befehlsverlauf wird mit dem folgende Format in einer lokalen Textdatei gespeichert werden:Parsen eines Puffers beeinflusst einen anderen?

0001 <command> 
0002 <command> 
0003 <command> 
... 

Wenn ich versuche, Zeilen aus der History-Datei zu drucken, nur die Zahlen gedruckt werden und nicht den Befehl selbst. Hier ist meine Funktion, um die Geschichte zu drucken:

169 int print_history() 
170 { 
171  int first = (current - 20); 
172  if (first < 1) 
173   first = 1; 
174 
175  char **arg_p; 
176  FILE *fp = fopen("history", "r"); 
177  int count = 0; 
178  char buff[MAX_LENGTH]; 
179  while(fgets(buff, sizeof buff, fp) != NULL) 
180  { 
181   char *temp_buf = buff; 
182   printf("%s\n", temp_buf); // this line prints the entire line, just as I need it 
183   arg_p = parse(buff); 
184   printf("%s\n", temp_buf); // this line prints only the number 
185   int temp = atoi(arg_p[0]); 
186   if(temp >= first && temp <= current) 
187    printf("%s\n", temp_buf); 
188  } 
189  fclose(fp); 
190 } 

Die printf Linien mit den Kommentaren (182 und 184) sind nur für die Fehlerprüfung. Wenn ich buff parse, ändert es irgendwie temp_buf, damit es nicht richtig anzeigt. Die Ausgabe von diesen beiden Linien (für einen einzelnen Zyklus Schleife) sieht wie folgt aus:

0035 exit 

0035 

Hier meine Parse-Funktion ist, dass buff wird geleitet wird:

76 char **parse(char *line) 
77 { 
78  int size = 64; 
79  int position = 0; 
80  char **words = malloc(size * sizeof(char*)); 
81  char *word; 
82  word = strtok(line, DELIM); 
83  while (word != NULL) 
84  { 
85   words[position] = word; 
86   position++; 
87   word = strtok(NULL, DELIM); 
88  } 
89  words[position] = NULL; 
90  return words; 
91 } 

Irgendwelche Ideen auf, warum das Parsen ein Puffer beeinflusst auch einen anderen Puffer? Jede Hilfe wird geschätzt.

Danke!

+0

* "Wenn ich Buffs parse, ändert es irgendwie temp_buf." * Das ist, weil sie der gleiche Puffer sind. 'char * temp_buf = buff;' –

+0

Also bindet 'char * temp_buf = buff' die beiden Puffer zusammen, so dass sie immer gleich sind? Ich nahm an, dass diese Zeile einen zweiten Puffer erstellen würde, der unverändert bleiben würde, wenn der erste Puffer geändert wurde. Ich glaube, ich habe das mit 'strcpy (temp_buf, buff)' behoben. Vielen Dank! – Unrealcow

+0

Es gibt nicht zwei Puffer. Es gibt einen Puffer, auf den zwei Variablen zeigen. Lektion 1 mit Strings. 'A = B' erstellt keine neue Zeichenfolge. Und 'strcpy (temp_buf, buff)' funktioniert nur, wenn Speicher zugewiesen wurde. Wie vorgeschlagen, verwenden Sie 'strdup'. –

Antwort

2

In Ihrer parse() Funktion, Sie speichern das Wort als

words[position] = word; 

Sie sollten jedoch

words[position] = strdup(word); 

beispiels duplizieren Sie die Zeichenfolge tun. Der Inhalt von word aka line aka buff (von Haupt) würde ändern, sobald Sie die nächste Zeile lesen.

+0

Ich habe diese Änderung gemacht und habe keinen Unterschied im Verhalten bemerkt. – Unrealcow

+0

@ Unrealcow, das ist wegen 'strtok' Problem, da es den Inhalt von' temp_buf' ändert, wie von @Leandros vorgeschlagen. – Rohan

2

strtok ist destruktiv.

Diese Funktion ist destruktiv: es schreibt die ‚\ 0‘ Zeichen in den Elemente des Strings str. Insbesondere kann ein String-Literal nicht als erstes Argument von strtok verwendet werden.

Aus der strtok doc here.

+0

Ich habe das nicht bemerkt. Gibt es eine andere Funktion, die Sie vorschlagen würden, um dies zu verhindern? – Unrealcow

+0

'strtok' ist im Allgemeinen keine gute Funktion, es ist nicht threadsicher und destruktiv. Mein Vorschlag ist, Ihnen einen String Tokenizer auf eigene Faust zu schreiben, es ist nicht schwer. Es könnte den ursprünglichen String unberührt lassen und eine Kopie des Tokens erstellen, anstatt einen Teil des ursprünglichen Strings zurückzugeben (wie bei strtok). – Leandros

Verwandte Themen