Подтвердить что ты не робот

Обязательно ли исключать символы табуляции в C и С++?

В C и С++ (и нескольких других языках) горизонтальные табуляторы (ASCII-код 9) в символьных и строковых константах обозначаются в экранированной форме как '\t' и "\t". Тем не менее, я регулярно печатаю символ неэкранированного табулятора в строковых литералах, например, в "A B" (есть TAB в betreen A и B), и, по крайней мере, clang++, похоже, не беспокоит - строка кажется эквивалентны "A\tB". Мне больше нравится версия без возврата, так как длинные отступы с несколькими строками лучше читаются в исходном коде.

Теперь я спрашиваю себя, является ли это вообще законным в C и С++ или просто поддерживается моим компилятором. Насколько переносимыми являются невидимые табуляторы в символьных и строковых константах?

Удивительно, но я не смог найти ответ на этот, казалось бы, простой вопрос: ни с Google, ни со стековым потоком (я просто нашел этот неопределенный вопрос).

4b9b3361

Ответ 1

Да, вы можете включить символ табуляции в строковый или символьный литерал, по крайней мере, согласно С++ 11. Разрешенные символы включают (с моим акцентом):

любой член набора символов источника, кроме двойная кавычка ", обратная косая черта \ или символ новой строки

(из стандарт С++ 11, приложение A.2)

и набор символов источника включает в себя:

символ пробела, управляющие символы, представляющие горизонтальную вкладку, вертикальную вкладку, фид формы и новую строку, а также следующие 91 графический символ

(из стандарт С++ 11, пункт 2.3.1)

ОБНОВЛЕНИЕ: Я только что заметил, что вы спрашиваете о двух разных языках. Для C99 ответ также да. Формулировка отличается, но в основном говорит то же самое:

В символьной константе или строковом литерале члены набора символов выполнения должны быть представлены соответствующими членами исходного набора символов или [...]

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

управляющие символы, представляющие горизонтальную вкладку, вертикальную вкладку и формы.

Ответ 2

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

Так что это портативный. Но это не очень хорошая идея, поскольку читатель не может различать разные типы пробелов. Также широко распространены текстовые редакторы, почтовые программы и т.п. Для переформатирования вкладок, поэтому в ходе таких операций могут быть введены ошибки в программу.

Ответ 3

Если вы введете вкладку во вход, то ваша строка будет содержать буквенный символ табуляции, и он останется символом табуляции - он не будет волшебным образом переведен в \t внутри.

То же самое касается написания кода - вы можете вставлять литеральные символы табуляции в свои строки. Однако учтите следующее:

     T     T     T        <--tab stops
012345012345012345012345
foo1 = 'a\tb';
foo2 = 'a  b'; // pressed tab in the editor
foo3 = 'a  b'; // hit space twice in the editor

Если вы не помещаете курсор в пробелы между a и b и не проверяете, сколько там символов, по существу нет способа определить, есть ли там вкладка или фактические пробелы. Но с версией \t она сразу же отображается как вкладка.

Ответ 4

Когда вы нажимаете клавишу TAB, вы получаете любой код, на который указывает ваша система. Эта кодовая точка может быть или не быть вкладкой в ​​системе, в которой выполняется программа. Когда вы помещаете \t в литерал, компилятор заменяет его соответствующей кодовой точкой для целевой системы. Поэтому, если вы хотите быть уверены, что получаете вкладку в системе, где запускается программа, используйте \t. Это его работа.