2013-02-25 12 views
6

To jest moja implementacja tablicy kołowej do tej pory. Ma on przechowywać ostatnie 5 wprowadzonych komend, wprowadzając szóste polecenie w miejsce piątego i odrzucając 1. Do tej pory udało mi się zapisać 5 poleceń i je wydrukować. Na szóstym poleceniu zauważyłem, że jest ono na 2. pozycji (k=1) z historyArray, ale podczas debugowania k było równe 0, które przynajmniej wypchnęłoby ostatnie polecenie na górze. Jeśli znowu umieścisz mnie na dobrej drodze, byłbym wdzięczny. Oto część kodu.Implementacja tablicy kołowej

#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); 
} 

Po sugestii (jeszcze niekompletna):

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

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

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

To może być lub może nie być powiązane, ale czy masz pewność, że twoje bufory są wystarczająco duże dla każdego napotkanego łańcucha? Jeśli nie, to 'gets' i' strcpy' spowodują przepełnienie. Powinieneś zbadać "fgets" i "strncpy" jako "bezpieczne" alternatywy. –

+2

Jestem także sceptyczny co do 'if (elementCounter <= 5)'; dlaczego tego potrzebujesz? –

+0

@OliCharlesworth Masz rację. Planuję je później naprawić. 'If ​​(elementCounter <= 5)' jest używany do zliczania elementów w tablicy i użyłem go w drukowaniu tablicy w dalszej części kodu. Jest tam, aby nie drukować więcej niż 5 wartości. – serge

Odpowiedz

5

Bugu opisać dzieje się ze względu na linii:

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

co widzę dzieje:

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 zachowuje się tak, jak powinien, o ile widzę. Jednak, gdy elementCounter jest 5, k = 1.

EDYCJA: Problem, który widzę jest to, że ostatnie polecenie jest dodawany na pozycji k, a nie pozycji 0, które na podstawie Twojej implementacji jest najświeższe wprowadzone polecenie (na podstawie różnych klauzul if, takich jak ten, który przetwarza polecenia "exit" i "history"). Wypróbuj ten zestaw poleceń, korzystając z aktualnego algorytmu. Spodziewam się, że zawartość listy [komenda] kolumny są co zobaczysz ...

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] 

Co chcesz zrobić, to elementy kopiowania 0-3, i przenieść je do elementów 1-4 . Następnie wstaw nowe polecenie w pozycji 0 w historyArray. Zatem historia powinna wyglądać następująco po skorygowaniu algorytmu odpowiednio:

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

Mam opublikowany pełny kod, dzięki czemu można uzyskać lepszy widok na to, co się dzieje. – serge

+0

Dziękuję, to bardzo pomaga! –

+0

Zaktualizowany o informacje w oparciu o zaktualizowany kod ... –

1

To próbowałem i wydaje się działać zgodnie z oczekiwaniami:

   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);     
      } 

to, w zasadzie, sprawdza czy elementCounter staje 6 (co oznacza, że ​​wprowadzono szóste polecenie). Jeśli tak, ustawia k=5, tak aby polecenie zostało wprowadzone w ostatniej pozycji tablicy, a następnie przesunąć pierwsze 4 wartości w górę o jedną pozycję, pozostawiając pusty indeks 4. Ostatni krok wypełnia pozycję poleceniem. To nie jest najbardziej elegancki kawałek kodu, ale wydaje się, że to wystarczy.