#c
#c
Вопрос:
В настоящее время я использую fscanf для получения слов, разделенных пробелом. Я устанавливаю символ[] фиксированного размера для хранения каждого из извлеченных слов. Как бы мне создать символ[] с правильным количеством пробелов для хранения правильного количества символов из word? Спасибо.
Редактировать: если я выполняю strdup для символа [1000], а символ [1000] на самом деле содержит только 3 символа, будет ли strdup резервировать место в куче для 1000 или 4 (для завершающего символа)?
Комментарии:
1. Вы имеете в виду, что
char[]
выделяемое вами пространство недостаточно велико для слов, с которыми вы читаетеfscanf()
?2.
strdup()
выделяется только используемое пространство вплоть до первого NUL''
включительно в копируемой строке — таким образом, 4, а не 1000 в вашем примере.3. Итак, я выделяю большое пространство для символа[]. Существуют строки в диапазоне от 1 до 1000. Я не хочу резервировать 1000 байт для каждой строки, если они могут состоять только из 3 символов.
Ответ №1:
Вот решение, включающее только два выделения и без realloc
:
- Определите размер файла, просматривая до конца и используя
ftell
. - Выделите блок памяти такого размера и прочитайте в него весь файл с помощью
fread
. - Подсчитайте количество слов в этом блоке.
- Выделите массив,
char *
способный содержать указатели на такое количество слов. - Снова выполните цикл по блоку текста, назначая каждому указателю адрес начала слова и заменяя разделитель слов в конце слова на 0 (нулевой символ).
Также, немного философский вопрос: если вы считаете, что такой подход, заключающийся в вставке на место ограничителей строк и разбиении одной гигантской строки, чтобы использовать ее как можно больше маленьких строк, уродлив, халтурен и т.д. Тогда вам, вероятно, следует забыть о программировании на C и использовать Python или какой-либо другой язык более высокого уровня. Возможность выполнять радикально более эффективные операции обработки данных, подобные этой, при минимизации потенциальных точек сбоя — это практически единственная причина, по которой кто-либо должен использовать C для такого рода вычислений. Если вы хотите выделить каждое слово отдельно, вы просто превращаете свою жизнь в сущий ад, делая это на C; другие языки с радостью скроют эту неэффективность (и множество возможных точек сбоя) за удобными строковыми операторами.
Ответ №2:
Нет одного-единственного способа. Идея состоит в том, чтобы просто выделить строку, достаточно большую, чтобы вместить максимально возможную строку. После того, как вы прочитаете его, вы можете выделить буфер точно нужного размера и скопировать его, если это необходимо.
Кроме того, вы также можете указать ширину в строке формата fscanf, чтобы ограничить количество считываемых символов и гарантировать, что ваш буфер никогда не переполнится.
Но если вы выделили буфер, скажем, из 250 символов, трудно представить ни одного слова, не помещающегося в этот буфер.
Ответ №3:
char *ptr;
ptr = (char*) malloc(size_of_string 1);
char first = ptr[0];
/* etc. */