Code Fix

初級

int と文字列リテラルの比較で出るエラーの原因

int型の変数をダブルクォートの文字列リテラル(例: "20")と== で比較しようとしたときに出るエラーです。文字列リテラルはconst char*型であり、int型とは根本的に比較できません。

エラーメッセージの読み方

main.cpp:4:13: error: ISO C++ forbids comparison between pointer and integer [-fpermissive]
main.cpp
ファイル名
4
行番号
13
列番号 — この位置でg++が構文解析に失敗しました
ISO C++ forbids comparison between pointer and integer [-fpermissive]
内容 — 期待していたもの、または受け付けられなかったもの

このエラーが出る典型パターン

パターン1

 1  #include <iostream>
 2  int main() {
 3      int age = 20;
 4      if (age == "20") {
                     ^
 5          std::cout << "match" << std::endl;
 6      } else {
 7          std::cout << "no match" << std::endl;
 8      }
 9      return 0;
10  }
main.cpp:4:13: error: ISO C++ forbids comparison between pointer and integer [-fpermissive]

"20"はconst char*型(文字列へのポインタ)であり、int型のageとは比べられません。数値と比較するには数値リテラルの20を使います。

直し方: "20" を 20 にします。

この問題を解いてみる →

広告
広告スロット(未設定)

パターン2

 1  #include <iostream>
 2  int main() {
 3      int code = 7;
 4      if (code == "7") {
                     ^
 5          std::cout << "ok" << std::endl;
 6      }
 7      return 0;
 8  }
main.cpp:4:14: error: ISO C++ forbids comparison between pointer and integer [-fpermissive]

見た目が同じ「7」でも、ダブルクォートで囲むと文字列(ポインタ)になり、int型とは比較できない別の型になります。

直し方: "7" を 7 にします。

この問題を解いてみる →

パターン3

 1  #include <iostream>
 2  int main() {
 3      int level = 1;
 4      if (level == "1") {
                      ^
 5          std::cout << "beginner" << std::endl;
 6      }
 7      return 0;
 8  }
main.cpp:4:15: error: ISO C++ forbids comparison between pointer and integer [-fpermissive]

Pythonなどでは単にfalseになる比較でも、C++は型として比較できないためコンパイルの段階で止まります。

直し方: "1" を 1 にします。

この問題を解いてみる →

パターン4

 1  #include <iostream>
 2  int main() {
 3      int total = 100;
 4      if (total == "100") {
                       ^
 5          std::cout << "full" << std::endl;
 6      }
 7      return 0;
 8  }
main.cpp:4:15: error: ISO C++ forbids comparison between pointer and integer [-fpermissive]

"100"はconst char*型なので、int型のtotalとは比べられません。

直し方: "100" を 100 にします。

この問題を解いてみる →

パターン5

 1  #include <iostream>
 2  int main() {
 3      int id = 5;
 4      if (id == "5") {
                   ^
 5          std::cout << "found" << std::endl;
 6      }
 7      return 0;
 8  }
main.cpp:4:12: error: ISO C++ forbids comparison between pointer and integer [-fpermissive]

見た目が同じ「5」でも、ダブルクォートで囲むと比較できない別の型になります。

直し方: "5" を 5 にします。

この問題を解いてみる →

よくある誤解

Pythonなど一部の言語では数値と文字列を比較すると単に false になりますが、C++はそもそも型として比較できないためコンパイルの段階で止まります。「実行すれば一致しないだけ」ではなく、実行にすら至りません。

実務での勘所

std::stringを使えば何でも比較できるわけではありません。std::string型とint型を==で比較しようとしても、やはり対応する演算子が無くコンパイルエラーになります。std::stringが便利なのは、文字列同士の比較(std::string == "文字列リテラル"のような組み合わせ)に対して==演算子が用意されている点で、const char*同士の==がポインタの値を比較してしまう(内容ではなくアドレスの比較になる)という、C由来の別の罠を避けられることです。

演習をはじめる

関連するエラー

広告
広告スロット(未設定)