Я думаю, вы слишком много думаете об этом. Я знаю, что всегда заманчиво попытаться избежать malloc, но эффективность синтаксического анализа параметров никогда (*) не важна. Вы анализируете параметры только один раз, и, учитывая стоимость инициализации нового процесса, поиска исполняемого файла, его связывания и загрузки и всего остального процесса запуска команды, время, необходимое для анализа параметров, вероятно, даже не шум. .
Так что просто сделайте это самым простым способом. Вот один из возможных набросков:
int main(int argc, char* argv) {
/* These variables describe the options */
int nparts = 0; // Number of partitions
unsigned long* parts = NULL; // Array of partitions (of size nparts)
const char* diskname="/the/default/name"; // Disk's filename
for (;;) {
switch (getopt(argc, argv, "s:")) {
case '?':
/* Print usage message */
exit(1);
case 's':
/* Some error checking missing */
parts = realloc(parts, ++nparts * sizeof *parts);
parts[nparts - 1] = strtoul(optarg, NULL, 0);
continue;
case -1:
break;
}
break;
}
if (optind < argc) diskname = argv[optind++];
if (optind != argc) {
/* print error message */
exit(1);
}
return do_partitions(diskname, parts, nparts);
}
В приведенном выше коде отсутствует множество проверок ошибок и других тонкостей, но он краток и по существу. Он просто перераспределяет массив разделов каждый раз, когда обнаруживается новый размер. (Вероятно, это не так ужасно, как вы думаете, потому что сам realloc, вероятно, достаточно умен, чтобы экспоненциально увеличить размер выделения. Но даже если бы это было ужасно, это не будет происходить достаточно часто, чтобы даже заметить.)
Трюк с continue
и break
— это распространенный способ вложения переключателя внутрь for. В переключателе continue
продолжит цикл for, а break
выйдет из переключателя; поскольку все действия переключения, которые не завершают цикл for continue
, все, что следует за блоком переключения, выполняется только для действия переключения, которое явно break
s. Таким образом, break
, следующий за блоком switch
, прерывает цикл for именно в тех случаях, когда действие switch выполнило break
.
Возможно, вы захотите проверить, что был определен хотя бы один размер раздела, прежде чем вызывать функцию, которая выполняет переразметку.
person
rici
schedule
10.12.2015