VC++とVC#のテキストファイルなどの参照の違いについて

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
豆電球

VC++とVC#のテキストファイルなどの参照の違いについて

#1

投稿記事 by 豆電球 » 9年前

C++を勉強中なのですが、欲しかった機能をC++で書けなかったのでC#にちょっと手を出してしまっています。
VC++ではテキストファイルなどのリソースはプロジェクトの見かけ上のフォルダ(実際は.cppと同一のフォルダ)にあるとファイル名だけで参照してくれますが、VC#は.csと同一フォルダに置いておいてもファイル名だけではダメでフルパスなどを要求されます。
初心者にとってはなんか面倒だなと思いますが、後発のVC#がこのような仕様になっているということは何かデメリットがあるからだと思うのですが、これはどのようなことを考えてこのような仕様になっているのでしょうか?
よろしくお願い致します。

C#に手を出してしまった理由は、IDManagerというパスワード管理ソフトを使っているのですがIEに上手く張り付かないので(firefoxはOK)あるサイトにIEでログインするアプリをC++(WinHTTPなど)で作ろうと思ったのですが全体的な知識が不足している為に上手く作れませんでした。
検索の途中でC#でグーグルの検索窓に値を入れるコードを見つけたのでそれを利用して作ったのですが、あまりに簡単に短いコードで出来てしまったので二股かけている状態です。

豆電球

Re: VC++とVC#のテキストファイルなどの参照の違いについて

#2

投稿記事 by 豆電球 » 9年前

VisualStudio2013です。
書き忘れました。すみません。

Idra

Re: VC++とVC#のテキストファイルなどの参照の違いについて

#3

投稿記事 by Idra » 9年前

どのクラスを使ってファイルを読み込もうとしているのか書いてないけど、
絶対パスでも相対パスでも動作するように作られてることが多いと思う。
豆電球さんが試したときはファイルの置き場所が間違ってたんじゃないかな

djann
記事: 27
登録日時: 12年前

Re: VC++とVC#のテキストファイルなどの参照の違いについて

#4

投稿記事 by djann » 9年前

実行プロセスには「作業ディレクトリ(カレントディレクトリ)」というものが存在します。相対パスをプログラム中に書いていた場合、その作業ディレクトリからの相対パスと認識されます。

実行ファイルを直接起動した場合等は、基本的にその実行ファイルが置いてある位置が作業ディレクトリとして実行されます。

VC++上から実行した場合には、基本的に「プロジェクトファイルが置いてあるディレクトリ」が作業ディレクトリとして設定されます。もちろんこれはプロジェクトの設定から変更することが可能です(プロジェクトのプロパティ -> 構成プロパティ -> デバッグ内に設定項目が存在します)。
VC#の場合は分かりませんが、私が試しに作成した空のプロジェクトでは、この作業ディレクトリの設定は空でした。その際は、VC++でもそうだったと思いますが、ビルドして出力される実行ファイルの場所が作業ディレクトリとして開始されます(プロジェクトファイルの場所/bin/Debug(Release)/ですね)。


なのでVC#でもVC++と同様に作業ディレクトリを設定するか、出力された実行ファイルが置かれる場所を基準に外部リソースを配置することで、望んだ結果が得られるのではないかと思われます。

なお「プロジェクトの見かけ上のフォルダ(実際は.cppと同一のフォルダ)」というのはよく分かっておりません。

豆電球

Re: VC++とVC#のテキストファイルなどの参照の違いについて

#5

投稿記事 by 豆電球 » 9年前

Idraさん、djannさん、ありがとうございます。
そして、情報不足で申し訳ありません。

「プロジェクトの見かけ上のフォルダ(実際は.cppと同一のフォルダ)」(説明不足で申し訳ありません)
VC++の場合、ソリューションエクスプローラに「Source Files」「Resource Files」というフォルダがあり、cppファイルは「Source Files」に入れて、テキストファイルなどは「Resource Files」に入れているのですが、ウィンドウズのエクスプローラで表示されるフォルダではなく、ソリューションエクスプローラだけのフォルダのようで実際には(ウィンドウズのエクスプローラ上では)同じフォルダにファイルが置かれています。

この.cppと同じフォルダにテキストファイル
.csと同じフォルダにテキストファイル
という状態でVC++とVC#の設定を変えたのは、後発のVC#の方がこれが良い設定なのだという事で変更したのかなと思ってしまいました。
しかし、お二人の回答をみて特にデメリットがあってという事ではないようですので、ファイル指定が多い場合はプロジェクトにパスを設定しようと思います。

ありがとうございました。

コードは下記のようなものです。
C#

コード:

using System;
using System.IO;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace CS_FileOperation
{
    class c1
    {
        static void Main(string[] args)
        {
            FileStream reader = null;
            try
            {
                reader = new FileStream(@"c:\XXXXXXXXXXXXXXXXXXXXXXX\CS_FileOperation\data1.txt", FileMode.Open);
            }
            catch (Exception)
            {
 
            }
            finally
            {
                if (reader != null)
                    reader.Close();
            }
            Console.ReadKey(true);
        }
    }
}
C++

コード:

#pragma warning(disable:4996)
#include <iostream>
#include <fstream>
#include <vector>
#include <string>
#include <sstream>
int main()
{
	std::string filename("data1.txt");
	std::ifstream ifs(filename, std::ios::in);
	if (ifs.fail()){ printf("fail\n"); return -1; }
	ifs.close();
	std::system("pause");
	return 0;
}

YuO
記事: 947
登録日時: 14年前
住所: 東京都世田谷区

Re: VC++とVC#のテキストファイルなどの参照の違いについて

#6

投稿記事 by YuO » 9年前

解決済みとされていますが,この場合だと,C#に関しては別解があります。

まず,data1.txtのプロパティで「出力ディレクトリにコピー」を「常にコピーする」若しくは「新しい場合はコピーする」に設定しておきます。
すると,ビルドプロセス中で自動的にファイルがコピーされます。
オフトピック
プロジェクトのフォルダ中に入れてこの設定にすると,フォルダ構成ごとコピーされます
そして,ファイルを開くときは実行ファイルのパスを元に指定します。
この方法であれば,ディレクトリ構成が変わっても問題なく実行できます。
オフトピック
絶対パスを記述する方法は特定の環境だけでしか実行できなくなってしまうので,勉強段階であってもできるだけ避けた方がよいです。
下記の様に,システムから情報を得て,得られたディレクトリからの相対パスを絶対パスに変換し,それを使う必要があります。

コード:

using System;
using System.IO;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
 
namespace CS_FileOperation
{
    class c1
    {
        static void Main(string[] args)
        {
            // CS_FileOperation.c1クラスを含むアセンブリのディレクトリにあるdata1.txtを読み込む場合
            // 実行開始ファイルのパスであるなら,typeof(c1).Assemblyの代わりにSystem.Reflection.Assembly.GetEntryAssembly()を利用。
            using (var stream = File.Open(Path.Combine(Path.GetDirectoryName(typeof(c1).Assembly.Location), "data1.txt"))
            {
                // 処理本体。
                // catchする必要がなければtry-catch-finallyよりもusingを推奨。
            }
            Console.ReadKey(true);
        }
    }
}

豆電球

Re: VC++とVC#のテキストファイルなどの参照の違いについて

#7

投稿記事 by 豆電球 » 9年前

YuOさん、ありがとうございます。
使ったことの無いものがいくつかあったのでググって弄っていました。
単純にworking directoryを設定せずに、この様な変化に強いコードを推奨しているのかもしれませんね。
ググっている中で、System.IO.Path系のものも色々あって面白かったです。
ありがとうございました。

閉鎖

“C言語何でも質問掲示板” へ戻る