• ベストアンサー

入力された文字列から整数だけを取り出す方法

入力された文字列から整数だけを取り出すにはどうしたらよいのでしょうか? 例えば、 (1,1,4,4,2,3,2,3) と入力された時、'(' や ',' は無視して、 1 1 4 4 2 3 2 3 のみを取り出したいのですが。。 自分なりにiostreamの関数について調べてみたのですが、良い方法が思いつきません。 どなたかお力添えをお願いいたします。

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

  • ベストアンサー
  • mha01
  • ベストアンサー率81% (9/11)
回答No.7

LippmanのC++プライマー(第4版)のp.340~p.342に、 8.5 stringストリーム という節があって、p.342に、 「istringstream を使って format_message(数値と文字列の並びが格納された ostringstream オブジェクト)を読めば数値を取り出すことができる。 文字列表現を数値に自動変換してくれるのである。 istringstream input_istring(format_message.str()); string dump; input_istring >> dump >> val1 >> dump >> val2;   」 て書いてありました。 input_istring の内容構成について知っていなければならない条件付きですけど。 ちなみにヘッダは sstream です。

voltaire00
質問者

お礼

これは便利ですね。 処理が短くなりそうで助かります。ありがとうございました。

全文を見る
すると、全ての回答が全文表示されます。

その他の回答 (6)

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

>#5さん >※ "整数だけを取り出す"問題 1桁限定ならば、OKですね。 2桁以上の数値を取り出すことがあるならば、別の手立てが必要になりそうです。 まあ、そういう仕様があるかどうかは質問者さんしだいですけれど…。

全文を見る
すると、全ての回答が全文表示されます。
回答No.5

C言語で単純に書いてみました。 #include <stdio.h> #include <stdlib.h> int main( void ) { char str[] = "(1,1,4,4,2,3,2,3)"; char *test; for (test=str; '\0' != (*test); test ++ ) { if ( ( *test >= '0' ) && ( *test <= '9' ) ) { printf("%c", *test ); } else { printf("%c", ' ' ); } } printf( "\n" ); } 数値のみを取り出したいという事で、目的をそのまま書きました。 入力値が"(1,1,4,4,2,3,2,3)"ではなく"#(1,1,4,4,2,3,2,3)"や"[1,1,4,4,2,3,2,3]","($1,&1#4!4,%2,=3,A2,BC3)"でも動作します。 ※ "整数だけを取り出す"問題でtokenが"(,"と固定されている問題ではなかったと感じましたので。 数字の確認部分、isdigit() 使っても良いし、符号("+-")や小数点(".")等も数値同様出力する様する事も可能です。

全文を見る
すると、全ての回答が全文表示されます。
  • massano1
  • ベストアンサー率40% (4/10)
回答No.4

strtok()関数は文字列を破壊してしまうので複製を作りますが… 「複製を作らなければならない」のなら、デリミタを統一した複製を 初めに作ってしまおうというコードです。 --- #include <stdio.h> #include <stdlib.h> #include <string.h> #define NUMERIC "-0123456789" #define DELIMIT "," int main( void ) { char *string = "(1,1,(4,4),2,3,2,3),[-5,10],{20,-40}"; char *token, *delimit = DELIMIT; char *str; int i; if (str=(char *)malloc(strlen(string)+1)) { strcpy(str,string); for (i=0;*(str+i)!=0;i++) if (!strchr(NUMERIC,*(str+i))) *(str+i)=*delimit; token = strtok(str, delimit); while (token) { printf("%d\n", atoi(token)); token = strtok(NULL, delimit); } free(str); } return 0; } --- 但し、このコードは「123-123」という「-」で繋がっている場合の考慮を していません。よって「この形が出現しない」という前提でしか使えません。 この点を踏まえた上で参考にして下さい。

全文を見る
すると、全ての回答が全文表示されます。
  • jacta
  • ベストアンサー率26% (845/3158)
回答No.3

こんな感じでどうですか? char *s = "(1,1,4,4,2,3,2,3)"; while (*s != '\0') {  char *ss = strpbrk(s, "+-0123456789");  if (ss == NULL) break;  s = ss;  errno = 0;  long value = strtol(s, &s, 10);  if (errno != 0) perror("error");  else printf("%ld\n", value); }

全文を見る
すると、全ての回答が全文表示されます。
  • BLK314
  • ベストアンサー率55% (84/152)
回答No.2

C++言語で実装してみました。 ・()が複数あっても正しく動作する  ex (0,1), (1,2) オーバーフロー対策  (符号付き)整数に収まらない場合は処理しない 上に述べた事は”仕様"の問題で色々あると思います。 絶対に()は一組しか存在しないとか オーバーフロー時はエラーを表示するとか 今回の場合 strtoken()でももちろん実装できますし、 その方がスマートでもあるのですが、 ちょっとした弱点も抱え込むと考えます。 それは、"融通がきかない"ということです。 ()の他に{}でくくられている場合もある さらに、[]もあることがわかった .... その度にプログラムに修正を入れなければなりません。 デリミタ(区切り文字)をプログラムに埋め込む(ハードコーディング) でなく、設定ファイル等から読み込ませることにすれば かなり融通が利くようになりますが、 高々整数を取り出すのに、 その他の文字として何が使われいるか 調査しなければいけないのもつらいです。 整数なのだから 数字, 符号からなり それ以外は区切り文字にしてしまう方が扱い易いと思います。 それでは、ソースを載せます ====== ここから ソース ========================================== // StringTest.cpp : コンソール アプリケーションのエントリ ポイントを定義します。 // #include "stdafx.h" #include <string> // 文字列処理にC++標準のStringクラスを用います #include <list> // 結果データ格納用 #include <errno.h> #include <iostream> using namespace std; // 文字が"整数"構成文字かチェックします static bool IsIntegerChar(char c) { if (isdigit(c)) return true; else if (c == '+' || c == '-') return true; else return false; } int main(int argc, char* argv[]) { // 元々の文字列です const char src[] = "(0, 1),(+2147483647, -2147483648, 2147483648, -2147483646)"; string s; // "整数"の候補格納用 list<int> tbl; // 結果の // 文字列を先頭から最後までサーチします for (const char* p = src; *p != '\0'; p++) { // 取り扱うのが整数のみなので // 文字としては数字及び+,-の符号のみが許されます。 char c = *p; if (IsIntegerChar(c)) { // 整数の候補を検出しました // まだ候補でしかないので保存しておきます s += c; } else { // 整数を表しえない文字です // 整数候補文字列の開始前か終了後です if (!s.empty()) { // 整数候補文字列の終わりです // 整数かどうかチェックを行います int n = atoi(s.c_str()); if (errno != ERANGE) { // 整数として変換できました // 後でまとめて表示するため // リストに格納します tbl.push_back(n); } // 新たな整数候補を探すため // 格納域をクリアします s.clear(); } } } // 文字列全体のサーチが終了しました // 整数を表示します for(list<int>::iterator it = tbl.begin(); it != tbl.end(); ++it) { cout << *it << endl; } return 0; } ======= ここまでソース ============================================= なお、この種の問題 (文字列を文字のパターンで区切ったり、パターンに該当する部分文字列を 検索したりする) は古くから研究されていて、ライブラリも多くあります。 正規表現 もその一つです 正規表現をサポートしたライブラリはたくさんありますので 探してみてください 日本語にきちんと対応した (ex Shift-JISでも"表"という文字と'\'を混乱しない) ものもたくさんあります

voltaire00
質問者

お礼

C++で実装しているため非常に助かります。 おっしゃる通り、strtokを使うやり方では確かに融通が利かないところもありますね。 この方法でも試してみようと思います。ついでに正規表現についても調べてみます。 どうもありがとうございました。

全文を見る
すると、全ての回答が全文表示されます。
  • asuncion
  • ベストアンサー率33% (2126/6288)
回答No.1

C言語での一例です。 #include <stdio.h> #include <stdlib.h> #include <string.h> int main( void ) { char str[] = "(1,1,4,4,2,3,2,3)"; char *token, *dlm = "(,"; token = strtok(str, dlm); while (token) { printf("%d\n", atoi(token)); token = strtok(NULL, dlm); } return 0; }

voltaire00
質問者

補足

早速の回答ありがとうございます。 試してみます。

全文を見る
すると、全ての回答が全文表示されます。

関連するQ&A

  • 文字列から整数導き出したい

    お世話になります。 現在、簡易的な占いのプログラムを作ってみています。 フォームに入力された文字から占いの結果を表示するようなものを 作りたいのですが、中々うまくいきません。 仕組み的にはフォームから文字列をPOST⇒10進数の整数に変換⇒10進数の整数に対応する占い結果を表示という形を考えています。 文字列をbin2hex関数で16進数にはできるのですが、16進数から10進数変換する方法がわかりません。 何かより方法がありましたらご教授ください。

    • ベストアンサー
    • PHP
  • ”123456”といった整数を文字列に変換、その後、文字列を1文字ごとに整数に変換 

    忙しい中失礼します。 http://oshiete1.goo.ne.jp/qa3424254.htmlでも質問させて頂いたものですが、 今、回答してくださった方の意見を参考に以下の過程をこなそうとしています。 1.整数入力 →scanf関数を使用し、"123456"と入力します。 2.整数を文字列に変換 → printf("Write the SIN: \n");   scanf("%d", &fnum);   printf("%c\n",fnum); で、"123456"と数値を入力しても”123456”という値が返されず、@となってしまいます。 どうすれば入力した数値が文字列として返ってくるのでしょうか? どんな文・関数を使用すれば数字を文字列として使用することが可能になるのでしょうか? 今のところ習っている文はif else, swith case, while for,do whileで、 getcharやstr?(string)という関数は習っていません。なので、どうプログラムを書けばいいのか??さっぱりなのです。 でもgetcharやstr?(string)という関数を使用するしか方法はないものなのでしょうか?  また、それから 3.文字列を1文字ごとに整数に変換  にする場合、どんな文・関数を使用すれば、1文字”ごと”に整数に変換できるのでしょうか? ごめんなさい、分からないのです。プログラム文、ヒントもしくは参考になるページ等があれば教えて下さい。 よろしくお願いします。 <使用環境:フリーソフト(Borland?)C ANSI C>

  • 整数を文字列として認識したい

    整数を文字列として認識したいんですが、可能なのでしょうか? 例えば、i=12470というint型の整数があるとして、1万の位の数1や、十の位の数7だけを取り出したいんです。 しかし、この際、1万の位の数1をi/10000、十の位の数7を(i%100)/10などというようにしては取り出したくないんです。 ややこしい質問ですが、よろしくお願いします。 というのも、整数を文字列として認識する目的は、int型として送られてきたデータが本当に整数なのかをチェックするためだからです。 初心者なので合っているか分かりませんが、整数を文字列として認識できれば、isdigit関数を使うことで、データが本当に整数なのかをチェックすることができるのかなあと考えているんですが・・・ もし、私の考えが間違っていたり、他に良い方法があったら是非教えて欲しいと思います。

  • 10進数を表す文字列を整数型に

    "0x10"(16進数) や "020"(8進数) などは oct関数で整数型に直せますが、 10進数の文字列を整数型に直す関数はありませんか?

    • ベストアンサー
    • Perl
  • 文字列と整数型について

    はじめまして。 どうしても困っているのでヒントでも良いのでおねがいします。 関数内(func1)で確保した文字列変数のポインタを 別の関数(func2)にポインタ渡しします。 func2内で整数型で計算した結果を引数で示された文字列変数に 代入するというようなことをしたいと思ってます。 ここで、intは4byteとします。 メモリ長だけで見ると、bit[4] = tmp です。 void func1(){ char bit[4]; func2(bit); return; } void func2(char* p){ int tmp = 0x10101100; p = tmp; <---- ??? return; } そこでどのようにすれば、 代入することができるのか分かりません。 以下のような結果になるように代入したいと思っています。 bit[0] = 0x10; bit[1] = 0x10; bit[2] = 0x11; bit[3] = 0x00; 小さな文字列型に整数型をどのように渡せばよいのかが 一番疑問に思っているところです。 整数型に文字列型を代入する場合には 文字列のバイト指定とシフト演算で実現できています。 ヒントでもよいのでお願いします。

  • 整数→文字列の置換

    VB6の質問です。 ↓例で、REC変数を文字列の扱い(整数→文字列)にする方法はございますか? 宣言時の変数タイプは、変更したくありません。 宜しくお願いいたします。 Dim REC As Integer Private Sub test() As Integer  ・  ・  ・  ・ REC = '←処理結果をRECに入れる。RECには、文字列が挿入されます。 End Sub

  • SUMPRODUCTで文字列を無視したい

    いろいろ検索してみたのですが、 よくわからないので助けていただきたいです。 エクセル関数の初心者(入門者)です。 複数条件の合計で =SUMPRODUCT(($E$5:$E$27=$E$33)*($D$5:$D$27="○○")*(BT$5:BT$27)) という関数を入力しました。 BT列には、文字列も入力してありますので 文字列がある場合はエラーになってしまいます。 文字列を無視する方法はありませんか? 恐れ入りますが、よろしくお願い致します。 ※DSUMはふさわしくありません。

  • 8086のアセンブリで文字列の入力方法は?

    8086系のアセンブリでチャットのプログラムを組もうと思っています。 ・・・が、チャットなのに1つの文字を入力する方法しか分かりません。 「文字列」の入力方法は、どうすれば良いのでしょうか?又、入力された文字列を表示させるには・・・? どなたか、教えて頂けないでしょうか?出来れば、方法だけでなくソースも書いて頂けると有り難いのですが・・・ よろしくお願いします。

  • B列とC列のいずれかに文字が入力されています。

    B列とC列のいずれかに文字が入力されています。 B列とC列同時に入力されていることはなく、B列とC列とも空白のこともあります。 この時、A列にB列、C列の文字をコピーするためにはA列にどのような関数を用いればよいですか。 A  B  C あ    あ い い           う    う といった具合です。 

  • 指定文字の同じ行2列、3列目の文字入力の個数

    B列3~12行に文字が入力されており指定文字Bの行の2列目に文字が入力されていればその個数をC14にまた3列目に文字入力個数5個をD14に入力したいのですがどなたか関数が解る方宜しくお願いします。Excel2013です。

このQ&Aのポイント
  • デスクトップPC型番MJ36HB-Jの電源ボタンを一度目を押しても電源が入らないことがあります。この問題は最近起こり始め、データの損失や仕事の遅延を招く可能性があります。買い換えはせずに修理を希望しています。
  • デスクトップPC型番MJ36HB-Jの電源ボタンを1度押しても電源が入らない問題が発生しています。この問題は毎朝の作業スタート時に不安を感じさせ、仕事の遅延やデータの損失を招く可能性があります。修理の依頼先を教えてください。
  • デスクトップPC型番MJ36HB-Jは、電源ボタンを1度押しても電源が入らないという問題が発生しています。この問題は最近始まり、データの損失や仕事の遅延を引き起こす可能性があります。修理を希望しているので、修理の依頼先を教えてください。
回答を見る