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

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

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

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

Q&A

解決済

1回答

892閲覧

ファイルパスを受け取り、ファイルの拡張子とファイル名を表示しようとするとエラーになる。

ryohasegawa

総合スコア437

C++

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

0グッド

0クリップ

投稿2017/07/16 05:24

編集2017/07/16 05:42

###問題
下のコードはファイルのパスを受け取りそのパスをもとにファルの拡張子とファイル名を表示するプログラムを書いて動いていたんですが、急にエラーがでるようになりました。
発生箇所は、get_ext(fpath)get_filename(fpath)で発生していると思います。

###エラー
イメージ説明
により ハンドルされない例外が 0x753CA9F2 で発生しました (test.exe 内): Microsoft C++ の例外: std::out_of_range (メモリの場所 0x003EF600)。 が発生しました

###ソース
main.cpp

C++

1#include <iostream> 2#include <fstream> 3#include <string> 4 5#include "Fileinfo.hpp" 6 7using namespace std; 8 9 10int main() { 11 string fpath; // ファイルパス保管 12 string err; 13 14 cout << "ファイルをドロップしてください。\n"; 15 cin >> fpath; // パス入力 16 17 if (!fpath.empty()) // 開いたファイルの中身が空じゃなかったら 18 { 19 cout << "ファイルを受け取りました。\n"; 20 21 cout << "ファイルの拡張子:" << get_ext(fpath) << "\n"; 22 cout << "ファイルの名前:" << get_filename(fpath) << "\n"; 23 } 24}

Fileinfo.hpp

hpp

1#pragma once 2#include <string> 3 4int _path(std::string fpath) { 5 int path_i = fpath.find_last_of("\\") + 1; // ファイルパスから、最後のディレクトリ名までも文字数取得 6 return path_i; 7} 8int _ext(std::string fpath) { 9 int ext_i = fpath.find_last_of("."); // ファイルパスから、最後の.までの文字数取得 10 return ext_i; 11} 12 13std::string get_ext(std::string path) { 14 std::string extname = path.substr(_ext(path)); // 拡張子取得 15 return extname; 16} 17std::string get_filename(std::string path) { 18 std::string filename = path.substr(_path(path), _ext(path) - _path(path)); // ファイル名取得 19 return filename; 20} 21

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

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

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

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

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

guest

回答1

0

ベストアンサー

こんにちは。

ファイル名に\\.(ドット)が含まれていないということはないですか?
その場合、path_iやext_iが非常に大きな値になるので、そこをsubstrするとout_of_range 例外になると思います。

投稿2017/07/16 06:18

Chironian

総合スコア23272

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

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

ryohasegawa

2017/07/16 06:28

ファイル名というのは、get_extやget_filenameに渡しているfpathに含まれているかという事ですか?
Chironian

2017/07/16 07:11

「fpath自体に'\'や'.'が含まれていないのでは?」という意味です。
ryohasegawa

2017/07/16 07:17

含まれています。 ファイルのパスを渡しているので、C:\Users\・・・・という形です。 色々ためしたのですが、デスクトップのファイルの場合は動作するんですが、ファイル構造が複雑になっているとエラーが発生します。このことから Chironian さんの回答が正しいという事が分かりました。 長いパスでもエラーを出さずに実行するようにするにはどうすればいいですか?
Chironian

2017/07/16 08:14

std::stringのfind系関数は、見つからなかったら、std::string::nposを返します。find_last_ofの戻り値が、std::string::nposと等しかったら、各get_xxx()関数は0を返却すればとりあえず、落ちなくはなると思います。 しかし、当然ファイル名や拡張子を適切に抽出できないはずです。 手元のWindows 10/msvc 2015でやってみました。 3000文字程の長さのパスでもちゃんと抽出できました。 恐らく長さの問題ではないと思います。本当にfpathに'.'(ドット)は含まれていますか?
ryohasegawa

2017/07/16 13:14 編集

今分かった事が一点ありました。 長さの問題ではなかったです。空白が混じっているとだめみたいです。 例えば、新しいフォルダ という名前ならいいんですが、新しい フォルダ という名前はエラーになるみたいです。
ryohasegawa

2017/07/18 01:24

ありがとうございます。 getline を勉強してきます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問