LINUX.ORG.RU

C, простейшая задача


0

0

[корм для троллей] Лично меня уже достали тролли орущие, что дескать C++ - это говно с кучей никому не нужных костылей для быдлокодеров, а C (без плюсов) - это единственно правильный, очень простой в использовании язык, программы на котром всегда портируемы хоть куда. И вообще ниибаццо труЪ. [/корм для троллей]

Итак, задача: Напишите _функцию_, которая считывает со стандартного ввода число в переменную типа uint32_t (нужно именно 32хбитное беззнаковое целое) и возвращает его вызывающей стороне, если считываение удалось, либо сигнализирует вызывающей стороне об ошибке. Это всё =). Естественно, решение должно быть полностью совместимо с действующим стандартом на C и максимально коротким. Использование сторонних библиотек и нестандартных возможностей запрещено.

Чтобы не получилось недоразумения: мне нравится язык C++, но я не против других языков программирования и уважаю программистов которые на этих языках программируют. Просто задолбали тролли и быдлокрасноглазики... =)

P.S. Сейчас потихоньку изучаю common lisp.

Deleted
Ответ на: комментарий от Onanim

>> Нет, не работает. На строках типа "123xxxxx" радостно печатает выдает >> 123 вместо исключения.

Это правда не попадает под условие, но тогда и на C тоже правильного решения нету, т.к. scanf ведёт себя так же.

Deleted
()
Ответ на: комментарий от Deleted

> Это правда не попадает под условие,

Детального условия и не было.

> но тогда и на C тоже правильного решения нету, т.к. scanf ведёт себя так же.

Как это "на C тоже правильного решения нету"?
Даже решение dilmah (c "ручным" разбором строки) при всех прочих
недостатках отлавливало этот случай.

Или ставь задачу корректно или не *** людям мозг.

Onanim
()
Ответ на: комментарий от Onanim

> Нет, не работает. На строках типа "123xxxxx" радостно печатает выдает 123 вместо исключения.

хехе:)

dilmah ★★★★★
()
Ответ на: комментарий от Onanim

>> Детального условия и не было.
>> Или ставь задачу корректно или не *** людям мозг.

Ok, уточняю задачу: число должно быть отдельным словом (отделено
пробелом или переводом строки), может
начинаться с '+', в 10-чной системе счисления, целое. Со стандартного
ввода должно быть считано только это число и ничего больше.


>> Как это "на C тоже правильного решения нету"? 
>> Даже решение dilmah (c "ручным" разбором строки) при всех прочих
>> недостатках отлавливало этот случай. 

Ну у него другие недостатки были (см. выше).

В общем снова ждём мегарешения на C =).

Мой вариант на C++:

uint32_t readNum()
{
	uint32_t r;
	int      c;
	
	cin.exceptions(ios_base::badbit | ios_base::failbit);
	cin >> r;
	c = cin.peek();
	if ((EOF != c) && (' ' != c) && ('\n' != c))
		throw (exception());
	
	return r;
}

Deleted
()
Ответ на: комментарий от satanic-mechanic

>> ok, заменить int64_t на long long, везде где GNU портирован, будет работать, хотя теоретически long long может быть 32-битным...

Я уже написал выше, что лучше взять uintmax_t, так как оно стандартизовано.

Deleted
()
Ответ на: комментарий от satanic-mechanic

>> И, кстати, вышло не сравнение языков, а сравнение их стандартных библиотек...

На чистом синтаксисе без стандартной библиотеки ничего невозможно сделать. Даже простейший ввод/вывод. С другой стороны, на возможностях языка стрится стандартаная библиотека. Попробуйте например сделать типобезопасный ввод/вывод на C (собственно на это и задача) =).

Deleted
()
Ответ на: комментарий от Deleted

Точно, про uintmax_t не знал.

Но вообще-то нет гарантии, что оно будет больше 32 бит, а это необходимое условие простого решения с помощью scanf.

satanic-mechanic
()
Ответ на: комментарий от gaa

>> А как же \t? И вообще, не лучше ль тут употребить isspace?

Логично, вот обновлённый вариант:

uint32_t readNum()
{
	uint32_t r;
	int      c;
	
	cin.exceptions(ios_base::badbit | ios_base::failbit);
	cin >> r;
	c = cin.peek();
	if ((EOF != c) && (!isspace(c)))
		throw (exception());
	
	return r;
}

Deleted
()
Ответ на: комментарий от Onanim

>Нет, не работает. На строках типа "123xxxxx" радостно печатает выдает 123 вместо исключения.

Так и должно быть. Вы не знали????

anonymous
()
Ответ на: комментарий от satanic-mechanic

>> Но вообще-то нет гарантии, что оно будет больше 32 бит, а это необходимое условие простого решения с помощью scanf.

В uintmax_t гарантированно лезет любой uint*_t. Так что если uintmax_t меньше 32-х бит, то uint32_t просто не существует для такой платформы.

Deleted
()
Ответ на: комментарий от Deleted

>> А чего там у нас с Itanium C++ ABI :?

>А что с ним? Расскажите, возможно я что-то важное упустил из виду...

Извини ежель попутал. Случайно не в ту тему запостил. (

anonymous
()
Ответ на: комментарий от anonymous

Да ладно, к месту пришлось) Это как "Опасная уязвимость. Ждем патчей" в теме про релиз Python 3000

anonymous
()
Ответ на: комментарий от satanic-mechanic

>> Я говорю о случае, когда его размер 32 бита (а это теоретически возможно). Тогда код со scanf работать не будет.

Почему?

Deleted
()
Ответ на: комментарий от Deleted

Потому что не будет обрабатываться случай переполнения.

Аналогичная версия на C:

int read_uint32 (uint32_t * pn) { intmax_t t; int c; if (scanf ("%jd", &t) != 1) return -1; if (t < 0 || (intmax_t) (uint32_t) -1 < t) return -2; c = fgetc (stdin); if (c != -1 && isalpha (c)) return -3; *pn = (uint32_t) t; return 0; }

satanic-mechanic
()
Ответ на: комментарий от satanic-mechanic

int read_uint32 (uint32_t * pn)
{
  intmax_t t;
  int c;
  if (scanf ("%jd", &t) != 1)
    return -1;
  if (t < 0 || (intmax_t) (uint32_t) -1 < t)
    return -2;
  c = fgetc (stdin);
  if (c != -1 && !isspace (c))
    return -3;
  *pn = (uint32_t) t;
  return 0;
}

satanic-mechanic
()
Ответ на: комментарий от satanic-mechanic

>> Потому что не будет обрабатываться случай переполнения.

Вот зараза то... А я наивно полагал, что scanf проверяет переполнения вверх и вниз, так же как и istream'ы в C++... Тогда единственное решение для C - писать парсер вручную 8).

>> Аналогичная версия на C:

Нужно ещё ungetc() добавить.

Deleted
()
Ответ на: комментарий от Deleted

Не проверяет, только я все равно не вижу смысла задачи. Теоретически можно на C написать нужную функцию и включить в стандартную библиотеку. Т.е. вопрос лежит не в области самих языков, а их библиотек: у C++ она побогаче.

satanic-mechanic
()
Ответ на: комментарий от satanic-mechanic

> Не проверяет, только я все равно не вижу смысла задачи. Теоретически можно на C написать нужную функцию и включить в стандартную библиотеку. Т.е. вопрос лежит не в области самих языков, а их библиотек: у C++ она побогаче.

Я тебе другую задачку могу подкинуть: считать матрицу в формате n, m, \n, {n строк по m чисел}. Красиво это можно сделать только с iostream.

gaa ★★
()

а я могу тоже задачку подкинуть, какое минимальное количество памяти нужно для запуска и выполнения примера на С++ и на С... платформа линукс х86?

dimon555 ★★★★★
()
Ответ на: комментарий от satanic-mechanic

> Глупость, я красивей это могу сделать в python/ocaml/lisp.

В контексте дискуссии эти языки отсутствуют.

gaa ★★
()
Ответ на: комментарий от gaa

И опять же вопрос в библиотеке.

Это не задача C сделать это красиво, его задача - сделать быстро. То, что ты сделаешь с iostream и stl будет гораздо медленнее, а если делать быстро, разницы в размере особо не будет.

satanic-mechanic
()
Ответ на: комментарий от dimon555

>> а я могу тоже задачку подкинуть, какое минимальное количество памяти нужно для запуска и выполнения примера на С++ и на С... платформа линукс х86?

Десяток килобайт.

Deleted
()
Ответ на: комментарий от dilmah

>> шикарная игруха King's Valley с 15 уровнями занимала 16 кбайт

Ну да, да... Компиляторы нынче пошли тупые, программисты глупые, а память стоит копейки... Не то что раньше: в 16кбайт лезло 15 уровней, 640кб хватало для любых задач, трава фставляла круче...

=)

Deleted
()
Ответ на: комментарий от Deleted

Только вот эта игра была технически на много порядков проще чем тот же nethack =).

Deleted
()
Ответ на: комментарий от anonymous

>> Ты лучше не задачу уточни, а свой феерический код.

Что именно вам не нравится в моём феерическом коде?

Deleted
()
Ответ на: комментарий от Deleted

cin >> r;

вот эта операция, сколько вызовов выполнит, сколько места на стеке потребуется?

p.s. ответ будет несколько и десяток килобайт :)

dimon555 ★★★★★
()
Ответ на: комментарий от dimon555

>> вот эта операция, сколько вызовов выполнит, сколько места на стеке потребуется?

Возможно даже меньше, чем для scanf =).

Deleted
()
Ответ на: комментарий от dimon555

cin >> r === cin.operator>>(r) == __operator_less_less(&cin, &r)

откуда несколько вызовов и несколько килобайтов?

// IOStreams таки жирные и медленные, я знаю, но это не проблема С++, как языка.

Legioner ★★★★★
()
Ответ на: комментарий от Legioner

Вообще осмысленней давать задачки вроде реализации универсальной библиотеки. Например хеш-таблицы для произвольного типа на C и C++. Это лучше характеризует языки.

Legioner ★★★★★
()
Ответ на: комментарий от dilmah

Да всё где-нибудь есть. И в С++ их куча. Я имею ввиду "с нуля", с использованием абсолютного минимума библиотечных примитивов (ну или сравнение неких общепринято лучших реализаций с обоих сторон).

Legioner ★★★★★
()
Ответ на: комментарий от dilmah

>> это в позиксе есть -- tsearch/hsearch

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

Deleted
()
Ответ на: комментарий от Legioner

>> // IOStreams таки жирные и медленные, я знаю, но это не проблема С++, как языка.

Довольно спорное утверждение. Всё зависит от того, как их использовать. И как эти самые потоки реализованы внутри.

Deleted
()
Ответ на: комментарий от Deleted

>> А как же \t? И вообще, не лучше ль тут употребить isspace?

>Логично, вот обновлённый вариант:

>uint32_t readNum()
>{
> uint32_t r;
> int c;

> cin.exceptions(ios_base::badbit | ios_base::failbit);
> cin >> r;
> c = cin.peek();
> if ((EOF != c) && (!isspace(c)))
> throw (exception());
>
> return r;
>}

iostreams - говно -> решение не годится.

Absurd ★★★
()

Ваня ещё не понял как он сильно заблуждался?

//правда лень тему читать, ещё какую-нибудь глупость из поста тузиков обсасывать

anonymous
()
Ответ на: комментарий от Deleted

>> iostreams - говно -> решение не годится.

>Ваша аргументация достойна уважения 8).

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

Absurd ★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.