Для начала позвольте мне кое-что рассказать о хранении и строках.
Есть 3 основных типа хранения. Автоматический, динамический, статический. А статический обычно делится на два: только для чтения и для чтения-записи. Скоро вам пригодятся динамические и статические.
Автоматические переменные - это параметры функции и локальные переменные. Когда вы вызываете функцию, они помещаются в стек, а когда функция возвращается, они раскручиваются.
Динамический - это тот, который вы выделяете во время выполнения с семейством malloc
. Вот как мы создаем динамический массив. И вам нужно вернуть этот источник, когда вы закончите с free
. Если вы этого не сделаете, это называется утечкой памяти, и вы можете проверить утечку памяти с помощью инструмента valgrind
наряду с другими ошибками памяти. Это очень полезно для занятий системным программированием.
А статические - это те, которые остаются там на протяжении всего срока действия программы. Если вы определите глобальную переменную или static int i = 42
, она создаст статическую переменную для чтения и записи, чтобы вы могли ее изменить. А теперь уловка.
void foo() {
char *string1 = "hello, world" //static read-only
char string2[] = "hello, world" //automatic
}
Поэтому, если вы попытаетесь изменить string1
, вы получите ошибку сегментации, но это нормально, чтобы изменить string2
. Я не знаю, почему вы не получаете ошибки сегментации, выполняя decode_args("77900289008764")
, но я попал на свою машину. : D
Теперь C-струны. Они оканчиваются нулем, что означает, что каждая строка имеет конец (char) 0
символов, который говорит, что это конец строки. strtok
в основном заменяет шаблон символом NULL
, чтобы у вас было несколько подстрок вместо одной. Итак, из вашего примера он преобразует "77900289008764 NULL"
в "779 NULL 289 NULL 8764 NULL"
Итак, на вашем месте я бы подсчитал встречи с «00» в строке и выделил бы указатель на столько символов. Что-то вроде:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char ** decode_args(char *arguments, char *delim) {
int num_substrings = 1; // Note that C don't initialize with 0 like java etc.
int len_delim = strlen(delim);
for (int i = 0;
arguments[i] != '\0' && arguments[i + 1] != '\0'; // Any of last 2 chars are terminator?
++i)
if (strncmp(arguments + i /* same as &arguments[i] */, delim, len_delim) == 0)
++num_substrings;
char **result = (char **) malloc(sizeof(char *) * (num_substrings + 1));
int i = 0;
char* token = strtok(arguments, delim);
while (token != NULL){
result[i] = token;
++i;
token = strtok(NULL, delim);
}
result[i] = NULL; //End of results. execv wants this as I remember
return result;
}
int main(int argc, char *argv[])
{
char str[] = "foo00bar00baz";
char **results = decode_args(str, "00");
for (int i = 0; results[i] != NULL; ++i) {
char *result = results[i];
puts(result);
}
free(results);
return 0;
}
person
bca
schedule
26.02.2020
char * ls_args[]
, т.е. вам нужен массив указателей наchar
. Основная проблема в вашем случае - узнать количество аргументов перед определением массива. Имейте в виду, чтоstrtok
изменяет начальную строку. Это может затруднить определение количества аргументов вначале и их последующее копирование в этот массив. - person Gerhardh   schedule 26.02.202000
. Обратите внимание, что это не то, что делаетstrtok(..., "00");
;strtok()
поддерживает только односимвольные разделители (хотя и несколько), поэтому это эквивалентноstrtok(..., "0");
. Вы можете использоватьstrstr()
или подобное. - person Ctx   schedule 26.02.2020