<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>C言語 on AIによる技術記事 備忘録</title><link>https://ai.hack-le.com/tags/c%E8%A8%80%E8%AA%9E/</link><description>Recent content in C言語 on AIによる技術記事 備忘録</description><generator>Hugo -- gohugo.io</generator><language>ja</language><lastBuildDate>Sat, 22 Aug 2026 10:21:59 +0900</lastBuildDate><atom:link href="https://ai.hack-le.com/tags/c%E8%A8%80%E8%AA%9E/index.xml" rel="self" type="application/rss+xml"/><item><title>C言語のstrcmp関数の完全ガイド – 戻り値の理解と注意点</title><link>https://ai.hack-le.com/c%E8%A8%80%E8%AA%9E%E3%81%AEstrcmp%E9%96%A2%E6%95%B0%E3%81%AE%E5%AE%8C%E5%85%A8%E3%82%AC%E3%82%A4%E3%83%89-%E6%88%BB%E3%82%8A%E5%80%A4%E3%81%AE%E7%90%86%E8%A7%A3%E3%81%A8%E6%B3%A8%E6%84%8F%E7%82%B9/</link><pubDate>Fri, 05 Sep 2025 00:20:47 +0900</pubDate><guid>https://ai.hack-le.com/c%E8%A8%80%E8%AA%9E%E3%81%AEstrcmp%E9%96%A2%E6%95%B0%E3%81%AE%E5%AE%8C%E5%85%A8%E3%82%AC%E3%82%A4%E3%83%89-%E6%88%BB%E3%82%8A%E5%80%A4%E3%81%AE%E7%90%86%E8%A7%A3%E3%81%A8%E6%B3%A8%E6%84%8F%E7%82%B9/</guid><description>&lt;h2 id="strcmp関数の基本仕様"&gt;strcmp関数の基本仕様&#10;&lt;/h2&gt;&lt;p&gt;C言語の&lt;code&gt;strcmp&lt;/code&gt;関数は文字列比較を行う標準ライブラリ関数である。この関数は&lt;code&gt;string.h&lt;/code&gt;ヘッダーで定義されており、2つの文字列を辞書順で比較して整数値を返す。関数のプロトタイプは&lt;code&gt;int strcmp(const char *s1, const char *s2)&lt;/code&gt;となっている。&lt;/p&gt;&#10;&lt;p&gt;戻り値の仕様が特徴的で、多くのプログラマーが混乱する原因となっている。戻り値は以下の3つのパターンに分類される。まず、文字列が等しい場合は0を返す。次に、第一引数が第二引数より辞書順で前にある場合は負の値を返す。最後に、第一引数が第二引数より辞書順で後にある場合は正の値を返す。&lt;/p&gt;&#10;&lt;p&gt;この仕様は一見直感的でないように思えるが、数学的な比較演算子の考え方と一致している。つまり、&lt;code&gt;s1 - s2&lt;/code&gt;の結果を表現していると考えることができる。等しければ差は0、s1が小さければ負、s1が大きければ正という論理である。&lt;/p&gt;&#10;&lt;h2 id="具体的な使用例とコード実装"&gt;具体的な使用例とコード実装&#10;&lt;/h2&gt;&lt;p&gt;実際の使用例を通じて&lt;code&gt;strcmp&lt;/code&gt;の動作を確認してみよう。以下のコードは基本的な文字列比較を示している。&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;#include &amp;lt;stdio.h&amp;gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;#include &amp;lt;string.h&amp;gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;int main() {&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; char str1[] = &amp;#34;apple&amp;#34;;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; char str2[] = &amp;#34;banana&amp;#34;;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; char str3[] = &amp;#34;apple&amp;#34;;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; char str4[] = &amp;#34;application&amp;#34;;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; int result1 = strcmp(str1, str2); // &amp;#34;apple&amp;#34; vs &amp;#34;banana&amp;#34;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; int result2 = strcmp(str1, str3); // &amp;#34;apple&amp;#34; vs &amp;#34;apple&amp;#34;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; int result3 = strcmp(str2, str1); // &amp;#34;banana&amp;#34; vs &amp;#34;apple&amp;#34;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; int result4 = strcmp(str1, str4); // &amp;#34;apple&amp;#34; vs &amp;#34;application&amp;#34;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; printf(&amp;#34;apple vs banana: %d\n&amp;#34;, result1); // 負の値&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; printf(&amp;#34;apple vs apple: %d\n&amp;#34;, result2); // 0&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; printf(&amp;#34;banana vs apple: %d\n&amp;#34;, result3); // 正の値&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; printf(&amp;#34;apple vs application: %d\n&amp;#34;, result4); // 負の値&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; return 0;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;}&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;このコードを実行すると、&lt;code&gt;result1&lt;/code&gt;と&lt;code&gt;result4&lt;/code&gt;は負の値、&lt;code&gt;result2&lt;/code&gt;は0、&lt;code&gt;result3&lt;/code&gt;は正の値となる。重要な点は、具体的な数値に依存してはいけないということである。実装によって返される具体的な値は異なる可能性があるため、符号のみを判定に使用するべきである。&lt;/p&gt;&#10;&lt;p&gt;条件分岐での使用例も示しておこう。文字列が等しいかどうかを判定する場合、戻り値が0であることを明示的に確認する必要がある。&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;if (strcmp(str1, str3) == 0) {&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; printf(&amp;#34;文字列は等しい\n&amp;#34;);&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;} else {&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; printf(&amp;#34;文字列は異なる\n&amp;#34;);&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;}&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;if (strcmp(str1, str2) &amp;lt; 0) {&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; printf(&amp;#34;str1はstr2より辞書順で前にある\n&amp;#34;);&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;}&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="重要な注意点とトラブルシューティング"&gt;重要な注意点とトラブルシューティング&#10;&lt;/h2&gt;&lt;p&gt;&lt;code&gt;strcmp&lt;/code&gt;を使用する際に陥りがちな問題がいくつか存在する。最も深刻なのはNULLポインタを渡した場合の動作である。&lt;code&gt;strcmp&lt;/code&gt;はNULLチェックを行わないため、NULLポインタを渡すとセグメンテーションフォルトが発生する。&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;char *str1 = NULL;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;char *str2 = &amp;#34;hello&amp;#34;;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;// strcmp(str1, str2); // これは実行時エラーを引き起こす&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;// 安全な実装例&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;if (str1 != NULL &amp;amp;&amp;amp; str2 != NULL) {&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; int result = strcmp(str1, str2);&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; // 比較処理&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;} else {&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; // NULLポインタの処理&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;}&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;大文字小文字の区別も重要な注意点である。&lt;code&gt;strcmp&lt;/code&gt;は大文字と小文字を異なる文字として扱うため、&lt;code&gt;strcmp(&amp;quot;Hello&amp;quot;, &amp;quot;hello&amp;quot;)&lt;/code&gt;は0を返さない。大文字小文字を無視した比較が必要な場合は、POSIX環境では&lt;code&gt;strcasecmp&lt;/code&gt;関数を使用できる。&lt;/p&gt;&#10;&lt;p&gt;文字列長が異なる場合の動作も理解しておく必要がある。短い文字列の方が長い文字列より「小さい」と判定される。例えば、&lt;code&gt;strcmp(&amp;quot;abc&amp;quot;, &amp;quot;abcdef&amp;quot;)&lt;/code&gt;は負の値を返す。これは短い文字列の終端文字（NULL文字）が、長い文字列の対応する文字より小さいと判定されるためである。&lt;/p&gt;&#10;&lt;p&gt;マルチバイト文字を含む文字列の比較では、&lt;code&gt;strcmp&lt;/code&gt;はバイト単位での比較を行うため、期待した結果にならない場合がある。日本語などを含む文字列を適切に比較するには、ロケールを考慮した&lt;code&gt;strcoll&lt;/code&gt;関数の使用を検討すべきである。&lt;/p&gt;&#10;&lt;h2 id="関連関数と使い分け"&gt;関連関数と使い分け&#10;&lt;/h2&gt;&lt;p&gt;&lt;code&gt;strcmp&lt;/code&gt;以外にも文字列比較に関連する関数が存在する。用途に応じて適切な関数を選択することが重要である。&lt;/p&gt;&#10;&lt;p&gt;&lt;code&gt;strncmp&lt;/code&gt;関数は指定した文字数まで比較を行う。プロトタイプは&lt;code&gt;int strncmp(const char *s1, const char *s2, size_t n)&lt;/code&gt;である。部分的な文字列比較や、長大な文字列の前方部分のみを比較したい場合に有用である。&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;char str1[] = &amp;#34;application&amp;#34;;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;char str2[] = &amp;#34;apple&amp;#34;;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;int result = strncmp(str1, str2, 5); // 最初の5文字を比較&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;// &amp;#34;appli&amp;#34; vs &amp;#34;apple&amp;#34; となり、結果は負の値&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;code&gt;strcasecmp&lt;/code&gt;関数（POSIX環境）は大文字小文字を無視した比較を行う。Web開発やファイル名の比較など、大文字小文字の違いを無視したい場面で活用される。&lt;/p&gt;&#10;&lt;p&gt;&lt;code&gt;strcoll&lt;/code&gt;関数は現在のロケール設定に基づいた文字列比較を行う。国際化されたアプリケーションで、各国の文字順序規則に従った比較が必要な場合に使用される。&lt;/p&gt;&#10;&lt;p&gt;これらの関数を適切に使い分けることで、より堅牢で国際化対応された文字列処理が実現できる。特に、ユーザー入力を扱うアプリケーションでは、想定外の文字列に対する適切な処理が重要となる。&lt;/p&gt;&#10;</description></item></channel></rss>