char *str_replace(char *orig, char *rep, char *with);
Параметры функции:
orig исходная строка, в которой должна произойти замена. rep подстрока исходной строки, которая должна быть заменена. with строка, содержимое которой должно заменить подстроку rep.
Возвращаемое значение: в случае успеха будет возвращен ненулевой указатель, содержащий новую строку, где будут отражены изменения. Память для этой строки была выделена динамически с помощью malloс, поэтому впоследствии эту память следует освободить вызовом free. При неудаче будет возвращен NULL, в этом случае память освобождать не нужно.
char *str_replace(char *orig, char *rep, char *with) {
char *result; // возвращаемая строка
char *ins; // следующая позиция вставки
char *tmp; // переменный указатель
int len_rep; // длина rep (заменяемой строки)
int len_with; // длина with (строки, которая заменит rep)
int len_front; // дистанция между rep и окончанием последнего rep
int count; // количество замен
// Проверки безопасности:
if (!orig || !rep)
return NULL;
len_rep = strlen(rep);
if (len_rep == 0)
return NULL; // пустая rep приведет к бесконечному циклу для count
if (!with)
with = "";
len_with = strlen(with);
// count это количество необходимых замен
ins = orig;
for (count = 0; tmp = strstr(ins, rep); ++count)
ins = tmp + len_rep;
tmp = result = malloc(strlen(orig) + (len_with - len_rep) * count + 1);
if (!result)
return NULL;
// tmp указывает на конец результирующей строки
// ins указывает на следующее появление rep в orig
// orig указывает на оставшуюся часть orig "конца rep"
while (count--)
{
ins = strstr(orig, rep);
len_front = ins - orig;
tmp = strncpy(tmp, orig, len_front) + len_front;
tmp = strcpy(tmp, with) + len_with;
orig += len_front + len_rep; // move to next "end of rep"
}
strcpy(tmp, orig);
return result; }
Ниже показан пример использования: замена символа ~, обозначающего домашнюю директорию, на полный путь до домашней директории [2]. Функция ReadFile прочитает содержимое файла в выделенную динамически память, и вернет указатель на неё. В параметре filename может быть указан путь до файла, где допустимо использовать символ домашней директории '~', он будет автоматически заменен на полный путь с помощью функции (см. [2]). В ячейку *filesize будет записан размер прочитанного файла, равный объему выделенной памяти в байтах.
uint8_t *ReadFile (char *filename, int *filesize) {
uint8_t *result = NULL;
FILE *fp = NULL;
char *full_path = NULL;
do
{
full_path = str_replace(filename, "~", get_home_dir());
char *path = (NULL == full_path) ? filename : full_path;
*filesize = get_file_size(path);
if (-1 == *filesize)
break;
result = malloc (*filesize);
if (NULL == result)
break;
FILE *fp = fopen(path, "rb");
if (NULL == fp)
break;
if (fread(result, sizeof(uint8_t), *filesize, fp) != *filesize)
{
if(feof(fp))
{
printf("Premature end of file '%s'", path);
break;
}
else
{
printf("File '%s' read error", path);
break;
}
free(result);
result = NULL;
}
} while (false);
if (NULL != fp)
fclose(fp);
if (NULL != full_path)
free(full_path);
return result; }
[Ссылки]
1. What function is to replace a substring from a string in C? site:stackoverflow.com. 2. Получение пути домашней директории в Linux. |