Странный вопрос. Просматриваешь строку с начала, подсчитывая попадающиеся пробелы (или группы подряд идущих пробелов, смотря что тебе надо), возможно пропуская начальные пробелы (опять же смотря что тебе надо). Запоминаешь позицию после n-1-го пробела и перед n-ным. Между ними - твоё поле.
Или я чего-то не понял?
Не просматривать всё подряд не выйдет, если только у тебя нет какой-то дополнительной информации об этой строке.
Вообще, ты про алгоритм же вроде спрашивал, я так понял что использование готовых библиотек отметается. А если нет - то конечно же нет смысла писать такое самому. Хотя именно это можно и написать, там писать-то...
Просто когда спрашивают об алгоритме, обычно имеют в виду, как это вообще должно работать, внутри. Безотносительно glibc, языка C, доступных библитек и прочих посторонних обстоятельств. В общем слово "алгоритм" маленько другое означает.
> почитай маны на них и условие задачи.
>
> на regex трудоёмкость на порядок меньше
Вспомним условие задачи:
> тоесть есть строкак состоящая из безпробелных полей разделённых
> произвольным количеством пробелов.
Единственный regexp в этой задаче - это "произвольное количество пробелов".
IMHO в C использование для такой цели regexp'ов - ненужный геморрой
и раздувание исходного кода. Хотя конечно можно использовать как
POSIX regexp'ы так и perlre - если хочется "стоя и в гамаке". :-)))
Я бы использовал или strtok (strtok_r) или просто цикл вручную -
получится куда короче, чем в regexp'ами.
2cvv:
> предлагаю посоревноватся.
> ты пытаешся реализовать на strtok или strsep а я не regex.
> потом сравним ;-)
Ну почему бы и нет...
Тогда поставь задачу более конкретно:
> нада ф-я выдающая поле по его номеру.
Что это значит? Сделать strdup() этого поля? Или вернуть указатель
на начало поля в исходной строке и отдельно его длину? Или сразу
распарсить всю строку и вернуть массив из char* на все поля с их
длинами? Или допускается модификация строки (забивание туда \0
вместо пробелов) и возврат массива из char* на все поля, при этом
длины уже не нужны? Или еще как?
Короче давай прототип функции ;-)
Млин, ну cvv, ты даешь, может ты лучше на python или perl пересядешь? Туда, где есть стандартная
библиотека, делающая все за тебя. Это же надо развить тему в форуме по такому вопросу. Я с вас ох..ваю.
Какие регекспы? это оверхеад, давай ка использовать их там, где они действительно нужны, там, где
они дают действительно ощутимый выигрыш в скорости разработки.
Функция, нужная тебе пишется за 3 минуты, решает задачу за O(n) (на регекспах ты этого не добьешься).
Вот пример, написанный за пару минут (без проверки на переполнение):
int
get_field (const char * const str, int num, char * ptr)
{
int len = strlen (str), state = 0, n = 0, i;
for (i = 0; i < len; ++p, ++i)
switch (state) {
case 0:
if (*p != ' ') state = ++n != num ? 1 : (*ptr++ = *p, 2);
break;
case 1:
if (*p == ' ') state = 0;
case 2:
if (*p == ' ') {
*ptr = 0; return 0;
} else
*ptr++ = *p;
}
return -1;
}
P.S. И стоило выносить эту тему на форум, показывая, что ты не можешь нормально решить такую задачу? Луговского на тебя нет...
sorry, гощу у родителей, залез в инет с виндовой тачки, а решение набил у себя на лэптопе, поэтому при переносе
пропустил две строки.
Нужно еще в начале
const char * p = str;
и break в конце ветки case 1.
В принципе p можно убрать, тогда получается так:
int
get_field (const char * str, int num, char * ptr)
{
int len = strlen (str), state = 0, n = 0, i;
for (i = 0; i < len; ++str, ++i)
switch (state) {
case 0:
if (*str != ' ') state = ++n != num ? 1 : (*ptr++ = *str, 2);
break;
case 1:
if (*str == ' ') state = 0;
break;
case 2:
if (*str == ' ') {
*ptr = 0; return 0;
} else
*ptr++ = *str;
}
return -1;
}
мои 5 копеек :)
писано с руки, не отлаживалось..
/** get field from space-sperated string
@arg str source string
@arg num field index
@arg dlen (out,optional) pointer for save field len
@return pointer to founded field (no \0 terminated - use dlen),
*/
#define SPACES " \t\v"
char *getfield(char *str,int num,int *dlen) {
int i;
assert(str!=NULL);
assert(num>=0);
num--;
str+=strspn(str,SPACES);
if (!*str)
return NULL;
for(i=0;i<num;i++) {
str+=strcspn(str,SPACES);
str+=strspn(str,SPACES);
if (!*str) {
return NULL;
}
}
if (dlen) (*dlen)=strcspn(str,SPACES);
return str;
}
2cvv:
Ну по твоему условию:
1. Вернуть ту же строку, нужное поле сдвинуто в начало.
2. Нумерация полей с единицы.
3. Если такого поля нет, строка станет нулевой длины.
На скорую руку, без всяких strtok() получается что-то типа:
#include <string.h>
char* get_field(unsigned n, char* str)
{
char *s, *e;
for (s=e=str; *e && n; n--)
{
for (s=e; *s == ' '; s++);
for (e=s; *e != ' ' && *e; e++);
}
if (n) s=e;
memmove(str, s, e-s);
str[e-s] = '\0';
return str;
}
ну во первых насколько я вижу ты программы пишеш только for fun и ни в одном серьёзном проэкте не учавствовал, иначе бы знал где существует масса задач для которых твои предложения на тему перла питона и иже с ними не годятся НИКАКИМ боком.
>чем не устраивают стандартные strsep/strtok ?
В манах их советуют не использовать:
man strsep:
>ОШИБКИ РЕАЛИЗАЦИИ
> Эта функция подвержена тем же проблемам, что и strtok(). В частности,
> она модифицирует исходную строку. Избегайте этой функции.
man strtok:
>ПРОБЛЕМЫ
> Никогда не используйте эти функции.
P.S. Я за использование strspn()/strcspn()
> ну во первых насколько я вижу ты программы пишеш только for fun и ни в одном серьёзном проэкте не учавствовал,
> иначе бы знал где существует масса задач для которых твои предложения на тему перла питона и иже
> с ними не годятся НИКАКИМ боком.
Нет, ну я с вас удивляюсь... И как это ты узнал, что я ни в одном серьезном проЭкте не учавствовал, из
каких моих слов ты сделал вывод, что я не знаю о "массе задач" для которых мои предложения на тему перла
и питона не годятся?
> а выдержать свою ф-ю хоть как-то соответвующей прототипу - слабо?
Я прочитал о твоем прототипе тогда, когда уже послал пост со своей реализацией. Да и не понравился мне
твой прототип. Кстати, интересно, ты действительно веришь, что мне слабо выдержать свою функцию в
соответствии с твоим прототипом, или это дополнительный повод меня покритиковать?
Я понимаю, что мог задеть тебя своими словами, но, по моему, я критиковал по существу, а вот ты -
нет (наверняка ты думаешь наоборот :) ). Извини, возможно я был немного резок.
Просто поднимать вопрос в форуме по такому делу... Делать с помощью
регекспов то, что и так пишется
за пару минут... Я понимаю, что Кнута с Корменом читать не хочется, но ты ведь хочешь быть программистом,
и, наверное, хорошим? Давай-ка ты почитаешь хотя бы Шеня - отличная книга, быстро читается, большое
число примеров - она очень полезна. А то развелось кодеров, которые изучат язык, стандартную
библиотеку и идут программровать, а программировать то они и не умеют... (особенно часто замечаю
это в сообществе Java-программистов (может от того, что их особенно много?).
Не прими мои слова как какое-то назойливое поучение. Это просто дружеский совет. Это действительно
стоит того, чтобы потратить немного своего времени.
P.S. не хотел никого обидеть...
Нет, я этого не рекомендую. Не знаю, где ты увидел что-то о преждевременной оптимизации? Я рекомендую учиться программированию.
Я не против готовых решений. Только за. Но ты сам решил написать нужную тебе функцию. Так почему бы не сделать это
нормально.
И вопрос в твоей манере: какими же серьезными задачами занимаешься ты, что можешь выносить такую маленькую задачу
на обсуждение в форум и ждать сутки, когда она решится, вместо того, чтобы за 10 минут сделать ее самому? По-моему
не похоже на то, что это серьезный проект с сжатыми сроками и т.д.
P.S. может перестанешь пытаться уличить меня в некомпетентности ?
P.P.S. я вполне согласен прекратить дискуссию, не имеющую отношение к первоначальному вопросу во избежание
возникновения неприятных впечатлений у оппонентов друг о друге :)
>И вопрос в твоей манере: какими же серьезными задачами занимаешься ты, что можешь выносить такую маленькую задачу на обсуждение в форум и ждать сутки, когда она решится, вместо того, чтобы за 10 минут сделать ее самому? По-моему не похоже на то, что это серьезный проект с сжатыми сроками и т.д.
просто я в тот день решил порядка сотни сильно разношерстных/разнотипных задач и когда к вечеру поднялась упомянутая мною задача мои мозги оказались не в состояниии переключится на новую тематику.
Hint: Енштейн за теоремой пифагора лазил в справочник а не выводил за 1 минуту.
> в тот день решил порядка сотни сильно разношерстных/разнотипных задач
8 часов по 60 минут на 100 задач это меньше 5 минут на каждую..
cvv : Вы монстр :)