LINUX.ORG.RU

Как вы склеиваете строки с путями в чистом Си

 


0

0

Конкретно для имени файла в fopen - хочу передать каталог откуда читать в виде параметра, имя файла знаю внутри функции. В интернете похоже все обходятся или файлами в текущем каталоге или абсолютными путями или какими-то костылями из С++. Просьба обкатанный по жизни коде-снипет.

★★★★★

Так-же, как и в любом другом

folder + "/" + filename

Ой, си. man srtcpy

Dragon59 ★★
()
Последнее исправление: Dragon59 (всего исправлений: 1)

На сколько чистый Си, g_build_filename не пойдёт ?

ilovewindows ★★★★★
()

char buf[]; sprintf(buf, «%s», "");

//UPD: когда из технического ресурса создают развлекательный или СМИ портал - получаются «звездочки»

minakov ★★★★★
()
Последнее исправление: minakov (всего исправлений: 1)
Ответ на: комментарий от DeVliegendeHollander

Скорее всего сморел бы в сторону wchar_t. Честно говоря от написания некоторых программ именно на Си останавливает незнание его работы с unicode. Но согласись, что отсутсвие поддержки unicode директорий в третьем тысячелетии выглядит не очень.

anonymous
()
Ответ на: комментарий от netcat

Опередил.

Только что из man-ов вылез, смотрел всё, что относится к склейке строк, тоже нашёл wcscat. :)

DeVliegendeHollander ★★
()
Ответ на: комментарий от anonymous

А как быть с Unicode путями?

Если использовать UTF-8 для кодирования Unicode-ной строки, то всё так же dir + «/» + filename (с поправкой на strcat, strcpy).

Begemoth ★★★★★
()
Ответ на: комментарий от minakov

sprintf

Никогда-никогда. Только snprintf.

А так поддержу коллегу ilovewindows: g_build_filename со товарищи.

akk ★★★★★
()
Ответ на: комментарий от anonymous

от написания некоторых программ именно на Си останавливает незнание его работы с unicode. Но согласись, что отсутсвие поддержки unicode директорий в третьем тысячелетии выглядит не очень.

Согласен полностью. Тем более, что сейчас юникод в целом стал стандартом если и не де-юре, то де-факто.

DeVliegendeHollander ★★
()

Все время для этого использую snprintf().

joy4eg ★★★★★
()
Ответ на: комментарий от PolarFox

Если я правильно догадываюсь о какой ОС ты говоришь, то могу заметить, что в оной разделителем может быть как \, так и /, оба варианта понимаются подсистемой Win32.

Begemoth ★★★★★
()
Ответ на: комментарий от PolarFox
#ifdef OS_WIN
	#define FS_DEPARATOR '\\'
#else
	#define FS_DEPARATOR '/'
#endif //OS_WIN

ну и в файле проекта определение OS_WIN, конечно

anonymous
()
Ответ на: комментарий от I-Love-Microsoft

Обычно все-таки что-то более простое для работы с отдельными символами, типа UTF-16. CoreFoundation (iOS, OS X), правда, вообще может в MacRoman хранить, если все символы влезают и строка неизменяемая.

note173 ★★★★★
()
Ответ на: комментарий от minakov

//UPD: когда из технического ресурса создают развлекательный или СМИ портал - получаются «звездочки»

УМВР ЧЯДНТ?

char buf[]; sprintf(buf, "%s", "");
derlafff ★★★★★
()
Ответ на: комментарий от PolarFox

да ну? а вообще да, в UTF-16 тоже есть расширение символов на большую ширину? я не ошибаюсь?

хотя мне пофиг - UTF-8 это святое для меня

I-Love-Microsoft ★★★★★
()
Ответ на: комментарий от I-Love-Microsoft

в UTF-16 тоже есть расширение символов на большую ширину?

Ага. Можно на него забить и получится UCS-2, который для большинства будет работать.

PolarFox ★★★★★
()
Ответ на: комментарий от minakov

спасибо, вполне компактненько.

мой снипет для истории:

    char file_path[strlen(input_data_path) + strlen("inputfile.txt") + 1]; 
    sprintf(file_path, "%s/%s", input_data_path, "inputfile.txt");
    f=fopen(file_path, "r");
bender ★★★★★
() автор топика
Ответ на: комментарий от ilovewindows

забыл, да

пусть будет так:

   char file_path[strlen(input_data_path) + 1 + strlen("inputfile.txt") + 1]; 
    sprintf(file_path, "%s/%s", input_data_path, "inputfile.txt");
    f=fopen(file_path, "r");

bender ★★★★★
() автор топика

или какими-то костылями из С++
пусть будет так:

Уж лучше костыли. Чесслово. :)

zJes ★★
()

Так тут уже говна понаписали, то хуже уже не будет:

int foo (const char* dirname...)
{

if (chdir(dirname)) {
...
... open(...);
...
}
...
}
anonymous
()
Ответ на: комментарий от bender

Вместо sprintf сподручнее будет mempcpy - хоть и не стандартная функция, но пишется в одну строку.

anonymous
()
Ответ на: комментарий от I-Love-Microsoft

Да, плюс модифицирующие символы, от них никуда не денешься, даже в UTF-32.

anonymous
()

Сохраняем путь к текущей директории, делаем chdir() в новую директорию, открываем в ней файл, возвращаемся в сохраненную директорию.

hippi90 ★★★★★
()
Ответ на: комментарий от hippi90

Сохраняем путь к текущей директории, делаем chdir() в новую директорию, открываем в ней файл, возвращаемся в сохраненную директорию.

и ловим баг описанный ещё Гомером и норвежскими скальдами: Одисей по возврату мог и не застать свою Пенелопу, ей как раз собиралась поменять фамилию :)

MKuznetsov ★★★★★
()
Ответ на: комментарий от zJes

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

bender ★★★★★
() автор топика
Ответ на: комментарий от MKuznetsov

Если директория, в которую мы хотим перейти, не существует, chdir() просто вернет -1. Уж это можно обработать.

hippi90 ★★★★★
()

Если директория и пути известны на этапе компиляции - можно (предварительный define) PATH «a/b/c.txt» (literal string concatenation, вроде c99, почти все компиляторы умеют).

anonymous
()
Ответ на: комментарий от hippi90

Дублирование же может возникнуть: обработка для отсутствия директории и для самого файла => дополнительный бойлерплэйт (хотя бы для выделения блока обработки и перехода туда).

anonymous
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.