Ru-Board.club
← Вернуться в раздел «Прикладное программирование»

» Язык Си Керниган, Ричи

Автор: mymuss
Дата сообщения: 21.08.2003 06:16
Глупый вопрос не совсем в тему (дабы не плодить топики).


Цитата:

For safety, programmers should use the snprintf() interface instead. Unfortunately, this interface is not portable.

(man 3 snprintf (FreeBSD 4.8))

Если честно, я до недавнего времени думал что snprintf() входит в стандарт и использовал ее везде. Выходит, не совсем так Отсюда вопрос, какие распространенные реализации ее не поддерживают?
И вообще, что собственно делать? Может, ее можно найти отдельно?
Автор: Bloody_Nokia_Adept
Дата сообщения: 21.08.2003 17:38
mymuss

Цитата:
Если честно, я до недавнего времени думал что snprintf() входит в стандарт и использовал ее везде.

И правильно делал!

Цитата:
ISO/IEC 9899:1999 (E)


Цитата:
7.19.6.6 The sprintf function
Synopsis
1 #include <stdio.h>
int sprintf(char * restrict s,
const char * restrict format, ...);
Description
2 The sprintf function is equivalent to fprintf, except that the output is written into
an array (specified by the argument s) rather than to a stream. A null character is written
at the end of the characters written; it is not counted as part of the returned value. If
copying takes place between objects that overlap, the behavior is undefined.
Returns
3 The sprintf function returns the number of characters written in the array, not
counting the terminating null character, or a neg ative value if an encoding error occurred.

Так что это проблемы

Цитата:
(man 3 snprintf (FreeBSD 4.8))

а никак не твоего кода, который использует стандартные функции.
Автор: mymuss
Дата сообщения: 21.08.2003 18:04
Bloody_Nokia_Adept

Цитата:
я до недавнего времени думал что snprintf()


Меня в snprintf() прет то, что какой-бы формат ей не подсунули, она возвращает кол-во символов, которое оно бы напечатало, если бы приемник был бесконечным. Это круто.
Автор: Bloody_Nokia_Adept
Дата сообщения: 21.08.2003 18:19
mymuss

Подслеповат стал на старости лет...
snprintf, так snprintf - получайте!

Цитата:
7.19.6.5 The snprintf function
Synopsis
1 #include <stdio.h>
int snprintf(char * restrict s, size_t n,
const char * restrict format, ...);
Description
2 The snprintf function is equivalent to fprintf, except that the output is written into
an array (specified by argument s) rather than to a stream. If n is zero, nothing is written,
and s may be a null pointer. Otherwise, output characters beyond the n-1st are
discarded rather than being written to the array, and a null character is written at the end
of the characters actually written into the array. If copying takes place between objects
that overlap, the behavior is undefined.
Returns
3 The snprintf function returns the number of characters that would have been written
had n been sufficiently large, not counting the terminating null character, or a neg ative
value if an encoding error occurred. Thus, the null-terminated output has been
completely written if and only if the returned value is nonnegative and less than n.

Вот и подтверждение твоих слов в п. 3
Автор: mymuss
Дата сообщения: 22.08.2003 03:25
Bloody_Nokia_Adept
А есть линк на первоисточник? (ISO/IEC 9899:1999 (E) )?
Автор: Bloody_Nokia_Adept
Дата сообщения: 22.08.2003 09:29
mymuss

Цитата:
А есть линк на первоисточник? (ISO/IEC 9899:1999 (E) )?

Вот страница скачки (там есть и другие стандарты )
Клуб программистов Весельчак У
Автор: S_Leha
Дата сообщения: 24.08.2003 21:02
Опять застрял. Дошел до главы "2.9 Побитовые операторы". Здесь я вообще ничего не понял. Конечно сообразить что ...& - это побитовое И... или ... ^ - это побитовое исключающее ИЛИ... можно. Но вот понять как это работает и как это выглядит в тексте, программе я не могу. Мне нужно это как то разжувать, объяснить или показать на примере что ли. Непонятны мне вот эти операторы:
&
|
^
<<
>>
~

На всяк помещу саму главу:
--------------------------------------------------------------------------------------------------------------------------------------------------------------------

2.9 Побитовые операторы
В Си имеются шесть операторов для манипулирования с битами. Их можно применять только к целочисленным операндам, т. е. к операндам типов char, short, int и long, знаковым и беззнаковым.

& - побитовое И
| - побитовое ИЛИ
^ - побитовое исключающее ИЛИ.
<< - сдвиг влево.
>> - сдвиг вправо.
~ - побитовое отрицание (унарный).

Оператор & (побитовое И) часто используется для обнуления некоторой группы разрядов. Например

n = n & 0177;

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

Оператор | (побитовое ИЛИ) применяют для установки разрядов; так,

x = x | SET_ON;

устанавливает единицы в тех разрядах x, которым соответствуют единицы в SET_ON.

Оператор ^ (побитовое исключающее ИЛИ) в каждом разряде установит 1, если соответствующие разряды операндов имеют различные значения, и 0, когда они совпадают.

Поразрядные операторы & и | следует отличать от логических операторов && и ||, которые при вычислении слева направо дают значение истинности. Например, если x равно 1, а y равно 2, то x & y даст нуль, а x && y - единицу.

Операторы << и >> сдвигают влево или вправо свой левый операнд на число битовых позиций, задаваемое правым операндом, который должен быть неотрицательным. Так, x << 2 сдвигает значение x влево на 2 позиции, заполняя освобождающиеся биты нулями, что эквивалентно умножению x на 4. Сдвиг вправо беззнаковой величины всегда сопровождается заполнением освобождающихся разрядов нулями. Сдвиг вправо знаковой величины на одних машинах происходит с распространением знака ("арифметический сдвиг”), на других - с заполнением освобождающихся разрядов нулями ("логический сдвиг”).

Унарный оператор ~ поразрядно "обращает” целое т. е. превращает каждый единичный бит в нулевой и наоборот. Например

x = x & ~077

обнуляет в x последние 6 разрядов. Заметим, что запись x & ~077 не зависит от длины слова, и, следовательно, она лучше, чем x & 0177700, поскольку последняя подразумевает, что x занимает 16 битов. Не зависимая от машины форма записи ~077 не потребует дополнительных затрат при счете, так как ~077 - константное выражение, которое будет вычислено во время компиляции.

Для иллюстрации некоторых побитовых операций рассмотрим функцию getbits(x, p, n), которая формирует поле в n битов, вырезанных из x, начиная с позиции p, прижимая его к правому краю. Предполагается, что 0-й бит - крайний правый бит, а n и p- осмысленные положительные числа. Например, getbits(x,4,3) вернет в качестве результата 4, 3 и 2-й биты значения x, прижимая их к правому краю. Вот эта функция:

/* getbits: получает n бит, начиная с p-й позиции */
unsigned getbits(unsigned x, int p, int n)
{
return (x >> (p+1-n)) & ~(~0 << n);
}

Выражение x >> (р+1-n) сдвигает нужное нам поле к правому краю. Константа ~0 состоит из одних единиц, и ее сдвиг влево на n бит (~0 << n) приведет к тому, что правый край этой константы займут n нулевых разрядов. Еще одна операция побитовой инверсии ~ позволяет получить справа n единиц.


Автор: mymuss
Дата сообщения: 25.08.2003 00:20
S_Leha
У тебя проблемы не с С, а с математикой (тут в каком-то соседнем топике мне еще втирали что программисту математика не нужна).

Я, к сожалению, не знаю какие сейчас есть хорошие книги. Из старого (найденного в своих залежах) могу лишь посоветовать:
1) Касаткин В.Н. Введение в кибернетику. К., Рад. Шк. 1986., (Глава 1,2,3).
2) Лавров С.С. Введение в программирование. М., Наука, 1977 (Глава 3, 11, в остальном книга так себе).
3) Еще есть Том Сван "Освоение Turbo Assembler", Там в Главе 3 очень кратко и доступно объясняется двоичная арифметика. Там буквально 7 страниц, все остальное тебе никогда не пригодится, так что покупать ее не стоит, а вот отксерить у кого-нибудь можно.
4) Ну и практически любые книги по дискретной математике в которых есть глава про булевы функции.
Автор: BugFixer
Дата сообщения: 25.08.2003 12:35
S_Leha

Цитата:
n = n & 0177;


Пусть n == 367 например.

Давай посмотрим x = n & 0xff (255 ):

101101111 // n
011111111 // 0xff
========
001101111 // 0x6f

Итого x == 111 (или 0x6f)

Примерно то же и с остальными - матлогика в полный рост!
Автор: mymuss
Дата сообщения: 25.08.2003 14:33
BugFixer

Цитата:
Примерно то же и с остальными - матлогика в полный рост!

угу...

только одно "но": с матлогикой мало общего... матлогика посложнее будет. как вспомню все эти теории первого порядка... жуть.
Автор: BugFixer
Дата сообщения: 26.08.2003 05:19
mymuss

Цитата:
только одно "но": с матлогикой мало общего... матлогика посложнее будет. как вспомню все эти теории первого порядка... жуть.

Ну хорошо, основы матлогики
Автор: S_Leha
Дата сообщения: 27.08.2003 20:02
if (!valid)
Что это такое?
-----------------------------------------
int x = 1;
int y = 2;
(x && y)
Как этим пользоваться? Я понимаю там: if (x == 1 && y == 2) читается как "Если х = 1 и у = 2 то произойдет то-то...", а как же: if (x && y)
"Если х и у..."?
-----------------------------------------
Автор: FuzzyLogic
Дата сообщения: 27.08.2003 21:50

Цитата:
if (!valid)

Это True/False
Принятая конвенция такова: если переменная равна нулю (битовое представление есть 000...00 (сколько бы там разрядов не было, все нули)), то это ложь(False), всё остальное - истина (True). Если условие внутри оператора if есть истина, то он выполняется, иначе - нет.
Таким образом...возьмем такую конструкцию:
if (valid) { ... }
Если valid есть ноль (ложь/False) то { ... } не выполнится.
Если valid не ноль (истина/True), то { ... } выполняется.

! - логическое отрицание (истина меняется на ложь, и наоборот), то есть
if (!valid)
Если valid есть ноль (ложь) то { ... } выполнится.
Если valid не ноль, то { ... } не выполнится.


Цитата:
(x && y)

Сделай побитово (x && y). получишь результат, а потом опять...ноль/не ноль.
Автор: BugFixer
Дата сообщения: 28.08.2003 06:25
S_Leha

Цитата:
(x && y)

Эта конструкция эквивалентна if (x != 0 && y != 0), (x и y одновременно не равны 0) т.к. в С всякое значение, отличное от 0 есть ИСТИНА (true).

А ! означает отрицание.
!= не равно

FuzzyLogic

Цитата:
Сделай побитово (x && y). получишь результат, а потом опять...ноль/не ноль.

А, извиняюсь, нахрена побитово???

&& - это вам не & ! И не надо путать человека...
Автор: Mickey_from_nsk
Дата сообщения: 28.08.2003 06:44
BugFixer
Насчет алгоритма с вырезанием коментариев - по хорошему надо отслеживать еще и строки, то есть, если встретилась конструкция типа "/*", то ее началом коментария не считать.
Просто сталкивался с этим...
Автор: BugFixer
Дата сообщения: 28.08.2003 07:02
Mickey_from_nsk

Цитата:
Насчет алгоритма с вырезанием коментариев - по хорошему надо отслеживать еще и строки, то есть, если встретилась конструкция типа "/*", то ее началом коментария не считать.

Только в том случае, когда она встретилась внутри комментария, не важно какого, "//" или "/*". Если же не внутри, то строки никакой рояли не играют!
Автор: woffer
Дата сообщения: 28.08.2003 14:06
BugFixer
Имеется ввиду что строки не нужно анализировать
Автор: BugFixer
Дата сообщения: 28.08.2003 15:03
woffer

Цитата:
Имеется ввиду что строки не нужно анализировать

А я когда-нибудь или где-нибудь утверждал, что при разборе комментариев типа "/*"... "*/" надо разбираться с концами строк???

Было следующее:
3.2. Нашли комментарий типа "/*" Всё то же самое, но ищем не конец строки, а последовательность "*/" - "закрывающую скобку" При этом радостно пропускаем комментарии типа "//"и " /*" - они нас ничуть не интересуют!

Это верно даже для ситуации
/*
int a = 0;
...
// */


Несмотря на то, что "*/" стоит вроде в закомментареной строке, тем не менее, комментарий на этом закроется!
Автор: woffer
Дата сообщения: 28.08.2003 15:37
BugFixer
Да ты не нервничай, не о том речь.
Твой алгоритм, споткнется тут:
/*
strcpy(s,"*/");
*/
О том и речь.
Автор: BugFixer
Дата сообщения: 29.08.2003 04:50
woffer
Понял, о чём речь

Добавлено

Цитата:
/*
strcpy(s,"*/");
*/

Только MS VC 6.0 считает, что
/*
strcpy(s,"*/");
*/

подчёркнутое уже не является комментарием, так что... если хочешь, чтоб в строке появилось "*/", пиши strcpy(s,"\*\/");
Автор: S_Leha
Дата сообщения: 09.09.2003 20:37
Что означает оператор sizeof?
Автор: woffer
Дата сообщения: 09.09.2003 22:13
BugFixer
чего ты все запутал Конечно не является. В общем лениво тень на плетень наводить -)
ps:

Цитата:
"\*\/"
*;)

S_Leha

Цитата:
Что означает оператор sizeof?


Цитата:
sizeof (keyword)
__________________
Returns the size, in bytes, of the given expression or type (as
type size_t).

Возвращает в байтах, размер переданного выражения, или типа. (Возврат типа size_t)
Например
sizeof(int) == 2 ;
sizeof(int*20) == 40 ;


Автор: BugFixer
Дата сообщения: 11.09.2003 07:33
woffer

Цитата:
В общем лениво тень на плетень наводить -)

Ну да, надо было написать:
если хочешь, чтоб в строке появилось "*/", и содержимое строки не влияло на комментарии пиши strcpy(s,"\*\/");

Хотя, к сути задачи это уже не относится!
Автор: S_Leha
Дата сообщения: 22.12.2003 19:13
Упражнение 2.3. Напишите функцию htol(s), которая преобразует последовательность шестнадцатеричных цифр, начинающуюся с 0x или 0X, в соответствующее целое. Шестнадцатеричными цифрами являются символы 0...9, a...f, А...F.

С помощью if'ов сделаю так:
1 Запомнить первый символ
2 Проверить второй, и если он 'X' или 'x', сравнить с первым.
3 Если первый '0' то начать последующее преобразование
если нет, очистить переменные и идти дальше по тексту.

Вопрос мой состит в том, как организовать преобразование шестнадцатиричного кода?
Автор: Dimonweb1990
Дата сообщения: 22.12.2003 21:28
А у меня такие проблемы:

Упражнение 1-7
----------------
Напишите программу, которая копирует ввод на вывод, за-
меняя при этом каждую последовательность из одного или более
пробелов на один пробел.

Упражнение 1-10
-----------------
Напишите программу, которая будет печатать слова из фай-
ла ввода, причем по одному на строку.

Упражнение 1-11
----------------
Переделайте программу подсчета слов, используя лучшее
пределение "слова"; считайте, например словом последователь-
ность букв, цифр и апострофов, рачинающуюся с буквы.

Вот еще: мой gcc не понимает \!\! . Как с этим можно справиться?
Автор: pores
Дата сообщения: 09.05.2008 09:48
Вcех с праздником! Ничего, что я реанимировал мертвеца?
Объясните пожалуйста, зачем нужна функция afree? За alloc мне всё понятно! Но afree? Какой-то неопнятный придаток!

Действительно alloc как нельзя лучше справляется со своими обязанностями. Проверяет, хватает ли места? Проверяет. Указателю присваивает адрес элемента, который за этим местом следуем? Присваивает. Возвращает адрес элемента, с которого надо заполнять массив, если мы хотим сохранить в нём отрывок текста? Возвращает.

Что ещё нужно? Непонятно! Спасибо, ваш pores
Автор: mrrex
Дата сообщения: 09.05.2008 11:09
S Leha

Цитата:
А ПМ это где?

Личная почта форума. ссылка
Цитата:
Личный Ящик
вверху страницы.


Цитата:
Упражнение 1-22

читаем файл как поок символов. Поскольку комментарии С допускаются только как
блоки из /* ...*/ вычленить их очень просто. (если не принимать во внимание, что они могут быть и вложенными. Но и тогда нет проблем) С++ допускает комментарии вида //
и до конца строки.

между символами начала комментария /* и //, а также */ пробелов не допускается.


Цитата:
Упражнение 1-19

Опять же читаем файл как символы и находим знак табуляции '/t' а в новый файл вместо найденного табула пишем нужное кол-во пробелов.

Цитата:
Упражнение 1-20

обратная задача.

Да, кстати. EOF - константа - сокращение от END OF FILE. Возникает при достижении конца файла, а не при ошибке ввода/вывода. Т.е. когда входной поток данных закончен и читать больше нечего.



Автор: pores
Дата сообщения: 09.05.2008 12:07
Предыдущему человеку.
Я как-то писал такое упражнение по убиранию из программы комментариев. Вcё сложнее.
Если мы вычленим /* как начало комментария, то вычленим и */ как конец, безусловно. С // как началлом комментария тоже справимся, конец его найдём. Со вложенными комментариями тоже разберёмся. Но!

Есть случаи, когда /* будучи в тексте программы и не будучи внутри комментари, тем мне менее началом комментария не является! И это тоже нужно оговорить! И такие случаи знаете ли, усложняют написание программы. Догадываетесь, о чём я?

...Как же всё-таки быть с функцией afree?


Автор: mrrex
Дата сообщения: 11.05.2008 12:06
pores

Примерчик... а?
Автор: pores
Дата сообщения: 11.05.2008 22:49
Примерчик чего?

Страницы: 123

Предыдущая тема: Delphi Console ShellExecuteEX


Форум Ru-Board.club — поднят 15-09-2016 числа. Цель - сохранить наследие старого Ru-Board, истории становления российского интернета. Сделано для людей.