Path, Filename & ofstream

Ok well before starting, I'd like to say that I'm not a pro and that I would really appreciate it if I could get precise and well explained answers. (I posted on some other forums and all they did was giving me one or two technics name that I had no idea what they were).


So I have this simple program that reads information from a .txt, does stuff with does numbers, and exports the results to .txt


To INPUT exe, we have to drop the .txt on the .exe

1
2
3
4
5
6
7
8
9
10
..........
int main(int argc, char **argv)

	{
		//Variables			
			ifstream read;
			
		//Opens the numbers txt
			read.open (argv[1]);  //Open ifstream
..........


To export, it "should" export to same folder as the exe.

1
2
3
4
5
6
7
..........
	write.open ("results.txt");  //open txt file to write to

	xport(); //prints the table in the txt file

	write.close(); //close the result file
..........



So now, my two problems are:

1. When I use this main parameter to get drag&drop .txt file, the ofstream doesn't work like before... It won't export if I don't put a PRECISE path. Therefore, when I leave it like it is now, it does nothing.

2. I want to be able to see the filename of the .txt, and if possible the path of the .txt too. When I print argv[1], it gives me both at the same time, and I'm not quite sure how I could CUT it in two.


Thanks in advance for the help
~Ph0X
Drag and drop will always execute the program in the caller's directory, not the directory of your exe. Meaning: every relative path in your program is now relative to the caller's current directory, which could be anywhere.

You can use a few simple std::string methods to split things up:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
std::string ExtractDirectory( const std::string& path )
  {
  return path.substr( 0, path.find_last_of( '\\' ) +1 );
  }

std::string ExtractFilename( const std::string& path )
  {
  return path.substr( path.find_last_of( '\\' ) +1 );
  }

std::string ChangeExtension( const std::string& path, const std::string& ext )
  {
  std::string filename = ExtractFilename( path );
  return ExtractDirectory( path ) +filename.substr( 0, filename.find_last_of( '.' ) ) +ext;
  }


You can use them easily:
1
2
3
4
5
6
7
8
9
10
11
12
int main( int argc, char **argv )
  {
  if (argc < 2) return 0;

  ifstream read;
  read.open( argv[1] );
  ...

  ofstream write;
  write.open( ExtractDirectory( argv[0] ) +"results.txt" );
  ...
  }


An example for changing a file extension:
1
2
3
4
5
6
7
8
  // Remove the extension
  cout << ChangeExtension( "example.txt", "" ) << endl;

  // Change an extension
  cout << ChangeExtension( "example.txt", ".doc" ) << endl;

  // Add an extension
  cout << ChangeExtension( "example.txt.", ".asc" ) << endl;


Hope this helps.
Wow, thanks alot! it worked almost perfectly. The filename worked great, and the directory output worked great too.

Only one problem

When I go to do
write.open( ExtractDirectory( argv[0] ) +"results.txt" );

I get

1
2
3
4
5
6
7
8
9
Compiling...
SizeCalculation.cpp
c:\....\sizecalculation.cpp(140) : error C2664: 'void std::basic_ofstream<_Elem,_Traits>::open(const wchar_t *,std::ios_base::openmode,int)' : cannot convert parameter 1 from 'std::string' to 'const wchar_t *'
        with
        [
            _Elem=char,
            _Traits=std::char_traits
        ]
        No user-defined-conversion operator available that can perform this conversion, or the operator cannot be called


Any ideas?

Thanks again for the three functions up there! very useful.
My bad. I always forget that the stupid STL streams don't take std::string as filename arguments. It should be:
 
write.open( string( ExtractDirectory( argv[0] ) +"results.txt" ).c_str() );

Pain in the nose, isn't it?
Topic archived. No new replies allowed.