2017-12-13 9 views
0

私はクラス用のカスタムシェルを作成しています。私はシェルを動作させましたが、リンクされたリストでどのコマンドがユーザによって呼び出されたかを追跡し、同様の方法でこれらのコマンドを出力することができるようにする必要があります。プログラムはリンクリストをうまく構築しているようですが、history(list)で印刷するとエラーが発生します。いくつかのコマンドが入力されると、ノードのコマンドおよび文字列データ値が変更され始めます。ポインタが指しているアドレスが同じであることを確認するためにチェックしましたが、何らかの形でデータ値が有効になっています。Cリンクリストヘッドポインタがデータ値を変更しています

私は最初は、最終的に変更するコマンドを入力する方法を強調するためにhistoryコマンドの出力ファイルを添付している
#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 
#include <unistd.h> 

struct Node{ 
    char* command; 
    char* string; 
    struct Node *next; 
}; 

struct List{ 
    struct Node* front; 
    struct Node* rear; 
}; 


void shell_loop(void); 
char *read_input(void); 
char **split_input(char *input); 

struct Node* createNode(char* command, char* string); 
struct List* createList(); 
struct List* add_to_end(struct List *Q, char* command, char* string); 
void history(struct List* Q); 



const int TOKEN_BUFSIZE = 64; 
const char* DELIMITER = " \t\r\n\a"; 
//#define EXIT_FAILURE 


int main(int argc, char **argv) 
{ 

    shell_loop(); 
} 


void shell_loop(void) 
{ 
char *input; 
char **arguments; 
char* command; 
char* string; 


struct List* list = createList(); 

    for(int i =0; i < 20; i++) 
    { 

    printf("User> "); 

    input = read_input(); 

    arguments = split_input(input); 

    command = arguments[0]; 

    string = arguments[1]; 

    list = add_to_end(list, command, string); 

    printf("\n"); 
    history(list); 
    printf("\n"); 

    free(input); 
    free(arguments); 
    } 
} 

char *read_input(void) 
{ 
    char* input; 
    size_t bufsize = 1000; 
    getline(&input, &bufsize, stdin); 

    return input; 
} 

char **split_input(char *input) 
{ 
    int size_of_buffer = TOKEN_BUFSIZE, position = 0; 
    char **tokens = malloc(size_of_buffer * sizeof(char*)); 
    char *token; 

    if(!tokens) 
    { 
     fprintf(stderr, "shell: allocation error\n"); 
     exit(1); // fix later 
    } 

    token = strtok(input, DELIMITER); 
    while (token != NULL) 
    { 
     tokens[position] = token; 
     position ++; 

    if(position >= size_of_buffer) 
    { 
     size_of_buffer += TOKEN_BUFSIZE; 
     tokens = realloc(tokens, size_of_buffer * sizeof(char*)); 

     if(!tokens) 
     { 
      fprintf(stderr, "shell: allocation error \n"); 
      exit(EXIT_FAILURE); // fix later 
     } 
    } 

    token = strtok(NULL, DELIMITER); 
} 

    tokens[position] = NULL; 
    return tokens; 
} 


struct Node* createNode(char* c, char* s) 
{ 
struct Node* temp = (struct Node*)malloc(sizeof(struct Node)); 
temp->command = c; 
temp->string = s; 
temp->next = NULL; 
return temp; 
} 

struct List* createList() 
{ 
struct List* Q = (struct List*)malloc(sizeof(struct List)); 
Q->front = NULL; 
Q->rear = NULL; 
return Q; 
} 

struct List* add_to_end(struct List *Q, char* c, char* s) 
{ 
    struct Node* temp = createNode(c, s); 

    if(Q->front == NULL) 
    { 
    Q->front = temp; 
    Q->rear = temp; 
    temp = NULL; 
    return Q; 
    } 

    Q->rear->next = temp; 
    Q->rear = temp; 
    temp = NULL; 
    return Q; 
} 


void history(struct List* Q) 
{ 
struct Node* current; 
if (Q->front == NULL) 
{ 
    printf("Command List is empty!\n"); 
    return; 
} 

current = Q->front; 

while(current !=NULL) 
{ 
    printf("Command: %s\nString: %s\n", current->command, current->string); 
    current = current->next; 
} 

} 

output

+2

テキストの画像を投稿しないでください。テキストを投稿する。 –

答えて

1

temp->string = strdup(s)をしたいと思いますあなたはちょうど周りにデータをスタックするポインタをシャッフルしている、あなたは実際の文字列をコピーする必要があります

command = strdup(arguments[0]); 

    string = strdup(arguments[1]); 
+0

これはほんの1つの問題ですが、もう1つの問題はPaul Ogilvieの答えです。 –

+0

これは私が解決しようとしていた主な問題になった。 – D7777777

+0

注 - あなたのリストからノードを解放するときには、これらの2つのフィールドを解放する必要があります。そうしないと、漏れてしまいます。ところで、Linux上でvalgrindを見つけ、漏れを追跡する方法として学ぶ場合 – pm100

0

を、私はあなたがcreateNode(...)代わりのtemp->string = s

1

getlineへのお電話は間違っています。

*lineptrがNULLに設定されていると*nは、呼び出しの前に0に設定され、その後 getlineの(場合は)ラインを格納するためのバッファを割り当てます。このバッファ はユーザプログラムによって解放されるべきです。 ···あるいは、getline()を呼び出す前に、*lineptrは、getlineが前提のmalloc(3)-allocatedバッファに*n 1000とinputが初期化されていない(どこのポイント)である

ので、サイズが*nバイト ポインタを含むことができ利用可能な1000文字のバッファです...そうではありません。

あなたの呼び出しは次のようになります。

char *read_input(void) 
{ 
    char* input= 0; 
    size_t bufsize = 0; 
    getline(&input, &bufsize, stdin); 

    return input; 
} 

は、あなたのプログラムの他の問題のためのコメントや他のソリューションを参照してください。

+0

これはほんの1つの問題です。もう1つの問題はpmの答えで解決されています。 –

+0

@MichaelWalz、実際には、多くの問題があります。 –

+0

多分もっと問題があります、私は詳細にチェックしませんでした。 –

関連する問題