문제

나는 나만의 쉘을 만드는 방법에 대한 튜토리얼을 따르고 있지만 며칠 동안 막혔습니다.

두가지:

  1. 이 코드를 컴파일하고 실행하면 무작위로 분할 오류가 발생하며 그 이유를 알 수 없습니다.
  2. if 문 `if (ferror != 0)`은 항상 참인 것 같습니다.왜 그런지 이해하지 못하기 때문에 이상합니다. fgets() 에서 실패하고있다 기본() 기능.

이러한 주제(또는 이 셸 생성에 대한 다른 주제)에 대한 정보를 주시면 감사하겠습니다.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>

#define MAXSIZE 512

int parseCmd(char *cmd, char *args[])
{
    printf("LOGGER: parseCmd(cmd=%s, args=%p)\n", cmd, args);

    char cmdDelims[] = {' ','>'};

    char *cmdReader;
    cmdReader = strtok(cmd, cmdDelims);

    int i = 0;
    while (cmdReader != NULL)
    {       
        args[i] = strdup(cmdReader);

        printf("LOGGER: args[%d]=%s\n", i, args[i]);

        cmdReader = strtok(NULL, cmdDelims);
        i++;
    }
    return 0;
}

void printToLine(char *args[])
{
    int length;
    length = sizeof(args) / sizeof(char);

    int i = 0;
    while (i < length)
    {
        printf("%s\n", args[i]);
        i++;
    }
}

int main(int argc, char *argv[]) 
{   
    char *in;
    in = malloc(MAXSIZE);

    char *args[15];
    char *cmd = NULL;

    int errorBit = 0;
    int terminationBit = 1;
    char error_message[30] = "An error has occurred\n";

    char inDelims[] = "\n";

    while (terminationBit)
    {
        printf("mysh>");

        // get input from command line
        fgets(in, MAXSIZE, stdin);
        if (ferror != 0)
        {
            perror(error_message);
        }

        // get pointer to command line input w/o the newline
        cmd = strtok(in, inDelims);

        // parse the command into separate arguments
        errorBit = parseCmd(cmd, args);
        if (errorBit)
        {
            perror(error_message);
            exit(1);
        }

        printToLine(args);

        // check if the user wants to exit the shell
        if (strcmp(*args, "exit") == 0)
        {
            terminationBit = 0;
        }
    }
    return 0;
}

다음은 몇 가지 출력입니다.

**[ray@12] (6)$ mysh**
mysh>1 2 3
An error has occurred
: Success
LOGGER: parseCmd(cmd=1 2 3, args=0x7fff4a50b080)
LOGGER: args[0]=1
LOGGER: args[1]=2
LOGGER: args[2]=3
1
2
3
Segmentation fault (core dumped)
**[ray@12] (7)$ mysh**
mysh>1 2 3 4 5 6 7 8 9 10
An error has occurred
: Success
LOGGER: parseCmd(cmd=1 2 3 4 5 6 7 8 9 10, args=0x7fffba053d70)
LOGGER: args[0]=1
LOGGER: args[1]=2
LOGGER: args[2]=3
LOGGER: args[3]=4
LOGGER: args[4]=5
LOGGER: args[5]=6
LOGGER: args[6]=7
LOGGER: args[7]=8
LOGGER: args[8]=9
LOGGER: args[9]=10
1
2
3
4
5
6
7
8
mysh>1 2 3
An error has occurred
: Success
LOGGER: parseCmd(cmd=1 2 3, args=0x7fffba053d70)
LOGGER: args[0]=1
LOGGER: args[1]=2
LOGGER: args[2]=3
1
2
3
4
5
6
7
8
도움이 되었습니까?

해결책

에 대한 ferror 오류가 발생했습니다. 테스트해야 합니다. ferror(stdin), 아니다 ferror.후자는 함수 주소이며 결코 0이 될 수 없습니다.

if (ferror(stdin) != 0)
{
    perror(error_message);
}

적어도 일부 세그폴트의 경우 생각한 대로 작동하지 않습니다.

length = sizeof(args) / sizeof(char);

이것은 당신에게 말할 것입니다 포인터를 저장하는 데 사용되는 바이트 수, 이는 4 또는 8입니다. ~ 아니다 인수의 수.

따라서 4개(또는 8개)의 인수가 있는 경우 나타나다 일하다.더 많은 것이 있으면 일부 인수를 무시하는 것처럼 보입니다.그리고 그보다 적은 인수가 있으면 Void 전체에서 누락된 인수를 가져와 (거의 확실한) 분할 오류가 발생합니다.

계산을 하셔야 합니다 length 독립적으로 전달하거나 터미네이터를 저장하십시오. args, 예를 들어, 찾은 마지막 유효한 인수 뒤에 NULL 인수를 추가합니다.

        cmdReader = strtok(NULL, cmdDelims);
        i++;
    }
    args[i] = NULL;
    return 0;
}

void printToLine(char *args[])
{
    int i = 0;
    while (args[i])
    {
        printf("%s\n", args[i]);
        i++;
    }
}
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top