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

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

新規登録して質問してみよう
ただいま回答率
85.48%
C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

Q&A

解決済

2回答

476閲覧

C++ ファイルからの読み込み

waewae96

総合スコア20

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

0グッド

0クリップ

投稿2018/04/15 16:41

こんばんは。
普段Cでコードを書いている学生です。
C++のvectorを使ってファイルから一行ずつ数字を読み込んで格納するファイルを作成中なのですが、
ファイルは読み込むのになぜかvectorに格納されません。
問題のコードは以下の通りです。二つの関数の宣言は別のヘッダファイルでしてあります。

c++

1#include <stdio.h> 2#include <iostream> 3#include <vector> 4using namespace std; 5 6 7FILE *fp1; 8/*(1-3)*/ 9void file_input(vector<double> v){ 10 int leng = file_counter(0); 11 v.reserve(leng); 12 rewind(fp1); 13 int i = 0; 14 double j; 15 while (1) { 16 fscanf(fp1, "%lf",&v[i]); 17 i++; 18 printf("v=%f\n",v[i]); 19 20 if(i >= leng) 21 break; 22} 23 fclose(fp1); 24} 25 26 27/*(1-5)*/ 28int file_counter(int flag){ 29 char filename [256]; 30 int counter = 0; 31 printf("ファイル名を入力してください:"); 32 scanf("%s",filename); 33 34 if ((fp1 = fopen(filename, "r")) == NULL) { 35 printf("file open error!!\n"); 36 exit(EXIT_FAILURE); 37 } 38 else{ 39 double fake; 40 while(fscanf(fp1, "%lf", &fake) != EOF){ 41 counter++; 42 } 43 } 44 if(flag){ 45 printf("ファイルから読み取ったデータ数は%dでした\n",counter); 46 fclose(fp1); 47 } 48 49 return counter; 50}

尚、ファイルからでなくキーボードから入力でvectorに格納する分にはうまく行きました。
以下のコードです。

C++

1vector<double> input_key(vector<double> v, int n){ 2 int i; 3 for(i=0;i<n;i++){ 4 printf("data[%d]=",i); 5 scanf("%lf",&v[i]); 6 } 7 return v; 8

この二つの違いがよくわかりません。
改善案などあれば教えてください。
稚拙な日本語とコードで申し訳ありませんが、よろしくお願いします。

気になる質問をクリップする

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

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

ベストアンサー

void file_input(vector<double> v){

値渡しであるために、vectorのインスタンスがコピーされてしまっています。
つまり、呼び出し元のvと、関数内のvが別物です。

参照渡しするようにすれば良いでしょう。

尚、ファイルからでなくキーボードから入力でvectorに格納する分にはうまく行きました。

この二つの違いがよくわかりません。

後者のコードも値渡しですが、戻り値としてvectorのインスタンスを返しています。
結果的に二回コピーが生じ(※)、意図通りの出力が得られているだけです。


※ 実際には最適化される(はず)なので、これは方便としての嘘です。

投稿2018/04/15 17:06

編集2018/04/15 17:11
LouiS0616

総合スコア35660

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

waewae96

2018/04/15 23:54

ありがとうございます。 調べてもvectorの参照渡しの方法がわかりません。 簡単にどのようにすれば良いか教えていただけますでしょうか。
episteme

2018/04/15 23:56

void file_input(vector<double>& v) {...} # &を型のケツに追加
waewae96

2018/04/16 00:12

ありがとうございます。ただ、 関数file_input内でもvectorであるvの値が変更されません。 FILE *fp1; /*(1-3)*/ vector<double> file_input(vector<double> &v){ int leng = file_counter(0); v.resize(leng); rewind(fp1); int i = 0; while (1) { fscanf(fp1, "%lf",&v[i]); i++; printf("v=%f\n",v[i]); if(i >= leng) break; } fclose(fp1); return v; } file_counterについては質問に乗せたものと同じです。 上記のようにv[]の値を全て表示させてみたのですが、全てv[i]=0.0000となってしまいます。 v[]に読み込ませずに確認したところ、ファイルの読み込みは、うまくいっているようです。 v[]への書き込みがうまくいかないようです。 どこが間違っているでしょうか。
episteme

2018/04/16 00:17 編集

fscanf(fp1, "%lf",&v[i]); // 読んで i++; printf("v=%f\n",v[i]); // 次の要素をプリント(だめじゃん) ↑この出力を根拠にうまくいかないって言ってる?
waewae96

2018/04/16 00:22

そうです! 全て0.00になってしまいます
episteme

2018/04/16 00:25

だからー、それじゃダメなのあたりまえでしょ? fscanf(fp1, "%lf",&v[i]); // 読んで printf("v=%f\n",v[i]); // その要素をプリント i++; // 次へ じゃなきゃ。
waewae96

2018/04/16 00:52

本当だ! ありがとうございます笑 変なミスしてましたね笑
episteme

2018/04/16 06:04

解決したんなら適切に closeしてねー
LouiS0616

2018/04/16 06:16

@episteme さん なにかとありがとうございます。。。
episteme

2018/04/16 06:18

いやだから、"best-answer"なり"解決済み"にしろって。
guest

0

呼び出し側のコードが提示されていないのでなんとも言えないですが、
下のバージョンのinput_keyを呼び出している時はvector<double> vにちゃんとn個分の要素があるvector<double>を渡して呼び出しているからうまく行ってるのでは?

上のコードでは

v.reserve(leng);

とやっていますが、std::vectorのreserveは領域の予約を行う関数で実際にleng分の要素を確保するわけではないです。

代わりに、

v.resize(leng);

とすることでうまく動くのではないかと思います。

C/C++はパフォーマンス上の理由から実行時に添字の範囲チェックなどはしないので、上のコードでも偶然動いてしまいうるんですが、Debugビルドだと実行時範囲チェックをしてくれる処理系も多いので、実はログなどに"Index is out of range"みたいな例外を出してプログラムが止まっているのではないでしょうか?本当に何も言わずにただただデータが入っていなかったのでしょうか?

投稿2018/04/15 17:04

SAM-tak

総合スコア199

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問