Что возвращает функция strtok в моем коде?

Я пытаюсь сделать из файла .txt файл .lzw, как уже говорил в этом вопросе. Использую для этого следующий код:

 FILE* compress (char* inputFileName){

char * outputFileName = "";

char * ex = strchr (inputFileName, '.');

printf ("%d", ex - inputFileName + 1);

outputFileName = strtok(inputFileName, ex);

if (strtok (inputFileName, ex) == NULL ){
    printf("%s\n", "NULL Караул");
} else {
    printf("%s\n", "strtok OK");
}

outputFileName = strcat (outputFileName, ".lzw");
FILE* outFile;
outFile = fopen (outputFileName, "a");

Но файл не создается. Теперь я пытаюсь проверить, что вернула strtok В консоль не выводятся проверочные строки NULL Караул или strtok OK В таком случае strtok вообще не отработала? Что она вернула?

Вызываю функцию так, просто для теста.

 int main (){

    FILE* compressed = compress("toCompress.txt"); 

    return 0;
} 

Файл toCompress.txt уже заранее создан в той же папке, что и exe. По поводу краша не думаю, так как кроме проверки strtok вывожу еще в консоль положение точки. Выводит 11, что верно. Уточню, что функция возвращает выходной файл и если в переменную outFile записать

   outFile = fopen ("toCompress.lzw");

такой файл создастся. То есть проблема именно в функции strtok


Ответы (1 шт):

Автор решения: Harry

Ну давайте займемся...

Итак, сразу: по-хорошему, строковый литерал "есть лицо неприкосновенное", его нельзя менять, так что если передаете

compress("toCompress.txt"); 

то используйте его как const char *. Одно это изменение у меня на Visual C++ перестало вызывать крэш программы.

char s[] = "toCompress.txt";
compress(s);

или

compress(const char* inputFileName)

Но идем дальше. Что вы получаете вот тут

char * ex = strchr (inputFileName, '.');

Вы получаете ex как указатель на строку .txt, т.е. strtok считает разделителями символы точка ., t и x. И, понятно,

strtok(inputFileName, ex);

обрывает вас на первом же символе t. Вы получаете outputFileName, равный

oCompress

После прибавления - но только если вы передаете не строковый литерал, а массив! иначе - крэш программы!! - вы получите в outputFileName

oCompress.lzw

И то, надо обязательно озаботиться, чтоб хватало места для добавляемого текста!

Итак, самая главная ваша ошибка - работа со строковым литералом как с char*, второстепенная - непонимание, как правильно работает strtok.

Update

Вот примерно как надо:

FILE* compress (const char* inputFileName)
{
    char* out = malloc(strlen(inputFileName)+5); // Для расширения и \0
    strcpy(out,inputFileName);
    char * ex = strrchr(out, '.');
    if (ex) strcpy(ex,".lzw");
    else strcat(out,".lzw");

    FILE* outFile;
    outFile = fopen(out, "a");

    free(out);

    //.....

    return outFile;

}
→ Ссылка