質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

89.12%

出入力c++

解決済

回答 2

投稿

  • 評価
  • クリップ 0
  • VIEW 1,322

reotantan

score 257

入出力のコードを書いていたのですが、エラーがでてしまいます。
問題点を指摘してくださるとうれしいです。
コード
/*
 * stream.cpp
 *
 *  Created on: 2015/10/29
 *      Author: 礼央
 */

#include<iostream>
#include<sstream>
#include<fstream>

int main() {
    using namespace std;
    ostringstream strbuf;

    int lucky = 7;
    float pi = 3.14;
    double e = 2.71;
//
    cout << "An in-memory stream" << endl;
    strbuf << "luckynumber:" << lucky << endl << "pi:" << pi << endl << "e:"
            << e << endl;

    string strval = strbuf.str();
    cout << strval;

    ofstream outf;
    outf.open("mydata");
    outf << strval;
    outf.close();

    cout << "Read data from the file-watch for errors" << endl;
    string newstr;
    ifstream inf;
    inf.open("mydata");
    if (inf) {
        int lucky2;
        inf >> newstr >> lucky2;
        if (lucky != lucky2)
            cerr << "error! wrong" << newstr << lucky2 << endl;
        else
            cout << newstr << "OK" << endl;

        float pi2;
        inf >> newstr >> pi2;
        if (pi2 != pi)
            cerr << "Error! wrong" << newstr << pi2 << endl;
        else
            cout << newstr << "OK" << endl;
        double e2;
        inf >> newstr >> e2;
        if (e2 != e)
            cerr << "ERROR:Wrong" << newstr << e2 << endl;
        else
            cout << newstr << "OK" << endl;
        inf.close();
    }
}
  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 2

checkベストアンサー

0

istreamから>>でstring型変数へ読みだすと、次の区切り記号(whitespace)までを読み出します。
区切り記号はスペースやタブ文字や改行文字のようです。
これらの区切り記号を挟まずに数値を出力しているため、:の後の数字もnewstrに読まれてます。

フォーマットを変えてよいなら、:の後に1つスペースを挟むだけで解決します。

フォーマットを変えない場合は、getlineの区切り記号指定版を使うことも考えられます。
下記のように使います。
        getline(inf, newstr, ':') >> lucky2;

ただ、':'を区切り記号にことで
  ①改行文字がnewstrに読まれてしまいます。
  ②':'はnewstrに読まれません。
①の影響が結構鬱陶しいし、対策は「汚く」なります。

少し面倒になりますが、行単位でstring型変数へ読み込んでfind_first_ofやfind_first_not_ofを使う定石的な方法を使った方がgetlineを使うより良いかも知れません。

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

0

std::ifstream operator>>( std::ifstream& ifs, std::string& str )
を確認しましょう.デフォルトでは数字も「:」も含めて全部読み取ります.
以下のようにオーバーライドするか,operator>>ではない独自関数を作って,そっちに任せましょう.

#include<iostream>
#include<sstream>
#include<fstream>
#include<cctype>

std::ifstream& operator>>( std::ifstream& ifs, std::string& str )
{
    char check = 0;
    if ( ifs >> check )
    {
        str += check;
        while ( isalpha( check ) && ifs.get( check ) )
        {
            str += check;
        }
    }
    else
    {
        ifs.setstate( std::ios_base::failbit );
    }
    
    return ifs;
}

int main() {
    using namespace std;
    ostringstream strbuf;

    int lucky = 7;
    float pi = 3.14;
    double e = 2.71;
    //
    cout << "An in-memory stream" << endl;
    strbuf << "luckynumber:" << lucky << endl << "pi:" << pi << endl << "e:"
        << e << endl;

    string strval = strbuf.str();
    cout << strval;

    ofstream outf;
    outf.open("mydata.txt");
    outf << strval;
    outf.close();

    cout << "Read data from the file-watch for errors" << endl;
    string newstr;
    ifstream inf;
    inf.open("mydata.txt");
    if (inf) {
        int lucky2;
        inf >> newstr >> lucky2;
        if (lucky != lucky2)
            cerr << "error! wrong " << newstr << ", " << lucky2 << endl;
        else
            cout << newstr << "OK" << endl;

        float pi2;

        inf >> newstr >> pi2;
        if (pi2 != pi)
            cerr << "Error! wrong " << newstr << ", "<< pi2 << endl;
        else
            cout << newstr << "OK" << endl;

        double e2;
        inf >> newstr >> e2;
        if (e2 != e)
            cerr << "ERROR:Wrong " << newstr << ", " << e2 << endl;
        else
            cout << newstr << "OK" << endl;
        inf.close();
    }

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2015/10/29 11:59

    >以下のようにオーバーライドするか,operator>>ではない独自関数を作って,そっちに任せましょう.

    標準ライブラリに既に存在している関数(http://www.cplusplus.com/reference/string/string/operator%3E%3E/)の動作を変えると混乱が生じやすいので、別関数を定義した方がより安全と思います。

    キャンセル

  • 2015/10/29 12:43

    自分も別のアプローチしたほうが絶対いいよなぁこれと思いながら書いてましたw

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 89.12%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

同じタグがついた質問を見る