「C言語の基礎 - 標準入力から安全に文字列を取得する」の版間の差分

ナビゲーションに移動 検索に移動
296行目: 296行目:
       printf("[%zu] %s\n", i, p);
       printf("[%zu] %s\n", i, p);
     }
     }
    return 0;
}
</syntaxhighlight>
<br><br>
== 任意のサイズの1行を読み取る ==
C言語において、可変長は基本的に避けるべきであるが、メモリが許容する限りどのような長さの1行でも読み取る<code>getline</code>関数が存在する。<br>
<u>ただし、使用後は手動でメモリを解放する必要があることに注意する。</u><br>
<br>
以下の例では、改行のみの入力を認めずに、改行を削除している。<br>
最初に確保される領域の大きさを4096文字にしている。<br>
サイズがオーバーする場合は自動的に拡張されるが、事前に多くの文字を入力することが分かっている場合、大きめに設定しておくほうが望ましい。<br>
<syntaxhighlight lang="c">
#include <stdio.h>
#include <stdlib.h>
#define _GNU_SOURCE
int main()
{
    char *buffer = NULL;
    ssize_t length;
    printf("Input: ");
    if ((length = getline(&buffer, &(size_t){4096}, stdin)) == EOF)
    {
      return 1;
    }
    if (buffer[length - 1] == '\n')
    {
      buffer[--length] = '\0';
    }
    printf("Output: %s\n", buffer);
    printf("Length: %zd\n", length);
    free(buffer);
    return 0;
}
</syntaxhighlight>
<br><br>
== 日本語の文字列を文字単位で処理する ==
==== 文字コードについて ====
例えば、マルチバイトにおいて、UTF-8では日本語で使用する1文字には3バイトの領域が必要である。<br>
マルチバイト文字では、連続したバイト列としてとして扱う場合は特に問題無いが、1文字ずつ取り出す場合や文字列長を求める場合は特殊な処理を記述する必要がある。<br>
<br>
==== ロケール設定 ====
マルチバイト文字を正しく扱う場合、以下の関数を使用する。<br>
<syntaxhighlight lang="c++">
#include <locale.h>
setlocale(LC_ALL, "");
</syntaxhighlight>
<br>
==== 使用するデータ型 ====
マルチバイト文字を1文字ずつ区別できるように格納する場合、<code>wchar_t</code>型を使用する。<br>
<code>wchar_t</code>型のリテラルを記述する場合、<code>L'<1文字>'</code>および<code>L"<文字列>"</code>と記述する。<br>
<br>
また、<code>wchar_t</code>型のフォーマット指定子を使用する場合、1文字の時は<code>%lc</code>、文字列の時は<code>%ls</code>と記述する。<br>
<br>
==== サンプルコード ====
以下の例では、入力された文字列を1文字ずつ鍵括弧で括って表示している。<br>
フォーマット指定子において、<code>%n</code>で求めることができるのはバイト長であり文字列長ではないため、ループ条件の変数としては使用できない。<br>
<syntaxhighlight lang="c++">
#include <stdio.h>
#include <wchar.h>
#include <locale.h>
int main()
{
    wchar_t buffer[256] = {0};
    setlocale(LC_ALL, "");
    printf("入力: ");
    if (scanf("%255l[^\n]%*[^\n]", buffer) != 1)
    {
      return 1;
    }
    scanf("%*c");
    printf("出力: ");
    for (wchar_t *c = buffer; *c; c++)
    {
      printf("「%lc」", *c);
    }
    putchar('\n');
   
   
     return 0;
     return 0;

案内メニュー