C: манипуляции со строками, добавление большего количества символов без переполнения буфера - PullRequest
1 голос
/ 04 августа 2011

В CI есть путь в одной из моих строк

/home/frankv/

Теперь я хочу добавить имена файлов, которые содержатся в этой папке - например, file1.txt file123.txt и т. Д.

Объявив мою переменную, например,

char pathToFile[strlen("/home/frankv/")+1]

или

char *pathToFile = malloc(strlen("/home/frankv/")+1)

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

Я действительно привык к ленивому PHP $ string1. $ String2 .. Какой самый простой способ сделать это вC

Ответы [ 5 ]

6 голосов
/ 04 августа 2011

Если вы выделили буфер с malloc(), вы можете использовать realloc() для его расширения:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(void) {
    char *buf;
    const char s1[] = "hello";
    const char s2[] = ", world";

    buf = malloc(sizeof s1);
    strcpy(buf, s1);

    buf = realloc(buf, sizeof s1 + sizeof s2 - 1);
    strcat(buf, s2);

    puts(buf);

    return 0;
}

ПРИМЕЧАНИЕ : я не включил проверку ошибок.Ты не должен.Всегда проверяйте, возвращает ли malloc() нулевой указатель;если это произойдет, предпримите некоторые корректирующие действия, даже если это просто завершает программу.Аналогично для realloc().И если вы хотите иметь возможность восстановления после сбоя realloc(), сохраните результат во временном хранилище, чтобы не заглушить исходный указатель.

1 голос
/ 04 августа 2011

У вас есть пара опций, но, если вы хотите сделать это динамически, без дополнительных библиотек, realloc () - это функция stdlib, которую вы ищете:

char *pathToFile = malloc(strlen("/home/frankv/")+1);
char *string_to_add = "filename.txt";

char *p = realloc(pathToFile, strlen(pathToFile) + strlen(string_to_add) + 1);
if (!p) abort();
pathToFile = p;
strcat(p, string_to_add);

Примечание: вы должны всегда присваивать результат realloc первому новому указателю, поскольку realloc () возвращает NULL в случае сбоя. Если вы присваиваете исходный указатель, вы просите утечки памяти.

Однако, если вы собираетесь много манипулировать строками, вы можете рассмотреть возможность использования библиотеки строк. Два, которые я нашел полезными, это bstring и ustr .

1 голос
/ 04 августа 2011

Используйте std :: string, если это возможно.В противном случае перераспределите другой блок памяти и используйте strcpy и strcat.

0 голосов
/ 04 августа 2011

Вы выбрали неправильный язык для работы со строками!

Простой и традиционный выход - сделать что-то вроде:

#define MAX_PATH 260
char pathToFile[MAX_PATH+1] = "/home/frankv/";

strcat(pathToFile, "wibble/");

Конечно, это подвержено ошибкам - если результирующая строка превышает символы MAX_PATH, может произойти все что угодно, и именно этот вид программирования используется многими троянами и червями для проникновения в систему безопасности (путем повреждения памяти в тщательно определенной путь). Следовательно, мой преднамеренный выбор 260 для MAX_PATH, который был в Windows - вы все равно можете заставить Проводник Windows делать странные вещи с вашими файлами с путями более 260 символов, возможно из-за кода, подобного этому!

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

Чтобы сделать это надежно, вам нужна библиотека строк, которая правильно делает строки переменной длины. Но я не знаю, есть ли такая вещь для C (C ++, конечно, другое дело).

0 голосов
/ 04 августа 2011

Если вы можете использовать C ++, используйте std::string.В случае, если вам нужно использовать чистый C, используйте то, что называется удвоением, то есть когда в строке не хватает места, удвойте память и скопируйте строку в новую память.И вам придется использовать второй синтаксис:

char *pathToFile = malloc(strlen("/home/frankv/")+1);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...