質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

90.48%

  • C

    4643questions

    C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

  • エスケープ処理

    19questions

    エスケープ処理とは、一連の文字や一文字に対して、一定の規則に従って別の意味を適用する処理過程です。

<C言語>エスケープ・シーケンスの表記は、続けて書かなくてもありなのでしょうか?

解決済

回答 3

投稿

  • 評価
  • クリップ 0
  • VIEW 550

cadet_study

score 5

 前提・実現したいこと

こんばんは。今回はエスケープ・シーケンス ( / と ESC ... など ) の使用方法(コンソールに出力する際の使用方法)について質問させていただきます。

 発生している問題

エスケープ・シーケンスを printf 関数などで使用する際,改行を実行したいときには
printf("test\n"); のように \n を利用して改行を行うことを学びました。また、その他にも \a や \r を利用することで警告や復帰を行うということも知りました。
このようなこともあり、エスケープ・シーケンスに該当する文字は、「続けて」 \ や ESC[ などの後に表記するものだと思っていました。
しかし、私が使用しているテキスト(新明解シリーズ)に以下のコードがあり、エスケープ・シーケンスの表記が3つの printf 関数にまたがってされており、なぜそのような表記ができるのかが分かりませんでした。

 該当のソースコード

このコードは、コンソール画面の文字の色・背景色を指定するエスケープ・シーケンスである 
ESC[-;-;...m を使用して、色の変更を行うコードです。(~は省略したものです。)

void color(int fg, int bg) {

    int col[] = { ~ };

    printf("ESC[0;");

    if (~) {

        printf("1;");

    }

    printf("%d;%dm", ~);

}

このように、ESC[-;-;...m のエスケープ・シーケンスが複数の printf 関数に分かれて表記されていました。
上記のコードのように、エスケープ・シーケンスの表記はその後に続けて書かなくても1つのエスケープ・シーケンスの表現としてみなされるのでしょうか?それとも、それぞれのエスケープ・シーケンスで別々の箇所で表記することが可能なものや、できないものなどが決まっているのでしょうか?

ご教授して下さると幸いです。宜しくお願いします。

 試したこと

私が visual studio しか持っておらず、この動作を実際に確かめようと思ったのですが、ESC などのエスケープ・シーケンスがサポートされていないため、実行することができませんでした。

エスケープ文字(\aや\n)の実行は行うことができましたが、やはりその printf 内での引数中に書かない場合はエスケープ・シーケンスとして機能せず、存在しないエスケープ・シーケンス表記を利用したとして未定義動作?となり、実行がおかしくなってしまいました。(引数の末尾に \ のみを指定した場合は "定数が 2 行目に続いています" と,エラーになりました。)

また、上記のようなコードが他にあるのかどうかや、別々に書いてもいいのかについて探してみたのですが見つかりませんでした。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 3

checkベストアンサー

+2

例えば "abc" とコンソールに出力し、続けて改行を入れずに "def" と出力すると、コンソールには "abcdef" と出力されます。
ソースコード中では分離していても、実際の出力は連続しているということです。

"ESC[0;" はコンソールに対してのエスケープシーケンスなので、コンソールから見て連続していればいいということです。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/09/02 21:35

    そうなんですか!ありがとうございます!

    キャンセル

  • 2018/09/02 21:46

    ちなみに \ から始まるのは C 言語のエスケープシーケンスなので、これはソースコード中で連続していなければいけません。

    それと「エスケープ表記」と「エスケープシーケンス」はおおよその文脈で同じものです。もっと正確に言うなら「エスケープシーケンスを使用した表記」が「エスケープ表記」です。

    y_waiwai さんの言は、C 言語のエスケープシーケンスとコンソールのエスケープシーケンスを混同してはならないという意味で、単なる言葉の綾だと思います。

    キャンセル

  • 2018/09/02 22:23

    \n や \a などの \ からはじまるエスケープシーケンスは、c言語が定義しているもので、c言語提供類のものは、そのコード内の部分で連続しなければならない決まりなのですね…

    コンソール制御の方は ANSI が定義したエスケープシーケンスで、ANSI 提供類のものはコンソールへの出力時に連続していれば問題ないということですか?

    (知識不足ながら、コンソールを制御するエスケープシーケンスについて調べたところ、ANSI 提供の エスケープシーケンスのものだと知ったので…)

    キャンセル

  • 2018/09/02 22:29

    その認識で合っています。

    私も見落としていたのですが、ANSI エスケープシーケンスのエスケープ文字は pepperleaf のおっしゃる通り ESC の三文字でなく \x1b ですので注意してください。

    キャンセル

  • 2018/09/02 22:42

    そうなのですか… 実はテキストでは \x1b と表記されていて、私がESC でも問題ないと思っていまして勝手に変えてしまいました。ありがとうございます。エスケープシーケンスは \ から指定するのですね!

    少し質問内容と逸れてしまい大変申し訳ないのですが、存在しないエスケープシーケンスを指定した場合は未定義であることは分かったのですが、仮に \ の後に何も指定しない場合も未定義の分類になるのでしょうか?(書き忘れなどが起きてしまった場合とかです…)

    キャンセル

  • 2018/09/02 22:57

    「\"」は「"」を表すエスケープシーケンスです。文字列にダブルクォーテーションマークを入れたい時に使います。
    例えば puts("a\"b") は a"b を出力します。

    なにも指定しないというのは puts("a\") のような呼び出しのことでしょうか?
    だとしたらクォーテーションが閉じていないとみなされてコンパイルエラーになります。

    キャンセル

  • 2018/09/03 00:30

    そうです。 puts("a\") などのような状態のとき,どのようになるのかと思いこの質問をさせていただきました。
    何から何まで詳しく説明して下さり本当に助かりました。
    本当にありがとうございました。

    キャンセル

+2

ちょっと気になったのですが、

   printf("ESC[0;");

これもエスケープシーケンスの一部ですか?
もし、そうだとすると、コンソールに "ESC[0;" の文字が出力されるだけですが、それが期待する結果でしょうか?
昨今のコンソールは、エスケープシーケンスをサポートするものも少ないようですが、サポートする端末に出力しても同様です。
ESC は制御コードとして出力する必要があるので、 "\x1B[0;" とすべきでしょう。 "\x1B" ("\033"でも良いが) は、エスケープコードです。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/09/02 22:47

    お返事ありがとうございます!
    実はテキストの方では \x1b としっかり表記されていまして、私が勝手に ESC でも問題ないと思ってしまっていたため、変えたものを出してしまいました。本当にご指摘ありがとうございます。
    エスケープシーケンスは \ からはじまるもの,ということが原則なのですね。

    キャンセル

  • 2018/09/03 07:31

    > エスケープシーケンスは \ からはじまるもの,
    違います。 他の方も書かれていますが、コンソール制御のためのエスケープは、コード '\x1B'(10進で 27)から始まるものです。
    \ 記号は、文字列のエスケープコード(ただし、言語に依存)、微妙ですが、違うものです。

    キャンセル

  • 2018/09/03 14:29

    つまり、エスケープシーケンスの制御命令は、それぞれの対応するエスケープコードで、一続きに表記することで命令を始める必要があり、コンソールを制御命令をするならコードとして \x1b を表記することで始め、制御文字を表記する命令をしたいなら \~ と指定する必要があるという意味でしょうか? 
    (それぞれの制御指令にはその該当するエスケープコードが割り当てられていて、そのコードを連続して表記することでその制御処理がスタートする,という意味なのかと…)

    キャンセル

  • 2018/09/03 15:38

    もし仮に \xhh (16進文字) の hh を指定しないような,正しくエスケープコードを使用しない場合は、構文エラーになるのでしょうか,それとも未定義動作となるのでしょうか?

    キャンセル

  • 2018/09/03 22:11

    既に、他の方のコメントで解決されたかもしれませんが、、
    \xhh の形式、、 文字列で、\x で始まると次は16進数字(0..F)が来ると期待されます。実際に、Visual Studio2017(*.c)で試したところ、
    数字無し ... エラー
    3桁以上 ... エラーでした。(実際の数値として解釈し、256を越えた場合)
    古い組込み系コンパイラでは、別の動作だったので、最近の仕様なのか、コンパイラ依存なのかは分かりませんが、参考までに。
    なお、\nnn (x 無しは、8進数として解釈されます。ご注意を)

    キャンセル

  • 2018/09/03 23:20

    なるほど…
    詳しいご説明ありがとうございました。

    キャンセル

+1

文字列表記時のエスケープ表記と、エスケープシーケンスは別のものです。
一緒くたにしても意味ないですw

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/09/02 21:32

    回答ありがとうございます。エスケープ表記とエスケープ・シーケンスがどのように違うのか具体的に教えてください。

    キャンセル

  • 2018/09/02 21:46

    エスケープ表記は、文字列を書くときに、文字で表せないコントロールコードを表現するために使われる便宜上の書き方です。改行コードは\n バックスペースは \b タブは\t と決められてますんで、これを分割してしまうと意味が通らなくなります。

    エスケープシーケンスは、ターミナルに表示するときに、そのターミナルに特別のことをさせたいときに送る命令列のことをいいます。
    文字の色を変える、とか、画面を消去、カーソル位置を移動させる、とかとか。
    まーこいつは、ターミナルが、その命令列をその順番に受信できればいいだけなので、分割しようがなにしようがOKですねー

    キャンセル

  • 2018/09/02 21:50

    私の回答のコメントにも書きましたが、バックスラッシュから始まるのもエスケープシーケンスです。

    キャンセル

  • 2018/09/02 21:58

    まあ、同じ呼び方もするってのもあって、まぎらわしいですわな。

    キャンセル

  • 2018/09/02 22:04

    エスケープ文字を使った文字列がエスケープシーケンスです。特に紛らわしくはないと思います。

    逆に「エスケープ表記」「エスケープシーケンス」と自作の方言で使い分ける方が紛らわしいと思います。

    言葉の綾かと思いましたが、回答の核の部分が間違っていると判断できるため低評価します。

    キャンセル

  • 2018/09/02 22:35

    お返事ありがとうございます!
    \ からはじまるエスケープシーケンス(エスケープ表記)は、\ とそれに続く文字が該当するコードで連続することで1つの制御コードを表すことができるため、分割することができず、コンソール制御のエスケープシーケンス(ANSI系)は、コンソールへの出力で順番に受けることができればいいため,上記のようなコードが許されるということなのでしょうか?

    キャンセル

  • 2018/09/02 22:57

    そゆことですね

    イマドキの人はコンソールと言ってもコマンドプロンプトとか黒いウィンドウを思い浮かべるだろうけど、その昔、コンピュータがデータセンタにしかなかった頃は、電話回線やら専用線でつながったようなコンソール装置、ターミナル装置というキカイでして、その表示を色々弄るためにエスケープシーケンスを駆使していろいろやったもんで、それでエロゲをつくったやつとかもいたとかいないとかw

    キャンセル

  • 2018/09/03 00:36

    そうなのですか… 
    コンソールといえばコマンドプロンプトとばかり思っていましたけど、そのようなことがあったのですね…
    色々と詳しい解説をして下さり本当に助かりました。
    本当にありがとうございました。

    キャンセル

同じタグがついた質問を見る

  • C

    4643questions

    C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

  • エスケープ処理

    19questions

    エスケープ処理とは、一連の文字や一文字に対して、一定の規則に従って別の意味を適用する処理過程です。

  • トップ
  • Cに関する質問
  • <C言語>エスケープ・シーケンスの表記は、続けて書かなくてもありなのでしょうか?