• ベストアンサー

文字列や文字から整数への変換方法について

文字列(string型)や文字(char型)から整数(int型など)に変換 する時のルールがよく解りません。 たとえば、キーボードから数字を打って、その入力された数字を 数値として整数型の変数に代入したい場合のやり方です。 ちょっとプログラムを作ってみました。 using System; class clmain { private static void Main() { Console.Write("1桁の整数を入れてね "); char ch = char.Parse(Console.ReadLine()); int by1 = (int)ch; int by2 = (int)char.GetNumericValue(ch); Console.WriteLine("by1 = {0}, by2 = {1}, ch = {1}", by1, by2, ch); Console.Write("整数を入れてね "); string st = Console.ReadLine(); /* by = (int)st; コンパイルエラー */ int by3 = int.Parse(st); Console.WriteLine("by3 = {0}, st = {1}", by3, st); } } まず、char型からint型への変換では、  int型変数=(int)char型変数; はコンパイルは通りますけど、実行すると全く違った値が入って しまいます。たとえば char型変数の値が "1" だと、int型変数には 49 が入ります。 int型変数 = (int)char.GetNumericValue(char型変数); と書いてようやく、思い通りの動きをしてくれます。 また、string型からint型への変換では  int型変数=(int)string型変数; はコンパイルエラーになります。 int型変数 = int.Parse(string型変数); とするとコンパイル出来て正しく動きます。 これで質問ですけど、 (1)なぜstring型とchar型で、int型への変換方法が違うのでしょうか? (2)int型変数=(int)char型変数; とすると、上に書いたように、全く 違った(希望しない)値が代入されてしまいます。これは、どういう 動きをしているのでしょうか? また、これはコンパイルエラーに なりませんけど、どういう時にこの書き方をするのでしょうか? 解る方、お願いします。

質問者が選んだベストアンサー

  • ベストアンサー
  • BDTF
  • ベストアンサー率55% (38/68)
回答No.2

→(1)について  string型はchar型やint型とは違い「準備された型」だからです。  言ってしまえば使いやすいようにカスタムしたchar型ということ。  ゆえに変換するときにはカスタムした分別の動作が必要になり、それをしてくれるのがParseだという訳です。 →(2)について  int型とchar型では中に入っているデータの「表現」が異なるからです。  わかりやすく書けば、両方をのぞいた時同じデータが入っていたとしても  int型は中に入っているデータそのものが見えますが、  char型は中に入っているデータから得られた文字が見える。 一枚フィルタを挟んでいるわけです  具体的には文字コードによる変換が、なされています。49→1 65→A  参考:http://okuyama.mt.tama.hosei.ac.jp/unix/C/slide95-1.html    なのでこれが正常で、エラーにはなりません。  言ってしまえば文字も数字もデータとはいえ、「文字」というデータはありません。数字から成り立つデータにおいて文字を表現する場合、文字に数字をふりわけてそこから表示するしか無いわけです。  で、char型はその振り分け後のものを表現する型なので、単純に中身をintに入れてやっても違う値になると。  こんなところで少しは参考になりましたでしょうか?

kanon_mori
質問者

お礼

ありがとうございます。 準備された型、カスタムした型っていうのは、構造体型 (ConsoleKeyInfoのような)って意味でしょうか? >int型は中に入っているデータそのものが見えますが、 >char型は中に入っているデータから得られた文字が見える。 一枚フィルタを挟んでいるわけです これはつまり、例えば1を代入したとすると、int型の変数には 0x01 が入ってるけど、char型には"1"という文字を表すASCIIコードが (16進イメージで言うと)入ってるということでしょうか。 全然プログラミングの基礎が解ってなくて、すみません(^^ゞ ありがとうございます。

その他の回答 (3)

  • arain
  • ベストアンサー率27% (292/1049)
回答No.4

No.1です。 No.1より >>String型はchar型やint型のような単純な方とは内部構造が違っています。 >というのは、char型やint型はその変数の中身そのものを指すけど、 >string型はその文字列が置かれてるアドレスを指すっていうような >意味でしょうか?(別の言語でいうポインタみたいな感じなんでしょうか。) ポインタそのものではありません。 簡単に書くと、データの入っている場所を示すポインタや文字数などの情報がまとめて入っている構造体のようなものです。 No.2より >これはつまり、例えば1を代入したとすると、int型の変数には >0x01 が入ってるけど、char型には"1"という文字を表すASCIIコードが >(16進イメージで言うと)入ってるということでしょうか。 これは若干認識が違います。 「1」を入力した場合に「数値」として取得すれば、「0x01」で「文字」として取得すれば「0x31」です。 scanf()の話がでましたので以下に簡単なサンプルを書きます(空白は全角スペースなので注意) -----------------  int i1, i2;  char c1, c2;  printf( "数値で取得 = " );  scanf( "%d", &i1 );  scanf( "%*c" );   // CR読み捨て  c1 = (char)i1;   // int型の内容をchar型に入れる  printf( "文字で取得 = " );  scanf( "%c", &c2 );  scanf( "%*c" );   // CR読み捨て  i2 = (int)c2;   // char型の内容をint型に入れる  //10進数と16進数で取得内容を表示  printf( "i1 = %3d[0x%02x] c1 = %3d[0x%02x]\n", i1, i1, c1, c1 );  printf( "i2 = %3d[0x%02x] c2 = %3d[0x%02x]\n", i2, i2, c2, c2 ); ----------------- これを実行して結果を確認してみてください。 (手抜きなので0~9の一桁以外入れないでください)

  • asuncion
  • ベストアンサー率33% (2126/6286)
回答No.3

char c; int n; scanf("%c", &c); でcに1桁の数字('0'~'9')を入れて、それを1桁の数値(0~9)に変換したいのであれば、 n = c - '0'; とでもすればよいのではないでしょうか。

kanon_mori
質問者

お礼

scanfっていうのは?? と思ってネットで調べてみたら、 System.Console.Readと同じように、標準入力から文字列を受け取る メソッドなんですね。 >n = c - '0'; 明示的に計算をするわけですね。 ありがとうございました。

  • arain
  • ベストアンサー率27% (292/1049)
回答No.1

(1) String型はchar型やint型のような単純な方とは内部構造が違っています。その部分は省きますが、 >int.Parse(string型変数); でString型に格納されている内容をint(数値)に変換して渡しているからです。 (2) 記述に従った正しい動作です。 > int型変数=(int)char型変数; は単純に「変数型を一致させている」だけです。 char型変数に入っている内容は「文字列」でしょうから「1」は「数値」ではなく「文字」です。 「1」の文字コードは「0x31」=10進数で「49」です。 「1」という数値が必要であれば、自分で数値への変化式を書くかatoi()等の関数を使用する必要があります。

kanon_mori
質問者

お礼

説明ありがとうございます。 私の理解力が足りなくて、レス出来るまで時間がかかってしまいました。 >String型はchar型やint型のような単純な方とは内部構造が違っています。 というのは、char型やint型はその変数の中身そのものを指すけど、 string型はその文字列が置かれてるアドレスを指すっていうような 意味でしょうか?(別の言語でいうポインタみたいな感じなんでしょうか。) >「1」の文字コードは「0x31」=10進数で「49」です。 これはとてもよく解りました! そういう代入をしてしまうんですね。 コンパイルの時に、せめて警告でも出して欲しいです(^_^;) ありがとうございました。

関連するQ&A

  • [C#]型変換について教えてください。

    ◆int型のリスト「 List<int>」に変換したいです。 以下、ソースの一部を記述します。 ***********ソースの一部*********** string str; Console.Write("4桁の数値->"); str = Console.ReadLine(); *************************************** ■現状 ・string型の変数"str"に、キーボードからの値入力を許容。 ■質問 2つあります。よろしくお願いいたします。 1. 要素の型「string」からint型のリスト「 List<int>」に変換する方法はありませんか? 2. キーボードからの値入力でint型のリスト「 List<int>」に直接入力することはできませんか? 拙い知識のため要領を得ない質問かもしれませんが、ぜひご教示ください。

  • 文字を整数として扱う場合の演算について質問

    javaの参考書に、文字を整数として扱う場合の演算についての解説があり、疑問点があったので質問します。 質問1:何故char型の変数は、キャストしなくてもint型のリテラルを代入することができるのか?      例えば、 以下の演算はキャストしなくてもこのまま代入できます。 char ch='a'; ch=98; でも、以下の演算はキャストしていないのでエラーになります。      char ch='a'; ch=ch+1; これは何故ですか?参考書に記載されていた理由として、「byte,char,short、 これ等の型の変数や値を使って計算すると、それ等は一度intに直して計算されるから」というような趣旨の事が書いてありました。 つまり、char型の変数には、キャストしない限りint型の数値を代入できないということですよね? でも前者のソースコードは、chはchar型であるにもかかわらず、int型のリテラル98を代入できています。 これは何故ですか? 質問2:javaの参考書に、インクリメント・デクリメント演算子と複合代入演算子は、型を保存するという解説がありました。これはどういう意味ですか? 僕の仮説では、例えば、      char ch='a';      ch+=5; であれば、5は、char型のまま代入されるということでしょうか?

    • ベストアンサー
    • Java
  • C#について

    using System; class AddressBook: PhoneBook { private string address; public AddressBook() : base() { address=""; } public void Input() { base.Input(); Console.Write("住所?"); string address=Console.ReadLine(); } public void Writes() { base.Write(); Console.WriteLine("住所:{0}",address); } } class kadai62 { public static void Main() { Console.Write("電話帳に入力する人数を入れてください:"); int n = int.Parse(Console.ReadLine()); AddressBook[] pb = new AddressBook[n]; int i; for (i = 0; i < pb.Length; i++) { pb[i] = new AddressBook(); Console.WriteLine("{0}番目を入力してください.", i+1); pb[i].Input(); } Console.WriteLine(); while(true) { Console.Write("どこから探しますか?[1:氏名,2:自宅電話,3:携帯電話,0:終了] "); int t = int.Parse(Console.ReadLine()); if (t == 0) break; Console.Write("探す文字列は?"); string s = Console.ReadLine(); for (i = 0; i < pb.Length; i++) { if (pb[i].Search(t, s)) pb[i].Writes(); } } } } このプログラムで public void Writes() { base.Write(); Console.WriteLine("住所:{0}",address); } のaddressが出力されません・・どうすれば 出力されますか?

  • C#で char型とstring型の比較で Equalsでハマりました。 

    C#で char型は値型でstring型は参照型ですがこの比較を正しく行うにはどうしたらよいでしょうか? string s = "0123456789"; Console.WriteLine(s[0]); Console.WriteLine("0".Equals(s[0]) ? "true" : "false"); で、falseなのは驚きでした。 Equalsを鵜呑みにしていました。 コンパイルできたので今まで気づきませんでした。 詳しい方、教えて頂けますか?

  • [C#]順序通りに実行されない

    次のC#のプログラムについて質問です。 //ここから using System; class Myclass { double[] point; string[] name; int nMax; public double this[string str] { get { for (int i = 0; i < nMax; i++) { if (str == name[i]) return point[i]; } return -1.0; } set { for (int i = 0; i < nMax; i++) { if (str == name[i]) { point[i] = value; break; } } } } public Myclass(int n) { point = new double[n]; name = new string[n]; nMax = n; setname(); } void setname() { for(int i=0;i<nMax;i++) { Console.Write("生徒名[{0}] = ",i); name[i] = Console.ReadLine(); } } } class ch08ex02 { public static void Main() { Console.WriteLine( "まずはじめに生徒数と、全員の名前入力が必要です"); Console.Write("生徒数--- "); string strn = Console.ReadLine(); Myclass mc = new Myclass(int.Parse(strn)); string ans, strp; Console.WriteLine("X入力で終了"); while (true) { Console.Write("点数を入力したい生徒名--- "); if ((ans = Console.ReadLine()) == "X") break; Console.Write("点数--- "); strp = Console.ReadLine(); mc[ans] = double.Parse(strp); } Console.WriteLine(); Console.WriteLine("X入力で終了"); while (true) { Console.Write("点数を知りたい生徒名--- "); ans = Console.ReadLine(); if (ans == "X") break; Console.WriteLine("{0}くんの点数は{1}点です", ans, mc[ans]); } } } //ここまで これはプロパティを使って生徒の点数を配列に格納したり参照したりするプログラムですが、実行するとMain()の    Console.Write("生徒数--- "); string strn = Console.ReadLine(); Myclass mc = new Myclass(int.Parse(strn)); string ans, strp; Console.WriteLine("X入力で終了");    while (true) { Console.Write("点数を入力したい生徒名--- "); if ((ans = Console.ReadLine()) == "X") break; Console.Write("点数--- "); strp = Console.ReadLine(); mc[ans] = double.Parse(strp); } の部分が思い通りに動いてくれません。 まずコンソールに「生徒数--- 」と表示されConsole.ReadLine()で数字を受け取り、その数からMyclassのインスタンスを作成し、「X入力で終了」と表示した後whileループで生徒名と点数の入力を受け付けるはずです。 しかしこれを実行すると「X入力で終了」と表示する前にwhileループに入り、ループを抜けた後「X入力で終了」と表示されます。 つまり順番が逆になっているわけです。 なぜこうなるかわかりません。 誰か教えてください、お願いします。

  • C#の数値の変換について

    ユーザーが数値以外を入力したらエラーを返すコードを作成したのですが while (!int.TryParse(Console.ReadLine(), out enterNum)) こちらの行を TryParse だけでなく、それ以外の分解した書き方でも作成するように指示を受けたのですが、書き方が分からず、どなたか教えて頂けないでしょうか? 【ソースコード】 int enterNum; Console.WriteLine("勝負回数を入力してください"); //入力された文字が数値に変換出来なかった場合、inputerrorを表示させループさせる while (!int.TryParse(Console.ReadLine(), out enterNum)) { Console.WriteLine("inputerror"); }

  • C#のループについて

    現在C#でジャンケンゲームの課題に取り組んでいるのですが、ループ処理や各メソッドに対しての変数にエラーがでてしまい、修正方法が分からず、どなたか教えて頂けないでしょうか? ・ユーザはグー、チョキ、パーをそれぞれ1、2、3の数字で入力する。 ・CPUは乱数を使って出す手を選ぶ。 ・5回勝負として、人間とコンピュータの勝った回数を数え、勝敗がつくたびに1回ずつ表示する。    あいこは決着がつくまで再勝負。途中でどちらかが3勝しても、5回最後まで勝負を続ける。   ・指定された範囲以外の値を入力したら負けにする 【実行例】  ユーザ名を入力してください:goto  手を入力してください(グー1、チョキ2、パー3): 1  CPU:チョキ  WIN  goto:1勝、CPU:0勝    手を入力してください(グー1、チョキ2、パー3): 3  CPU:パー  DRAW    手を入力してください(グー1、チョキ2、パー3): 3  CPU:チョキ  LOSE  goto:1勝、CPU:1勝    手を入力してください(グー1、チョキ2、パー3): 0  LOSE(反則負け)  goto:1勝、CPU:2勝    (中略)    goto:3勝、CPU:2勝  gotoさんの総合勝利です! using System; namespace Ensyuu007 { static class Program { static string? Myhand; static int CntWin = 0; //勝利回数 static int CntLose = 0; //敗北回数 static int CntDraw = 0; //引分回数 //ユーザー名の入力 static void Main(string[] args) { string EnterName = Console.ReadLine(); Console.WriteLine("ユーザ名を入力してください: {0}", EnterName); Console.ReadLine(); } //じゃんけんを5回行います。 for (int GameCnt = 0; GameCnt <= 5; GameCnt++) { //正しく入力されたかチェックを行うメソッド。 static string Check(ref string Myhand) { static = Console.ReadLine(); Console.WriteLine("手を入力してください(グー1、チョキ2、パー3):{0}", Myhand); //正しく入力されたかチェックします。 Check(ref Myhand); //0,1,2が入力された場合 if (Myhand.Equals("1") || Myhand.Equals("2") || Myhand.Equals("3")) { //入力した数字をそのまま返します。 return Myhand; } //1,2,3以外が入力された場合 else { Console.WriteLine("LOSE(反則負け)"); return Myhand; } } //じゃんけんを開始するメソッド。 static void Start() { //コンピューターとじゃんけんさせます。 Janken(ref Myhand); Console.ReadLine(); } //コンピュータと自分の入力した手を判別するメソッド static void Janken(ref string Myhand) { // Random クラスの新しいインスタンスを生成する Random ran = new System.Random(); //コンピュータの出す手を1以上3以下に設定する。 string[] com = new string[] { "1", "2", "3" }; string con = ran.Next(3).ToString(); //配列型、変数teに出す名前を設定 string[] te = { "グー", "チョキ", "パー" }; //コンピュータが勝利した場合 if (((Myhand == "1") && (con == "3")) || ((Myhand == "2") && (con == "1")) || ((Myhand == "3") && (con == "0"))) { Console.WriteLine("あなた:" + te.GetValue(int.Parse(Myhand))); Console.WriteLine("コンピュータ:" + te.GetValue(int.Parse(con))); Console.WriteLine("LOSE"); CntLose++; //敗北回数に加算 } //自分が勝利した場合 else if (((Myhand == "1") && (con == "2")) || ((Myhand == "2") && (con == "3")) || ((Myhand == "3") && (con == "1"))) { Console.WriteLine("あなた:" + te.GetValue(int.Parse(Myhand))); Console.WriteLine("コンピュータ:" + te.GetValue(int.Parse(con))); Console.WriteLine("WIN"); CntWin++; //勝利回数に加算 } //あいこだった場合 else { Console.WriteLine("あなた:" + te.GetValue(int.Parse(Myhand))); Console.WriteLine("コンピュータ:" + te.GetValue(int.Parse(con))); Console.WriteLine("DRAW"); CntDraw++; //引分回数に加算 } } } static void Resurut() { if (CntWin > CntLose) { Console.WriteLine("総合勝利です"); } else if (CntLose < CntWin) { Console.WriteLine("CPUの総合勝利です"); }

  • C# 猫でもわかる・・・ のプログラムで質問です。

    猫でもわかる・・・のページでC#の勉強させてもらってるのですが、 解らないところが出たので教えてください。 using System; class dowhle01 { public static void Main() { Console.Write("数字を入力してください(1-9) --- "); string strInput = Console.ReadLine(); if (strInput.Length >= 2) return; if (!char.IsDigit(strInput[0]) || strInput[0] == '0') return; int n = strInput[0] - '0'; string mystr = ""; int i = 1, sum = 0; do { sum += i; mystr += string.Format("{0} + ", i); i++; } while (i <= n); char[] trimchar = new char[] { '+', ' ' }; mystr = mystr.TrimEnd(trimchar); mystr += " = "; mystr += sum; Console.WriteLine(mystr); } } このプログラムの中の int n = strInput[0] - '0'; この部分なんですけど、 これはint型に直してるってことでしょうか? でも、普通int型にするなら、 int n = int.Parse(strInput);ですよね? こういうやり方もあるって意味なんですかね? それとも、何か特別な意味があるのでしょうか? 教えて下さい。よろしくお願いします。

  • 文字列をint型に変換したいのですが

    文字列をint型に変換して、計算に使用したいのですが うまくいきません。 char moji[0] = '1' moji[1] = '2' moji[2] = '3' この文字列をひとつずつint型の変数に代入したいのですが atoi関数を使用した場合、文字列全ての値が変換されてしまいます。 どうしたらいいのでしょうか? お答えいただけるとありがたいです。

  • c#でサンプルゲームを作ってみた

    c#でサンプルゲームを作ってみたのですがエラーがでるので間違っている所を指摘してくださいm(__)m using System; class test1 { public int HP; public int ATK; public int DF; } public class test2 { public static void Main() { test1 player1 = new test1(); test1 player2 = new test1(); player1.HP = 150; player2.HP = 150; char ch; char ken; char zyuu; char chois; int buki; for(;;){ do{ Console.WriteLine(" 使う武器を選んでください"); Console.WriteLine("¥n"); Console.WriteLine(" 1. 刀 "); Console.WriteLine("¥n"); Console.WriteLine(" 2. 拳銃 "); Console.WriteLine("¥n"); Console.WriteLine(" 3. 素手 "); Console.WriteLine(" 終了させたい場合は e"); do{ ch = (char) Console.Read(); } while(ch == '¥n' | ch == '¥r'); }while(ch < '1' | ch > '3' & ch != 'n'); if(ch == 'n') break; Console.WriteLine("¥n"); switch(ch){ case '1': Console.WriteLine(" どの刀を使いますか?"); Console.WriteLine(" 1. 太刀"); Console.WriteLine(" 2薙刀"); ken = (char) Console.Read(); while(ken == '¥n' | ken == '¥r'); Console.WriteLine("¥n"); switch(ken){ case '1': buki = 15; break; case '2': buki = 14; break; } case '2': Console.WriteLine(" どの銃を使いますか?"); Console.WriteLine(" 1.マシンガン"); Console.WriteLine(" 2.リボルバー"); zyuu = (char) Console.Read(); while(zyuu == '¥n' | zyuu == '¥r'); Console.WriteLine("¥n"); switch(zyuu){ case'1': buki = 10; break; case'2': buki = 15; break; } case'3': buki = 8; break; } Console.WriteLine("敵が現れた!"); for(;;){ if(plyer1.HP < 0) break; else(player2.HP < 0 ) break; Console.WriteLine(" 1.攻撃¥n 2.防御"); chois = (char) Console.Read(); while(chois == '¥n' | chois == '¥r'); Console.WriteLine("¥n"); switch(chois){ case'1': Console.WriteLine("player1の攻撃!!"); player2.HP = player2.HP - (buki + 10) - 5; Console.WriteLine("%d, player2.HP") ; Console.WriteLine("player2の攻撃!!"); player1.HP = player1.HP - (20 - 5); break; case'2': Console.WriteLine(" player1はガードした!!"); Console.WriteLine("player2の攻撃!!"); Console.WriteLine(" しかしplayer1は攻撃を防いだ!"); break; } } } } }