Модераторы: bsa
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Символ '\b' - поведение зависит от ситуации... 
V
    Опции темы
Compositum
  Дата 28.5.2011, 14:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Senior developer
**


Профиль
Группа: Awaiting Authorisation
Сообщений: 430
Регистрация: 6.1.2008
Где: Санкт-Петербург

Репутация: нет
Всего: 1



Возможно кому-то из новичков (таких как я), изложенная ниже информация будет интересна...

Герберт Шилдт в "Справочник по Cчетвёртое издание, на стр. 62, в табл. 2.2 (Специальные символьные константы) пишет, что символ \b - это удаление предыдущего символа. Однако, как показывает практика, на самом деле результат использования этого символа будет в различных ситуациях разный...
Пример 1:
Код

#include<stdio.h>
main(){
    printf("abcdef");
    putchar('\b');
    putchar('\b');
    putchar('\b');
//    printf("ghk");
//    putchar('\n');
}

Результат:
Цитата

bush@mycomp:~/training/c/c89/mytests$ gcc bs.c -o bs.out
bush@mycomp:~/training/c/c89/mytests$ ./bs.out 
abcbush@mycomp:~/training/c/c89/mytests$

 Результат тот, который я и ожидал получить, но... Не устраивает меня то, как это выглядит - нужно, чтобы присутствовал переход на новую строку после вывода результата. Давайте попытаемся это исправить...
Пример 2:
Код

#include<stdio.h>
main(){
    printf("abcdef");
    putchar('\b');
    putchar('\b');
    putchar('\b');
//    printf("ghk");
    putchar('\n');
}

Я всего лишь добавил переход на новую строку, но результат уже не тот, что я ожидаю... Результат:
Цитата

bush@mycomp:~/training/c/c89/mytests$ gcc bs.c -o bs.out
bush@mycomp:~/training/c/c89/mytests$ ./bs.out 
abcdef
bush@mycomp:~/training/c/c89/mytests$

Как видим,  в данном случае символы \b не сделали своего дела, словно их и не было вовсе...
Давайте попробуем удалить предыдущие символы, с последующей записью новых значений, причём новых будет меньше, чем удаляемых и в завершении мы не будем переходить на новую строку:
Пример 3:
Код

#include<stdio.h>
main(){
    printf("abcdef");    
    putchar('\b');
    putchar('\b');
    putchar('\b');    
    printf("gh");
//    putchar('\n');
}

Результат:
Цитата

bush@mycomp:~/training/c/c89/mytests$ gcc bs.c -o bs.out
bush@mycomp:~/training/c/c89/mytests$ ./bs.out 
abcghbush@mycomp:~/training/c/c89/mytests$

Как видим - было удалено три последних символа и вместо них записано два новых. Однако что произойдёт, если в таком примере всё же выполнить переход на новую строку?
Пример 4:
Код

#include<stdio.h>
main(){
    printf("abcdef");
    putchar('\b');
    putchar('\b');
    putchar('\b');
    printf("gh");
    putchar('\n');
}

Я ожидаю получить в терминале такой результат: abcgh, т.е., согласно Шилдту, должно быть удалено три последних символа (def) и вместо них записаны два новых (gh).
Однако по факту получаю такой результат:
Цитата

bush@mycomp:~/training/c/c89/mytests$ gcc bs.c -o bs.out
bush@mycomp:~/training/c/c89/mytests$ ./bs.out 
abcghf

Ощущение такое, что в этом случае происходит смещение курсора на предыдущую позицию, без затирания уже существующего в этой позиции символа... Затирание происходит только при последующем вводе символов, причём сколько будет введено - столько и будет затёрто старых. На всякий случай делаю ещё одну проверку...
Пример 5:
Код

#include<stdio.h>
main(){
    printf("abcdef");
    putchar('\b');
    putchar('\b');
    putchar('\b');
    printf("ghk");
    putchar('\n');
}

Результат:
Цитата

bush@mycomp:~/training/c/c89/mytests$ gcc bs.c -o bs.out
bush@mycomp:~/training/c/c89/mytests$ ./bs.out 
abcghk

Похоже, что моё предположение оказалось верным.

Интересна ещё одна ситуация...
Пример 6:
Код

#include<stdio.h>
main(){
    printf("abcd\nef51");
    putchar('\b');
    putchar('\b');
    putchar('\b');
    putchar('\b');
    putchar('\b');
    putchar('\b');    
    printf("ghk");
    putchar('\n');
}

Результат:
Цитата

bush@mycomp:~/training/c/c89/mytests$ gcc bs.c -o bs.out
bush@mycomp:~/training/c/c89/mytests$ ./bs.out 
abcd
ghk1

Как видим, действие \b ограничено рамками одной строки.

Т.о. в различных ситуациях символ \b ведёт себя по разному. Если обобщить всё изложенное выше, то получится следующее:

1. Действие символа \b не может выйти за рамки строки, в которой он присутствует (т.е. нельзя поставив подряд несколько символов \b удалить символы и из предыдущей строки).
2. Если строка не завершена (в конце строки отсутствует символ \n), то символы \b выполняют своё прямое предназначение - т.е. удаляют предыдущие символы, по одному для каждого \b.
3. Если строка завершена (т.е. в конце присутствует символ \n), то символы \b не удаляют предыдущие символы, а всего лишь перемещают курсор на предыдущую позицию. При этом, если в дальнейшем будет производиться вывод символов - они начнут вставляться с текущей позиции курсора, перезаписав столько символов, сколько будет введено новых.

Заключение:
На мой взгляд, подобное поведение символа \b Шилдту всё же следовало подробно описать в своём справочнике, тем более, что на нём крупными буквами написано: "Полный справочник"...

P.S. я пробовал эти же действия производить и со строковыми переменными до того, как выводить их содержимое на консоль, например такой вариант:
Код

#include<stdio.h>
main(){
    char text[] = "Hello Windows\n\b\b\b\b\b\b\b\bLinux!";
    printf("%s\n", text);    
}

Однако результат использования \b зависит всё от тех же правил, которые я обозначил в первом сообщении...

Это сообщение отредактировал(а) Compositum - 28.5.2011, 14:34
PM   Вверх
borisbn
Дата 28.5.2011, 14:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 4875
Регистрация: 6.2.2010
Где: Ростов-на-Дону

Репутация: 21
Всего: 135



Compositum, ты отлично провёл исследование, но, если уж ты такой скурпулёзный, то не помешало бы заглянуть в стандарт, а не в популярную книгу.
Цитата

5.2.2 Character display semantics
...
\b (backspace)Moves the active position to the previous position on the current line. If
the active position is at the initial position of a line, the behavior of the display
device is unspecified.

А Шилдт с одной стороны не прав, говоря
Цитата(Compositum @  28.5.2011,  14:05 Найти цитируемый пост)
символ \b - это удаление предыдущего символа

т.к. в стандарте сказано, что \b moves the active position
а с другой стороны он не обязан был проверять это на всех компиляторах, да ещё и на всех вариантах сборки линукса

И ещё, найди профиль участника shaggie и посмотри его подпись  smile 

Это сообщение отредактировал(а) borisbn - 28.5.2011, 14:58


--------------------
Женщины отличаются от программистов тем, что у них чары состоят из стрингов
PM MAIL Jabber   Вверх
Compositum
Дата 28.5.2011, 15:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Senior developer
**


Профиль
Группа: Awaiting Authorisation
Сообщений: 430
Регистрация: 6.1.2008
Где: Санкт-Петербург

Репутация: нет
Всего: 1



Цитата(borisbn @ 28.5.2011,  14:58)
Compositum, ты отлично провёл исследование, но, если уж ты такой скурпулёзный, то не помешало бы заглянуть в стандарт, а не в популярную книгу.

Обозначенный стандарт у меня отсутствует (в интернете не нашёл) и продаётся буржуями за немалые деньги, а книга (русский перевод) мною уже куплена. Кроме того, на обложке обозначенной книги написано: "Полное описание языка C, включая как его первоначальный стандарт C89, так и новые средства, добавленные в C99". Слово "полное" я воспринимаю буквально, т.е. исчерпывающее, содержащее всю информацию, касающуюся C89 и C99.
Т.о. получаю информацию из тех источников, которые имею под рукой.

п.с. За цитату из стандарта - спасибо.

Это сообщение отредактировал(а) Compositum - 28.5.2011, 15:35
PM   Вверх
volatile
Дата 29.5.2011, 01:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2107
Регистрация: 7.1.2011

Репутация: 16
Всего: 85



Compositumуправляющие символы, вообще-то к языку (какому бы ни было) не относятся.
Например \t - табуляция. Это просто символ с кодом 9. Оператор вывода просто посылает этот символ на вывод в ВСЁ!
А как его интерпретирует принимающая сторона, (т.е. консоль, файл, или устройство) зависит от этого устройства. В данном случае от ОС.
Символ \b это точно такой-же символ только с кодом 8.
Можете перенаправить в файл и посмотреть в hex вьюере.  smile



PM MAIL   Вверх
borisbn
Дата 29.5.2011, 08:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 4875
Регистрация: 6.2.2010
Где: Ростов-на-Дону

Репутация: 21
Всего: 135



Цитата(Compositum @  28.5.2011,  15:14 Найти цитируемый пост)
Обозначенный стандарт у меня отсутствует (в интернете не нашёл) и продаётся буржуями за немалые деньги

http://www.open-std.org/JTC1/SC22/WG21/doc.../2005/n1905.pdf - совершенно бесплатно и легально.
Только учти, что стандарт - стандартом, а не все компиляторы его полностью поддерживают. Есть моменты, когда MSVC действует полностью по стандарту, а gcc - нет. Есть - когда наоборот... Так что "доверяй, но проверяй" © smile

Это сообщение отредактировал(а) borisbn - 29.5.2011, 08:48


--------------------
Женщины отличаются от программистов тем, что у них чары состоят из стрингов
PM MAIL Jabber   Вверх
Compositum
Дата 29.5.2011, 09:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Senior developer
**


Профиль
Группа: Awaiting Authorisation
Сообщений: 430
Регистрация: 6.1.2008
Где: Санкт-Петербург

Репутация: нет
Всего: 1



Цитата(borisbn @ 29.5.2011,  08:46)
http://www.open-std.org/JTC1/SC22/WG21/doc.../2005/n1905.pdf - совершенно бесплатно и легально.
Только учти, что стандарт - стандартом, а не все компиляторы его полностью поддерживают. Есть моменты, когда MSVC действует полностью по стандарту, а gcc - нет. Есть - когда наоборот... Так что "доверяй, но проверяй" © smile

Но ведь мой топик не о C++, а о C (это указано в наименовании приведённого мною справочника)... И стандарт соответственно нужен не по C++... smile У тебя есть такая же ссылка на pdf-файл, но по стандарту по языка C (ANSI X3.159-1989 и ISO/IEC 9899:1990)? Если есть линк и по ISO 9899:1999 - это было бы вообще чудесно... Я по гуглу попадаю только на платные варианты (((

п.с. за pdf-файл по стандарту C++ так же спасибо - после C я возьмусь за C++. Однако хотелось бы уточнить, что это за документ? Номер стандарта в нём не прописан, однако на первой же странице указано это:
Цитата

Note: this is an early draft. It’s known to be incomplet and incorrekt, and it has lots of bad for matting.

Несколько смущает, что уже с первой страницы присутствуют яркие грамматические ошибки (заметил их даже не смотря на своё незнание английского): "incomplete and incorrect"(с)... Вряд ли оригинал стандарта содержал бы такие промахи... ???
Далее:
Цитата

C++ is a general purpose programming language based on the C programming language as described in ISO/IEC
9899:1990 Programming languages - C (1.2).

Т.е. этот pdf-файл всё таки не стандарт?

Добавлено @ 09:49
Цитата(volatile @ 29.5.2011,  01:26)
Compositumуправляющие символы, вообще-то к языку (какому бы ни было) не относятся.
Например \t - табуляция. Это просто символ с кодом 9. Оператор вывода просто посылает этот символ на вывод в ВСЁ!
А как его интерпретирует принимающая сторона, (т.е. консоль, файл, или устройство) зависит от этого устройства. В данном случае от ОС.
Символ \b это точно такой-же символ только с кодом 8.
Можете перенаправить в файл и посмотреть в hex вьюере.  smile

Я понимаю, что \b - это обычный символ, однако предполагал, что существует чётко определённое для него поведение, которое должно быть единообразным и реализовано всеми, без самодеятельности. 

п.с. volatile,  borisbn - я искренне благодарен вам за ваши ответы и прошу не расценивать моё дотошное отношение к вопросам как придирки - на самом деле я просто стараюсь до конца разобраться в интересующих меня вопросах. Вопрос по \b для меня закрыт, т.к. получил от вас ответ на эту тему. Сейчас топик плавно перешёл к pdf-файлам стандартов C/C++, которые на самом деле мне тоже очень важны, поскольку учиться по книжкам это одно, но иметь стандарт под рукой просто обязан каждый программист (хотя бы потому, что книги переводятся русскими и не всегда корректно, да и оригиналы книг не всегда свободны от ошибок... А когда к ошибкам автора добавляются и ошибки переводчиков - сие не есть приятный момент...).

Это сообщение отредактировал(а) Compositum - 29.5.2011, 10:13
PM   Вверх
borisbn
Дата 29.5.2011, 14:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 4875
Регистрация: 6.2.2010
Где: Ростов-на-Дону

Репутация: 21
Всего: 135



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


--------------------
Женщины отличаются от программистов тем, что у них чары состоят из стрингов
PM MAIL Jabber   Вверх
volatile
Дата 29.5.2011, 18:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2107
Регистрация: 7.1.2011

Репутация: 16
Всего: 85



Цитата(Compositum @  29.5.2011,  09:45 Найти цитируемый пост)
Несколько смущает, что уже с первой страницы присутствуют яркие грамматические ошибки (заметил их даже не смотря на своё незнание английского): "incomplete and incorrect"(с)... Вряд ли оригинал стандарта содержал бы такие промахи... ???

Ну в данном случае, это юмор. Подобным образом у нас употребляют слово "очепятка"

Код

Note: this is an early draft. It’s known to be incomplet and incorrekt, and it has lots of bad formatting.

В слове "bad formatting" - специально сделано две ошибки форматирования.

Смысловой перевод. "В этом документе очень много очепяток и нeПРАВИЛЬНОГО фОРМАТИРОВАНИЯ."
ну где-то ~~~ так smile 
Нужно ценить юмор! Кроме того, составители пытаются быть честными, до конца.
На самом деле опечаток там не так много...  
PM MAIL   Вверх
Compositum
Дата 29.5.2011, 20:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Senior developer
**


Профиль
Группа: Awaiting Authorisation
Сообщений: 430
Регистрация: 6.1.2008
Где: Санкт-Петербург

Репутация: нет
Всего: 1



ясно, спасибо smile
PM   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "C/C++: Для новичков"
JackYF
bsa

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, JackYF, bsa.

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Для новичков | Следующая тема »


 




[ Время генерации скрипта: 0.1130 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.