Strtok возвращает NULL для последнего токена строки - PullRequest
0 голосов
/ 01 марта 2019

Я пишу ассемблерную программу на C, которая берет ассемблерный код (составленной архитектуры) и манипулирует им для создания исполняемой программы.

Строка, которую я пытаюсь проанализировать:

jmp L1

Это код, который я использую:

int line_count = 0;
char line[MAX_LINE_LENGTH];
char original_line[MAX_LINE_LENGTH];
char *first_field;
char label[MAX_LABEL_LENGTH];
char *argument;
int arguments_in_line = 0;
while(fgets(line, MAX_LINE_LENGTH, fp) != NULL) {
    line_count++;
    strcpy(original_line, line);
    first_field = strtok(line, delimit);
    if(is_valid_label(first_field)) { /* first field is label */
        strcpy(label,first_field);
        first_field = strtok(NULL, delimit); 
    }
    if(!is_entry_or_external(first_field)) {
        arguments_in_line = get_num_operands(original_line);
        if(arguments_in_line == UNEXPECTED_ERROR)
            return UNEXPECTED_ERROR;
        else if(arguments_in_line == 0) {
            continue; 
        }
        else if(arguments_in_line == 1) { 
            argument = strtok(NULL, delimit);
            if(is_valid_label_name(argument)) /* SEGFAULT HERE!!! */
                printf("found needed replacement at line %d, replace label: %s", line_count, argument);
        }
    }
}

Итак, во втором или третьем (зависит от ввода, для строки примера это второй) вызов strtok,Аргумент получает значение NULL, и происходит ошибка.Значения перед вызовом strtok:

(gdb) p line
$1 = "jmp L1\000\000\000\000\000\000[q\346\267\000\360... /* more values */

После первого вызова:

(gdb) p line
$2 = "jmp\000L1\000\000\000\000\000\000[q\346\267\000\360... /* more values */

И второй возвращает NULL.

Метод get_num_operands выглядит следующим образом:

int get_num_operands(char *src_line) {
    char line_copy[MAX_LINE_LENGTH];
    char *first_field;
    strcpy(line_copy, src_line);
    first_field = strtok(line_copy, delimit);
    if(is_valid_label(first_field)) /* first field is label */
        first_field = strtok(NULL, delimit); /* make sure first field is a command or instruciton */
    if (first_field == NULL)
        return UNEXPECTED_ERROR;
    else 
        return get_num_arguments_for_command(first_field);
}

Есть идеи относительно того, почему это происходит?

...