как бы строку на слова поделить в С++ ? (а то строка такая: char* str;)

Модератор: Модераторы разделов

Аватара пользователя
Ослик ИА
Сообщения: 261

как бы строку на слова поделить в С++ ?

Сообщение Ослик ИА »

strtok пробовалось.
ничего кроме глюков не наблюдается.
должна же быть для того функция специальная!
литературы перерыто - море.
спасибо за внимание
Спасибо сказали:
Аватара пользователя
Jan2ary
Бывший модератор
Сообщения: 630
Статус: Тщедушный очкарик

Re: как бы строку на слова поделить в С++ ?

Сообщение Jan2ary »

Не знаю, насколько это корректно, но я использовал memchr для смещения до следующего пробела, между указателями и есть слово, непарсенная строка начиниается с нового указателя. В общем, писать свою ф-цию...

Еще есть index(...)....

В общем, man 3 string.
Не шалю, никого не трогаю, починяю примус...
Спасибо сказали:
Аватара пользователя
elide
Бывший модератор
Сообщения: 2421
Статус: Übermensch
ОС: лялих

Re: как бы строку на слова поделить в С++ ?

Сообщение elide »

а что там за глюки? вполне, по-моему, работоспособная функция. все прекрасно разбивает....
опиши детальнее проблему, может где недочет вкрался?
слава роботам!
Спасибо сказали:
Аватара пользователя
Jan2ary
Бывший модератор
Сообщения: 630
Статус: Тщедушный очкарик

Re: как бы строку на слова поделить в С++ ?

Сообщение Jan2ary »

Кстати, да, в мане указано, что strtok модифицирует свой первый аргумент. Это?
Не шалю, никого не трогаю, починяю примус...
Спасибо сказали:
Аватара пользователя
elide
Бывший модератор
Сообщения: 2421
Статус: Übermensch
ОС: лялих

Re: как бы строку на слова поделить в С++ ?

Сообщение elide »

во-во, и я так подумал. просто если исходная строка - констатна, strtok может выпасть с segfault.
слава роботам!
Спасибо сказали:
Аватара пользователя
TIM
Сообщения: 91
ОС: FreeBSD

Re: как бы строку на слова поделить в С++ ?

Сообщение TIM »

(elide @ Четверг, 23 Декабря 2004, 19:33) писал(а):во-во, и я так подумал. просто если исходная строка - констатна, strtok может выпасть с segfault.


конечно, выпадет ...

константа лежит в read-only секции программы, а strtok() вместо разделителя пишет в память "\0"
А запись в read-only память - это и есть segfault
Спасибо сказали:
Аватара пользователя
Jan2ary
Бывший модератор
Сообщения: 630
Статус: Тщедушный очкарик

Re: как бы строку на слова поделить в С++ ?

Сообщение Jan2ary »

Подождем от Инги подробностей...
Не шалю, никого не трогаю, починяю примус...
Спасибо сказали:
-=Zepplock=-
Сообщения: 49

Re: как бы строку на слова поделить в С++ ?

Сообщение -=Zepplock=- »

(TIM @ Четверг, 23 Декабря 2004, 17:38) писал(а):А запись в read-only память - это и есть segfault


Это еще почему?
Спасибо сказали:
Аватара пользователя
elide
Бывший модератор
Сообщения: 2421
Статус: Übermensch
ОС: лялих

Re: как бы строку на слова поделить в С++ ?

Сообщение elide »

потому, что так устроен этот поганый мир. в память только_для_чтения писать нельзя....
слава роботам!
Спасибо сказали:
-=Zepplock=-
Сообщения: 49

Re: как бы строку на слова поделить в С++ ?

Сообщение -=Zepplock=- »

(elide @ Пятница, 31 Декабря 2004, 19:30) писал(а):потому, что так устроен этот поганый мир. в память только_для_чтения писать нельзя....


Как мы определяем "только_для_чтения".
Это типо CONST да?


-=Zepplock=- добавил в 01.01.2005 00:05
как вы думаете что вот это даст?

Код: Выделить всё

#include <iostream>
#include <cstdlib>

using namespace std;

int main(int argc, char *argv[])
{
  const char text = 'a';
  printf("%c\n", text);
  char* p = const_cast<char*>(&text);
  *p = 'A';
  printf("%c\n", *p);
  printf("%c\n", text);
  return EXIT_SUCCESS;
}


вот это



а теперь все дружно думаем почему ))))

p.s. подсказка тут
Спасибо сказали:
Аватара пользователя
elide
Бывший модератор
Сообщения: 2421
Статус: Übermensch
ОС: лялих

Re: как бы строку на слова поделить в С++ ?

Сообщение elide »

ну, во-первых, даже в твоем примере сам text ты так и не изменил (:
а, во-вторых, работа компилятора с отдельными символами и с ASCIIZ строками - немного различается.
вот посмотри на этот код, и найди десять отличий:

Код: Выделить всё

#include <iostream>
#include <cstdlib>
using namespace std;
int main(int argc, char *argv[])
{
 char *text = "abc";
 printf("%s\n", text);
 char* p = const_cast<char*>(text);
 *p = 'A';
 printf("%s\n", p);
 printf("%s\n", text);
 return EXIT_SUCCESS;
}
а потом скомпили, запусти и возрадуйся.
слава роботам!
Спасибо сказали:
-=Zepplock=-
Сообщения: 49

Re: как бы строку на слова поделить в С++ ?

Сообщение -=Zepplock=- »

он поменялся )
нет такого понятия как read-only память - это только для программистов - чтоб часть run-time ошибок перевести в compilation-time ошибки

ты лучше скажи почему поинтер на char печатает одно а сам char другое (последние 2 принтфа)

:new_biggrin:
Спасибо сказали:
Аватара пользователя
elide
Бывший модератор
Сообщения: 2421
Статус: Übermensch
ОС: лялих

Re: как бы строку на слова поделить в С++ ?

Сообщение elide »

потому, что в случае одного чара - значение копируется...
нет такого понятия как read-only память - это только для программистов - чтоб часть run-time ошибок перевести в compilation-time ошибки
ну если по-твоему, segfault при обращении к странице памяти - это compilation-time ошибка... ну-ну... и вообще-то есть такое понятие как read-only память. если не знаешь, чего споришь? вот цитата из того документа, что ты приводил:
The standard does not say where the compiler puts literal strings. They can go anywhere, possibly in some place in memory that you shouldn't be modifying.
слава роботам!
Спасибо сказали:
-=Zepplock=-
Сообщения: 49

Re: как бы строку на слова поделить в С++ ?

Сообщение -=Zepplock=- »

Для elide:
(elide @ Суббота, 01 Января 2005, 3:25) писал(а):потому, что в случае одного чара - значение копируется...


это абсолютно не связано с типом переменной, тот же эффект будет например с интом.

(elide @ Суббота, 01 Января 2005, 3:25) писал(а):ну если по-твоему, segfault при обращении к странице памяти - это compilation-time ошибка... ну-ну...

я этого не говорил. внимательней читай то что я написал.
я сказал что const - это для программистов, для удобства программирования, компилятор тебе укажет на твою ошибку если ты попытаешся модифицировать read-only (что есть const) ПЕРЕМЕННУЮ. А такой вещи как read-only (или const) памяти нет.

Для этого я привел тебе пример гдя я поменял то место в памяти которое было аллоцировано как read-only (const в программе)

Кроме того в цитате что ты привел ничего не сказано про read-only память, а лишь разъясняет частный случай аллокации строк (и ОЧЕНЬ зависит от компилятора), кроме того говорит о том что SHOULD NOT, а не CAN NOT кстати.

Поэтому не надо воспринимать в штыки когда человек тратит свое время и что либо тебе объясняет. Все мы учимся и ничего зазорного в этом нет. Я хожу сюда время от времени и узнаю много нового о Линуксах - за что форуму отдельное спасибо.
Спасибо сказали:
Аватара пользователя
elide
Бывший модератор
Сообщения: 2421
Статус: Übermensch
ОС: лялих

Re: как бы строку на слова поделить в С++ ?

Сообщение elide »

это абсолютно не связано с типом переменной
согласен. это зависит от того, что ей присваиваешь.

Код: Выделить всё

#include <stdio.h>

int main(){
    char c='1';
    char d='2';
    char *t1=&c;
    char *t2=&d;
    char *t3="1";
    char *t4="2";

    printf("t1 at %x\nt2 at %x\n", t1, t2);
    printf("&t1 at %x\n&t2 at %x\n", &t1, &t2);
    printf("&t3 at %x\n&t4 at %x\n", &t3, &t4);
    printf("t3 at %x\nt4 at %x\n", t3, t4);
    return 0;
}
это тебе о чем-то говорит?

А такой вещи как read-only (или const) памяти нет
ты знаешь структуру elf, или хотябы pe?
ты знаешь, что различные секции могут иметь различные режимы доступа? что для секция данных можно указать, что ее содержимое не будет выполняться, а дла секции кода - не будет модифицировано? так вот для секции инициализированных данных практически всеми компиляторами указывается разрешение только на чтение. и система виртуальной памяти отслеживая попытки модификации read-only секции, гробит программу с сообщением segmentation fault, при всяком нарушении режима доступа. что это, если не const storage?
а в том документе, что ты приводил, написано, что ты МОЖЕШЬ изменять содержимое const storage, но тебе НЕ СТОИТ этого делать. т.к. это действие приводит к undefined behavior. т.о. иногда может и сработать, но не на всех компиляторах, и не на всех системах.
слава роботам!
Спасибо сказали:
-=Zepplock=-
Сообщения: 49

Re: как бы строку на слова поделить в С++ ?

Сообщение -=Zepplock=- »

Структура файла здесь непричем.

В этом примере я показал что память аллоцированная под const переменную может быть модифицирована
как бы строку на слова поделить в С++ ?
Спасибо сказали:
Аватара пользователя
elide
Бывший модератор
Сообщения: 2421
Статус: Übermensch
ОС: лялих

Re: как бы строку на слова поделить в С++ ?

Сообщение elide »

Структура файла здесь непричем.
очень даже причем - в твоем примере переменная выделяется на стеке, где нет системных ограничений на модификацию, поэтому в этом случае контроль осуществляется средствами языка, и ты показал, как его можно обойти отменив константность переменной. в случае строковых литералов память для них выделяется в секции данных, а не в стеке. а на секцию данных наложено системное ограничение на модификацию. поэтому сообщение об ошибке ты получаешь не от компилятора, а от подсистемы виртуальной памяти ОС. так вот как раз структура файла здесь причем.

кстати, если уж я заблуждаюсь, а ты прав, не мог бы ты, если найдется немного свободного времени, привести пример модификации строки. вот есть const char* str="test string";
и ее надо изменить. вот каким образом это можно сделать?
слава роботам!
Спасибо сказали:
-=Zepplock=-
Сообщения: 49

Re: как бы строку на слова поделить в С++ ?

Сообщение -=Zepplock=- »

(elide @ Суббота, 01 Января 2005, 22:07) писал(а):вот есть const char* str="test string";


а если это не const - то ты ее поменять можешь? :new_biggrin:
Спасибо сказали:
Аватара пользователя
elide
Бывший модератор
Сообщения: 2421
Статус: Übermensch
ОС: лялих

Re: как бы строку на слова поделить в С++ ?

Сообщение elide »

я намекаю тебе на то, что ее в ЛЮБОМ случае нельзя изменить, будь она хоть конст, хоть не конст.
просто ты так красиво рассуждал о const в С++, что я подумал так тебе больше понравится. (:
слава роботам!
Спасибо сказали:
-=Zepplock=-
Сообщения: 49

Re: как бы строку на слова поделить в С++ ?

Сообщение -=Zepplock=- »

(elide @ Суббота, 01 Января 2005, 23:15) писал(а):просто ты так красиво рассуждал о const в С++


так как приходится программировать на C++ по 8-10 чаов в день и уже не первый год - то только философское отношение и спасает ))

(elide @ Суббота, 01 Января 2005, 23:15) писал(а):что я подумал так тебе больше понравится. (:


тут дело не в нравится или нет )
просто я интерпретировал твое определение read-only как const, а ты имел ввиду немного другое видимо )

Зато сколько интересных примеров разобрали )
Спасибо сказали:
Аватара пользователя
elide
Бывший модератор
Сообщения: 2421
Статус: Übermensch
ОС: лялих

Re: как бы строку на слова поделить в С++ ?

Сообщение elide »

я интерпритировал read-only, как память, которую невозможно изменить в run-time, потому что твоя прога немедленно будет выгружена ядром за нарушение режима доступа к странице памяти.
слава роботам!
Спасибо сказали:
-=Zepplock=-
Сообщения: 49

Re: как бы строку на слова поделить в С++ ?

Сообщение -=Zepplock=- »

Да, в большинстве операционных систем так и будет.

А ты разобрался почему в моем 1м примере результат

a
A
a

а не

a
A
A

? :new_biggrin:
Спасибо сказали:
Аватара пользователя
elide
Бывший модератор
Сообщения: 2421
Статус: Übermensch
ОС: лялих

Re: как бы строку на слова поделить в С++ ?

Сообщение elide »

ну тут я могу только догадываться. подтверждения своим догадкам я нигде не нашел...
а вообще хороший пример (: Изображение
слава роботам!
Спасибо сказали:
-=Zepplock=-
Сообщения: 49

Re: как бы строку на слова поделить в С++ ?

Сообщение -=Zepplock=- »

все дело в том что const_cast на самом деле срабатывает и мемори под констом меняется

но компилятор для printf("%c\n", text);
подставляет movl $0x61,0x4(%esp)

т.е он подставляет то что ты как чар прописал (для интов тоже самое)

вообще это не очень красиво, хотя скорее всего это оптимизация компилятора для скорости.
Спасибо сказали:
Аватара пользователя
elide
Бывший модератор
Сообщения: 2421
Статус: Übermensch
ОС: лялих

Re: как бы строку на слова поделить в С++ ?

Сообщение elide »

я так и подумал (в исходниках правда не смотрел (: ), но нигде не нашел упоминаний возможности такого поведения...
поэтому и усомнился.
слава роботам!
Спасибо сказали:
Аватара пользователя
oav
Бывший модератор
Сообщения: 296

Re: как бы строку на слова поделить в С++ ?

Сообщение oav »

(Ослик ИА @ Четверг, 23 Декабря 2004, 17:04) писал(а):Ответ в как бы строку на слова поделить в С++ ?


как-нить так?

Код: Выделить всё

bool split_by_words( const std::string& str , std::vector<std::string>& words , char delimeter = ' ' )
{
    std::string::size_type i(0),tmp;
    do
    {
  tmp = str.find( delimeter , i );
  words.push_back( str.substr( i , tmp == std::string::npos ? tmp : tmp -i ) );
  i = tmp + 1;
    }while( tmp != std::string::npos );

#ifdef OUTPUT_WORDS_VECTOR
    std::copy( words.begin() , words.end() ,
  std::ostream_iterator<std::string>( std::cout , "\n" ));
#endif

    return words.empty();
}

писал на коленке, мож можно по-лучше (по-меньше) написать...
Спасибо сказали:
-=Zepplock=-
Сообщения: 49

Re: как бы строку на слова поделить в С++ ?

Сообщение -=Zepplock=- »

(oav @ Понедельник, 03 Января 2005, 12:20) писал(а):как-нить так?

писал на коленке, мож можно по-лучше (по-меньше) написать...


если важна скорость то std::string плохо )
Спасибо сказали:
Аватара пользователя
oav
Бывший модератор
Сообщения: 296

Re: как бы строку на слова поделить в С++ ?

Сообщение oav »

(-=Zepplock=- @ Понедельник, 03 Января 2005, 21:08) писал(а):если важна скорость то std::string плохо )


Ну, это у тебя пройдет ;) Гораздо дороже и ценней читабельность и сопровождаемость кода.

зы1: первое правило оптимизации - ничего не оптимизируй. второе - см. первое.
зы2: кто сказал что std::string такой медленный?
Спасибо сказали:
-=Zepplock=-
Сообщения: 49

Re: как бы строку на слова поделить в С++ ?

Сообщение -=Zepplock=- »

(oav @ Вторник, 04 Января 2005, 17:04) писал(а):Гораздо дороже и ценней читабельность и сопровождаемость кода.


Ну ну, это пройдет )

Ну вот сижу щас и смотрю на код где на каждый UDP пакет (днс запрос) - создается по 2 std::string, всего генерятся 200 тысяч запросов в секунду. Помянял чтоб пакет был собран заранее и не было операций над std::string - стало 270 тысяч.

п.с. кстати если не пользуешься std::string - все равно можно писать читабельный и сопровождаемый код )
Спасибо сказали:
Аватара пользователя
oav
Бывший модератор
Сообщения: 296

Re: как бы строку на слова поделить в С++ ?

Сообщение oav »

(-=Zepplock=- @ Вторник, 04 Января 2005, 21:36) писал(а):
(oav @ Вторник, 04 Января 2005, 17:04) писал(а):Гораздо дороже и ценней читабельность и сопровождаемость кода.


Ну ну, это пройдет )

Ну вот сижу щас и смотрю на код где на каждый UDP пакет (днс запрос) - создается по 2 std::string, всего генерятся 200 тысяч запросов в секунду. Помянял чтоб пакет был собран заранее и не было операций над std::string - стало 270 тысяч.

п.с. кстати если не пользуешься std::string - все равно можно писать читабельный и сопровождаемый код )


енто все за уши притянуто ;) ну скажи, какие 200 тыш запросов в секундну в обычном, самом массовом софте? (мы ведь в общем говорим?) ;)
и на каких операциях std::string тормозит конкретно? - интересно же
Спасибо сказали: