Что возвращает функция 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 шт):
Ну давайте займемся...
Итак, сразу: по-хорошему, строковый литерал "есть лицо неприкосновенное", его нельзя менять, так что если передаете
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;
}