2013-02-25 11 views
6

Questa è la mia implementazione di un array circolare finora. Si suppone di memorizzare gli ultimi 5 comandi immessi, inserendo il 6 ° comando al posto del 5 ° e scartando il 1 °. Quello che sono riuscito a fare finora è quello di poter memorizzare i 5 comandi e stamparli. Al 6 ° comando, ho notato che si trova nella 2a posizione (k=1) di historyArray, ma quando si eseguiva il debug, era uguale a 0 che almeno avrebbe spinto l'ultimo comando in alto. Se riesci a rimettermi nella giusta direzione, lo apprezzerei. Ecco parte del codice.implementazione array circolare

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

int main (int argc, char *argv[]) 
{ 
    int i=0; 
    int j=0; 
    int k=0; 
    int tempIndex = 0; 
    int elementCounter = 0; 

    char inputString[100]; 
    char *result=NULL; 
    char delims[] = " "; 
    char historyArray[5][20] = {0}; 
    char tokenArray[20][20] ; 
    char hCommand[1][20]; 

    do 
    { 
     j = 0; 

     printf("hshell>"); 
     gets(inputString); 

     //skip writing "history" in historyArray 
     if (strcmp(inputString,"history")!= 0) 
     { 
      strcpy (historyArray[k], inputString); 
     } 

     k = (k+1) % 5; 
     if (elementCounter <= 5) 
      elementCounter++; 

     // Break the string into parts 
     result = strtok(inputString, delims); 

     while (result!=NULL) 
     { 
      strcpy(tokenArray[j], result); 
      j++; 
      result= strtok(NULL, delims);     
     } 

     if (strcmp(tokenArray[0], "exit") == 0) 
      return 0; 

     if (strcmp(tokenArray[0], "history") == 0) 
     { 
      if (j>1) 
      { 
       tempIndex = atoi(tokenArray[j]); 
       puts(tempIndex); 
      } 
      else 
      { 
       for (i=0; i<elementCounter-1;i++) 
        printf("%i. %s\n", i+1, historyArray[i]); 
      } 
     } 
     else 
     { 
      printf("Command not found\n"); 
     } 
    } while (1); 
} 

Dopo suggerimenti (ancora incompleto):

  j = 0; 
     //elementCounter = 0; 
     printf("327>"); 
     gets(inputString); 

     strcpy (historyArray[k], inputString); 
     k = (k+1) % 5; 

     if (elementCounter <= 5) 
     {   
      elementCounter++;     
     } 
+0

Questo può o non può essere correlato, ma sei sicuro che i tuoi buffer sono abbastanza grandi per qualsiasi stringa che incontrerai? In caso contrario, quindi 'gets' e' strcpy' porteranno a tracimare. Dovresti studiare 'fgets' e' strncpy' come alternative "sicure". –

+2

Inoltre, sono scettico riguardo a 'if (elementCounter <= 5)'; perché ne hai bisogno? –

+0

@OliCharlesworth Hai ragione. Ho intenzione di aggiustare quelli più tardi. Il 'if (elementCounter <= 5)' è usato per contare gli elementi nella matrice e l'ho usato nell'array stampando ulteriormente il codice. È lì che non stampa più di 5 valori. – serge

risposta

5

Il bug si descrive che sta accadendo a causa delle linee:

k = (k + 1) % 5; 
elementCounter++; 

quello che vedo accadendo:

k initial | calculation | k result | elementCounter 
0   (0 + 1) % 5 1 % 5 = 1 1 
1   (1 + 1) % 5 2 % 5 = 2 2 
... 
4   (4 + 1) % 5 5 % 5 = 0 5 
0   (0 + 1) % 5 1 % 5 = 1 5 

k si sta comportando come dovrebbe, per quanto posso vedere. Tuttavia, quando elementCounter è 5, k = 1.

MODIFICA: Il problema che vedo è che l'ultimo comando è stato aggiunto alla posizione k, non alla posizione 0, che in base all'implementazione è il comando più recente inserito (in base alle varie clausole if, come quella che elabora i comandi "exit" e "history"). Prova questo insieme di comandi, usando il tuo attuale algoritmo. Mi aspetto che il contenuto della colonna [Elenco comandi] sono ciò che vedrete ...

Command # | Command Text | [Command List] 
0   (null)   [] 
1   Login   [Login] 
2   History  [Login,History] 
3   Skynet   [Login,History,Skynet] 
4   ps -al   [Login,History,Skynet,ps -al] 
5   Skynet   [Login,History,Skynet,ps -al,Skynet] 
6   Exit   [Exit,History,Skynet,ps -al,Skynet] 

ciò che si vorrebbe fare, è elementi di copia 0-3, e spostarli elementi 1-4 . Quindi, inserire il nuovo comando nella posizione 0 nel historyArray. Così, la vostra storia dovrebbe essere così dopo aver regolato l'algoritmo in modo appropriato:

Command # | Command Text | [Command List] 
0   (null)   [] 
1   Login   [Login] 
2   History  [History,Login] 
3   Skynet   [Skynet,History,Login] 
4   ps -al   [ps -al,Skynet,History,Login] 
5   Skynet   [Skynet,ps -al,Skynet,History,Login] 
6   Exit   [Exit,Skynet,ps -al,Skynet,History] 
+1

Ho pubblicato il codice completo in modo da avere una visione migliore di ciò che sta accadendo. – serge

+0

Grazie, questo aiuta molto! –

+0

Aggiornato con informazioni basate sul codice aggiornato ... –

1

Questo è ho provato e sembra funzionare come previsto:

   j = 0; 
      //elementCounter = 0; 
      printf("hshell>"); 
      gets(inputString); 

      strcpy (historyArray[k], inputString); 
      k = (k+1) % 5; 

      if (elementCounter <= 5) 
      {   
       elementCounter++;     
      } 

      if (elementCounter ==6) 
      { 
       k = 5; 
       for (i=0; i<5; i++) 
       { 
        strcpy(historyArray[i], historyArray[i+1]); 
       } 
       strcpy (historyArray[4], inputString);     
      } 

Questo, in sostanza, controlla se il elementCounter diventa 6 (significa che è stato inserito un 6 ° comando). In tal caso, imposta k=5 in modo che il comando venga inserito nell'ultima posizione dell'array, quindi sposta i primi 4 valori su una posizione lasciando vuoto l'indice 4. Il passo finale riempie la posizione con il comando. Non è il pezzo di codice più elegante ma sembra fare il trucco.

Problemi correlati