2017-02-14 3 views
0

"ls | wc"のような入力を分割し、argv [0] = ls、argvのように表示することです。1 = wc これはMacBookで正しく機能しますが、Linuxマシンでは失敗します。セグメント障害を示します。 朝は慎重にチェックしますが、なぜか分かりません。 誰かが私を助けることができますか? Linuxマシン上セグメント障害が発生するのはなぜですか?

結果は次のとおりです。 enter image description here

#include <stdio.h> 
#include <string.h> 
#include <stdlib.h> 
#define MAX_SUB_COMMANDS 5 
#define MAX_ARGS 10 
struct SubCommand{ 
    char *line; 
    char *argv[MAX_ARGS]; 
}; 
struct Command{ 
    struct SubCommand sub_commands[MAX_SUB_COMMANDS]; 
    int num_sub_commands; 
}; 
void PrintArgs(char** argv){ 
    int i = 0; 
    while (argv[i] != NULL){ 
     printf ("argv[%d] = '%s' \n", i , argv[i]); 
     i++; 
    } 
    return; 
} 

void ReadArgs(char *in, char **argv, int size){ 
    if (size <= 0){ // in case of size is negative or 0// 
     fprintf(stderr,"Please enter a positive size.\n"); 
     return; 
    } 
    if (size == 1){ // if size is 1, directly return// 
     *argv = NULL; 
     return; 
    } 
    char *p; 
    int length = strlen(in); 
    //in[length - 1] = '\0';// 
    int count = 1; //count the number of element, it is 1 since NULL must be included// 
    p = strtok(in, " "); 
    char *buff = strdup(p); 
    count++; 
    *argv = p; 
    argv++; 
    free(buff); 
    if (p == NULL){ 
     *argv = NULL; 
     return; // we need just output one element// 
    } 
    while ((p=strtok(NULL, " "))!= NULL && (count <= size - 1)) { 
      buff = strdup(p); 
      *argv = p; 
      argv++; 
      count++; 
      free(buff); 
    } 
    argv++; 
    *argv = NULL; 
    return; 
} 

int get_args(char *in, char **argv, int max_args){ 
    char *p; 
    int length = strlen(in); 
    in[length - 1] = '\0'; 
    p = strtok(in, "|"); 
    char *buff = strdup(p); 
    *argv = p; 
    argv++; 
    free(buff); 
    if (p == NULL){ 
     return 1; // we need just output one array // 
    } 
    int count = 1; // if p is not null, it means at lease we have one array// 
    while ((p=strtok(NULL, "|"))!= NULL && (count <= max_args - 1)) { 
     buff = strdup(p); 
     *argv = p; 
     argv++; 
     count++; 
     free(buff); 
    } 
    return count; 
} 
void ReadCommand(char *line, struct Command *command){ 
    /*Split the line by "|", and store them in argv*/ 
    int i; 
    char *argv[MAX_SUB_COMMANDS]; 
    int number = get_args(line, argv, MAX_SUB_COMMANDS); 
    /*End of Split procedure*/ 
    /*Stored into sub-command's line*/ 
    if (number > MAX_SUB_COMMANDS){ 
     number = MAX_SUB_COMMANDS; 
    } 
    for (i = 0; i < number; i++){ 
     command->sub_commands[i].line = argv[i]; 
     command->num_sub_commands = i; 
     ReadArgs(command->sub_commands[i].line, command->sub_commands[i].argv, MAX_ARGS); //populate all argv in SubCommand// 
    } 
    return; 
} 
void PrintCommand(struct Command *command){ 
    int i; 
    for (i = 0; i < MAX_SUB_COMMANDS; i++){ 
     PrintArgs(command->sub_commands[i].argv); 
    } 
} 

int main(){ 
    char s[200]; 
    char *argv[10]; 
    int argc; 
    printf("Enter a string: "); 
    fgets(s, sizeof s, stdin); 
    struct Command a; 
    struct Command *command; 
    command = &a; 
    ReadCommand(s, command); 
    PrintCommand(command); 
    return 0; 
} 
+0

私はこれらの演習を 'buff'と理解していません –

+0

テキストの画像を投稿しないでください! – Olaf

答えて

0

なぜあなたはargvargcを使用してみませんか?それはそんなにきれい

#include<stdio.h> 

int main(int argc, char *argv[]){ 
    int i; 
    for(i=0;i<argc;i++){ 
     printf("Argv[%d] = %s\n", i, argv[i]); 
    } 
    return 0; 
} 
+0

私は彼/彼女がコマンドラインから文字列を読みたいと思っています....彼らはまた、argc argvの規則について少し混乱していると思います。 –

+0

@CarefulNow私は彼の質問を本当に理解していないので、簡単にするのに役立ちます。 – Lopan

0
while ((p=strtok(NULL, " "))!= NULL && (count <= size - 1)) {...} 

あなたは本当にstrtokはのドキュメントを検索する必要があります。上記の行は、書き込み可能メモリへの有効なポインタを持つstrtokを以前に呼び出していないので、未定義の動作を引き起こします。

+0

これは9行先 – stark

関連する問題