у нас есть школьное задание, чтобы сделать определенную функцию разделения строк дан заголовок и аргументы функции не могут их изменить. эта функция должна разбить оригинал по разделителю на массив строк, в котором хранится каждая часть разделителя строк, не включенная, и в дополнение для каждого разделителя увеличить размер
void stringSplit(const char *original, char result[50][256], int* size, char delim){
size_t begin = 0;
if (!original){
return;
}
for(size_t i=0; i<strlen(original);i++ ){
if (original[i] == delim){
int str_begin = 0;
for( ; begin < i; begin++ ){
result[*size][str_begin] = original[begin];
str_begin++;
}
(*size)++;
begin ++ ;
}
}
}
for(size_t i=0; i<strlen(original);i++ ) -> for (size_t i = 0; original[i] != '\0'; i++ ), потому что strlen()считает символы и это неэффективно.
we have an school asignment - Не вовлекайте меня в свои задания.
@EdHeal - справедливо участвовать в заданиях, если спрашивающий приложил усилия, чтобы выполнить работу, но застрял. Я возражаю против того, чтобы текст задания просто вставлялся как вопрос.
«мы» подразумевает владение. "пожалуйста, помогите мне с ..." было бы лучше
@IharobAlAsimi Поскольку original не изменяется в цикле, я ожидаю, что оптимизатор предварительно вычислит длину строки и заменит условие цикла for этим значением, вместо того, чтобы каждый раз вызывать strlen, нет? Вероятно, все еще не так эффективно, как то, что вы предлагали, но я бы не ожидал значительного снижения производительности от использования strlen. Просто интересно outloud, ни одной сборки не смотрел.
Строки должны заканчиваться '\0'. Перед (*size)++; делайте: result[*size][str_begin] = 0;
С какой реальной проблемой вы столкнулись / что не работает? А что вам говорит ваш отладчик?
Сделайте копию original, а затем используйте strtok() и strcpy().
... или используйте strchr, memcpy и завершите строки назначения.
если у вас возникли проблемы, научитесь использовать отладчик для пошагового выполнения кода.
@yano правильно. Как я правильно помню, strlen просто использует приведение к unsigned для проверки 4-х символов на итерацию вместо 1. Вы не увидите большой измеримой разницы, пока не будете работать со строками из многих сотен (или тысяч) символов. (Я проводил тесты, потому что запоминающийся ум просто должен знать ....)
@yano, Предположим, что это правда. Оптимизатор обнаружил, что перемешивание не изменилось, и заменил вызов на фиксированную длину. Он по-прежнему выглядит как PHP и заслуживает того, чтобы его изменили. К тому же original[i] != '\0' более идиоматичен.
@ pm100 пытался, чтобы даже мой учитель не мог сказать, что не работает, я полагаю, это было что-то с указателем, я еще не очень хорошо их понимаю





Идея нормальная, но у вас есть пара ошибок:
Ваши строковые копии не завершаются '\0'. Также вы не принимаете
учетная запись, когда несколько разделителей следуют подряд.
Если вам не разрешено использовать
такие функции, как strchr и strncpy, тогда вы можете сделать это:
size_t str_begin = 0;
*size = 0; // the user may have passed an uninitialized int variable
for(size_t i = 0; original[i] && *size < 50; ++i)
{
if (original[i] == delim)
{
size_t sublen = i - str_begin;
if (sublen == 0)
{
// skip delimiter, last character was also a
// delimiter and/or the first character in
// original is a delimiter
str_begin++;
continue;
// or if you want to have empty words instead of skipping
// results[*size] = 0;
// (*size)++;
}
if (sublen > 256)
sublen = 256;
for(size_t j = 0; j < sublen; ++j)
result[*size][j] = original + str_begin + j;
result[*size][j] = 0; // \0-terminating string
(*size)++;
str_begin = i + 1; // updating str_begin to next char
}
}
Самый простой способ сделать это - как предложил Бармар - сделать копию исходной строки, а затем работать с strtok() и strcpy.
В качестве альтернативы вы можете использовать strchr в цикле для поиска разделителей и memcpy для копирования памяти между предыдущим разделителем и следующим. См. Следующий код, который также учитывает границы результирующего массива:
void stringSplit(const char *original, char result[50][256], int *size, char
delim)
{
if (!original){
return ;
}
*size = 0;
const char* nextDelim;
const char* prevDelim = original;
do {
nextDelim = strchr(prevDelim,delim);
size_t len = nextDelim ? (nextDelim - prevDelim) : strlen(prevDelim);
if (len >= 256) {
len = 256-1;
}
memcpy(result[*size],prevDelim,len);
result[*size][len] = '\0';
(*size)++;
prevDelim = nextDelim ? nextDelim+1 : NULL;
}
while(nextDelim && *size < 50);
}
int main() {
char result[50][256];
int size;
stringSplit("Hello, this, is", result, &size, ',');
return 0;
}
Надеюсь, поможет.
Прохладный. У вас есть вопросы по этому поводу?