Пунктуация, приводящая к ошибкам при чтении строки с пробелами с использованием sscanf в C - PullRequest
2 голосов
/ 14 января 2012

Обновление : Правильная инициализация строки с char string[sizeof buffer - 1] решила проблему сбоев, но мне все еще интересно, что с этим связано с более чем одним знаком препинания!

Я пытаюсь прочитать строку из файла в виде «некоторый текст». Использование sscanf с шаблоном \"%[^\"]\" до сих пор прекрасно для меня работало, но как только я начал добавлять пунктуацию в строку, программа начала падать.

Кажется, что ошибка возникает, только если используется более чем один знак пунктуации, независимо от того, какой это знак пунктуации или положение знака. Это также происходит независимо от положения строк с пунктуацией в файле (т. Е. Даже если в последней строке нет знаков пунктуации, ошибка все равно возникает).

В любом случае, ниже приведен код, который у меня есть:

char* func(char* f_name);
    FILE* file = get_file(f_name,"r"); // a short function I wrote to get the
                                       // file pointer from the current
                                       // directory. The error is almost
                                       // certainly not here.
    if (file == 0) {
        print("Unable to load file\nExiting...");
        exit(-1);
    }

    char* pattern = "\"%[^\"]\"";
    int read_args = -1;
    char* string; //  string size is unknown until read
    char buffer[1200]; // i expect very long line of data in the file

    while ( fgets( buffer, sizeof(buffer), file ) != NULL ) {
        printf("found line: %s\n",buffer);
        read_args = sscanf(buffer, pattern, string);
        printf("num args: %d\n",read_args);
        printf("read value: %s\n", string);
    }

    fclose(file);
    return string;
}

Ниже приведены некоторые данные, которые я попробовал. Там, где отмечено «неуспешно», программа компилируется, запускает все и вылетает непосредственно перед выходом.

"test test test" // successful
"test, test test" // successful
"test test; test" // successful

"test, test, test" // unsuccessful
"test; test. test," // unsuccessful

Я планирую использовать более сложный шаблон, если эта проблема решена, и до того, как произошла эта ошибка, я успешно считывал данные с шаблоном %d \"%[^\"]\" \"%[^\"]\". Заранее спасибо за любые ответы.

1 Ответ

3 голосов
/ 14 января 2012

Ваш код вызывает неопределенное поведение, так как вы сканируете в случайную память.

Переменная string никогда не инициализируется, поэтому назначение строки, записанной sscanf(), не определено.

Вам нужно, например,

char string[sizeof buffer - 1];

Тот факт, что не всегда происходит сбой, является просто удачей, код постоянно вызывает неопределенное поведение. Возможно, из-за знаков препинания, согласно вашим примерам, отсканированный текст был длиннее и, следовательно, перезаписывал больше памяти, в конечном итоге вызывая сбой, когда он сталкивался с чем-то достаточно важным.

...