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 です。
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() 使っても良いし、符号("+-")や小数点(".")等も数値同様出力する様する事も可能です。
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」という「-」で繋がっている場合の考慮を
していません。よって「この形が出現しない」という前提でしか使えません。
この点を踏まえた上で参考にして下さい。
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);
}
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でも"表"という文字と'\'を混乱しない)
ものもたくさんあります
C++で実装しているため非常に助かります。
おっしゃる通り、strtokを使うやり方では確かに融通が利かないところもありますね。
この方法でも試してみようと思います。ついでに正規表現についても調べてみます。
どうもありがとうございました。
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;
}
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
このQ&Aを見た人はこんなQ&Aも見ています
-
準・究極の選択
「年収1000万円で一生カレーライス」か 「年収180万円で毎日何でも食べ放題」 あなたはどちらを選びますか?
-
フォロワー20万人のアカウントであなたのあるあるを披露してみませんか?
あなたが普段思っている「これまだ誰も言ってなかったけど共感されるだろうな」というあるあるを教えてください
-
映画のエンドロール観る派?観ない派?
映画が終わった後、すぐに席を立って帰る方もちらほら見かけます。皆さんはエンドロールの最後まで観ていきますか?
-
海外旅行から帰ってきたら、まず何を食べる?
帰国して1番食べたくなるもの、食べたくなるだろうなと思うもの、皆さんはありますか?
-
天使と悪魔選手権
悪魔がこんなささやきをしていたら、天使のあなたはなんと言って止めますか?
-
C++で入力した文字列から数字を取り除くもしくは数字のみをのこす
C言語・C++・C#
関連するカテゴリからQ&Aを探す
おすすめ情報
- ・漫画をレンタルでお得に読める!
- ・街中で見かけて「グッときた人」の思い出
- ・「一気に最後まで読んだ」本、教えて下さい!
- ・幼稚園時代「何組」でしたか?
- ・激凹みから立ち直る方法
- ・1つだけ過去を変えられるとしたら?
- ・【あるあるbot連動企画】あるあるbotに投稿したけど採用されなかったあるある募集
- ・【あるあるbot連動企画】フォロワー20万人のアカウントであなたのあるあるを披露してみませんか?
- ・映画のエンドロール観る派?観ない派?
- ・海外旅行から帰ってきたら、まず何を食べる?
- ・誕生日にもらった意外なもの
- ・天使と悪魔選手権
- ・ちょっと先の未来クイズ第2問
- ・【大喜利】【投稿~9/7】 ロボットの住む世界で流行ってる罰ゲームとは?
- ・推しミネラルウォーターはありますか?
- ・都道府県穴埋めゲーム
- ・この人頭いいなと思ったエピソード
- ・準・究極の選択
- ・ゆるやかでぃべーと タイムマシンを破壊すべきか。
- ・歩いた自慢大会
- ・許せない心理テスト
- ・字面がカッコいい英単語
- ・これ何て呼びますか Part2
- ・人生で一番思い出に残ってる靴
- ・ゆるやかでぃべーと すべての高校生はアルバイトをするべきだ。
- ・初めて自分の家と他人の家が違う、と意識した時
- ・単二電池
- ・チョコミントアイス
このQ&Aを見た人がよく見るQ&A
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
CStringをwchar_tに変換したい
-
main の引数には const 付けた方が
-
AnsiPos相当の関数はありません...
-
fgetsなどのときのstdinのバッ...
-
文字列から空白を取り除きたい...
-
ネットワークにつながっている...
-
テキストデータをそのままバイ...
-
charからLPTSTRへの変換方法
-
型変換
-
間接操作のレベルとは
-
int main()の・・・
-
phpMyAdminからストアドプロシ...
-
英単語をアルファベット順に
-
sprintfに同じ変数は使えるか
-
日付表示の方法
-
ソースコードエラー
-
C言語 バイナリファイルをfloa...
-
文字列ポインタを結合
-
16進数から10進数に変換
-
char型からのバイト数取得
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
fgetsなどのときのstdinのバッ...
-
CStringをwchar_tに変換したい
-
charでの計算?
-
文字列から空白を取り除きたい...
-
charからLPTSTRへの変換方法
-
'const char *' 型は 'char *' ...
-
テキストデータをそのままバイ...
-
配列をnビットシフトする
-
半角カナ→16進
-
double型の値をchar配列に変換...
-
sprintfに同じ変数は使えるか
-
ファイル名である文字列からbas...
-
ネットワークにつながっている...
-
ftoa の作り方
-
間接操作のレベルとは
-
型変換
-
C言語です
-
C言語のfor文です。 繰り返しの...
-
Win32APIでのエディットボック...
-
【C言語】文字型と整数型の違い
おすすめ情報