error: missing terminating " character の原因と直し方
文字列リテラルを開いたダブルクォートを閉じ忘れたときに出るエラーです。1行の途中で誤って別の記号を書いてしまった場合にも起きます。
エラーメッセージの読み方
main.c:4:12: error: missing terminating " character
main.c- ファイル名
4- 行番号
12- 列番号 — この位置でgccが構文解析に失敗しました
missing terminating " character- 内容 — 期待していたもの、または受け付けられなかったもの
このエラーが出る典型パターン
パターン1
1 #include <stdio.h> 2 3 int main(void) { 4 printf("hello ); ^ 5 return 0; 6 }
開いたダブルクォートは同じ行の中で閉じる必要があります。閉じ忘れると、行末までが1つの未完成な文字列として扱われます。
直し方: "hello を "hello" にします。
パターン2
1 #include <stdio.h> 2 3 int main(void) { 4 printf("score: %d\n ); ^ 5 return 0; 6 }
書式指定子や改行を含む文字列でも、閉じクォートを忘れれば同じエラーになります。
直し方: "score: %d\n を "score: %d\n" にします。
パターン3
1 #include <stdio.h> 2 3 int main(void) { 4 char *msg = "done ; ^ 5 printf("%s\n", msg); 6 return 0; 7 }
変数への代入でも同様です。printfの引数だけの問題ではありません。
直し方: "done を "done" にします。
パターン4
1 #include <stdio.h> 2 3 int main(void) { 4 char name[] = "Al ; ^ 5 printf("%s\n", name); 6 return 0; 7 }
配列の初期化子として使う文字列でも同じ規則です。閉じクォートを忘れると未完成な文字列として扱われます。
直し方: "Al を "Al" にします。
パターン5
1 #include <stdio.h> 2 3 int main(void) { 4 puts("bye ); ^ 5 return 0; 6 }
putsの引数でも同様です。printf以外の関数でも文字列リテラルの規則は変わりません。
直し方: "bye を "bye" にします。
よくある誤解
文字列の途中で改行しても自動的に閉じられるわけではありません。Cの文字列リテラルは同じ行の中でダブルクォートを閉じる必要があり、複数行にまたがる文字列を書きたい場合は連結や\nの利用など別の方法が必要です。
実務での勘所
文字列リテラルの途中で改行を許さないのは、文字列を1つの行の中で完結させるという古くからの設計です。ただし例外が1つあり、行の末尾にバックスラッシュを置いてすぐ改行すると、プリプロセッサがコンパイラに渡す前にその改行そのものを消してしまう(行の連結)ため、見た目は複数行でも実際には1行の文字列として解釈されます。この行連結の仕組みは文字列リテラルに限らずコード全体に働くため、意図せず行末に\を書いてしまうと、次の行が直前の行の続きとして解釈されるという別のトラブルの原因にもなります。