Задачка...

Модераторы: Hawk, Romeo, Absurd, DeeJayC, WinMain

Ответить
Yurich
Сообщения: 107
Зарегистрирован: 23 фев 2004, 19:07

Гуры и монстры C++,

если есть желание посмотрите вот такую задачку...

Есть код:

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

#include <string>
#include <iostream>
#include <cstdlib>

int main(int argc, char *argv[])
{
 std::string tmp = "0,0,1.4;0,25,2.0;0,61,2.7;13.4,0,10%;13.4,25,15%;13.4,61,20%;133.4,0,13.4;133.4,25,20.0;133.4,61,26.7";

 std::string::size_type s_pos = 0, e_pos = 0;
 const char sep = ';';

 do
 {
  e_pos = tmp.find_first_of(&sep, s_pos);
  std::string val = tmp.substr(s_pos, e_pos-s_pos);
  std::cout << val << std::endl;
  s_pos = tmp.find_first_not_of(&sep, e_pos);
 }
 while(e_pos != std::string::npos);

 return 0;
}
 
который на моей машине (SuSe Linux 2.6.8 )
выдает следующие результаты:

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

0,0,1.4
0,25,2.0
0,61,2.7
13.4,0,10%
13.4,25,15%
13.4,61,2
0%
133.4,0,13.4
133.4,25,20.0
133.4,61,26.7
Вопрос: почему "0%" вылезает на 7 строке, когда он должен быть на 6-й?
Аватара пользователя
Oscar
Сообщения: 963
Зарегистрирован: 29 май 2004, 13:44
Откуда: Мюнхен (рожден в Киеве)
Контактная информация:

Solaris (g++ (GCC) 3.2.2) вернул:

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

0,0,1.4
0,25,2.0
0,61,2.7
13.4,0,10%
13.4,25,15%
13.4,61,20%
133.4,0,13.4
133.4,25,20.0
133.4,61,26.7
Linux (g++ (GCC) 3.3.1 (SuSE Linux)) - есть перенос в 6-й строке ..
Не знаю почему, но может это хоть как-то сможет помочь ..
Yurich
Сообщения: 107
Зарегистрирован: 23 фев 2004, 19:07

Oscar писал(а):Solaris (g++ (GCC) 3.2.2) вернул...
:) Класс, у меня на Солярке тоже работает... Но на самом деле нет гарантии, что это будет работать и дальше... ;)
Аватара пользователя
Oscar
Сообщения: 963
Зарегистрирован: 29 май 2004, 13:44
Откуда: Мюнхен (рожден в Киеве)
Контактная информация:

Так работает:

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

#include <string>
#include <iostream>
#include <cstdlib>
using namespace std;

int main(int argc, char *argv[])
{
 string s = "0,0,1.4;0,25,2.0;0,61,2.7;13.4,0,10%;13.4,25,15%;13.4,61,20%;133.4,0,13.4;133.4,25,20.0;133.4,61,26.7"; 
 string tmp = s;

 string::size_type e_pos = 0;
 char sep = ';';

 do
 {
  e_pos = tmp.find_first_of(sep);
  string val = tmp.substr(0, e_pos);
  cout << val << endl;
  tmp = tmp.substr(e_pos+1, string::npos);
 }
 while(e_pos != string::npos);

 return 0;
}

Yurich
Сообщения: 107
Зарегистрирован: 23 фев 2004, 19:07

Oscar писал(а):Так работает...
Респект! 8) Понравилась задачка? ;)
Аватара пользователя
Oscar
Сообщения: 963
Зарегистрирован: 29 май 2004, 13:44
Откуда: Мюнхен (рожден в Киеве)
Контактная информация:

Yurich,
я на С года два не программировал.
Если бы я знал в чём причина, что оно под Linux не работет - тогда бы понравилось ...
а так ... просто очередная задача по уборке мусора.
Yurich
Сообщения: 107
Зарегистрирован: 23 фев 2004, 19:07

Oscar писал(а):Yurich,
я на С года два не программировал.
Если бы я знал в чём причина, что оно под Linux не работет - тогда бы понравилось ...
а так ... просто очередная задача по уборке мусора.
Все просто... 8)

Есть несколько вариантов функций
find_first_of и find_first_not_of и друших подобных...
Один из вариантов принимает разделитель как char, второй как char*
В примере разделитель типа char (который естественно не ограничен \0), но в функцию передается указатель на char. А функция получая указатель на char естественно считает его строкой ограниченной \0.
Вопрос скорее не почему это не работает на Linux'e, а почему это работает на Solaris. Мое предположение, что видимо программисты Сана обнуляют память после использования, поэтому после записи в память разделителя там идет \0. Хотя я не уверен, что этот код будет работать везде и всегда на Солярке.
Ответить