0

I want to find a way to save a file to a desktop. Since every user has different user name, I found following code will help me find the path to someone else’s desktop. But how can I save the following to desktop? file.open(appData +"/.txt"); doesn't work. Can you please show me an example?

#include <iostream>
#include <windows.h>
#include <fstream>
#include <direct.h>
#include <shlobj.h>
using namespace std;
int main ()
{
    ofstream file;  

    TCHAR appData[MAX_PATH];
    if (SUCCEEDED(SHGetFolderPath(NULL,
                                  CSIDL_DESKTOPDIRECTORY | CSIDL_FLAG_CREATE,
                                  NULL,
                                  SHGFP_TYPE_CURRENT,
                                  appData)))

    wcout << appData << endl; //This will printout the desktop path correctly, but
    file.open(appData +"file.txt"); //this doesn't work
    file<<"hello\n";
    file.close();
    return 0;
}

Microsoft Visual Studio 2010, Windows 7, C++ console

UPDATED:


#include <iostream>
#include <windows.h>
#include <fstream>
#include <direct.h>
#include <shlobj.h>
#include <sstream> 
using namespace std;
int main ()
{
    ofstream file;  

    TCHAR appData[MAX_PATH];
    if (SUCCEEDED(SHGetFolderPath(NULL,
                                  CSIDL_DESKTOPDIRECTORY | CSIDL_FLAG_CREATE,
                                  NULL,
                                  SHGFP_TYPE_CURRENT,
                                  appData)))

    wcout << appData << endl; //This will printout the desktop path correctly, but
    std::ostringstream file_path; 
    file_path << appData << "\\filename.txt";//Error: identifier file_path is undefined

    file.open(file_path.str().c_str()); //Error:too few arguments in function call
    return 0;
}
Learner_51
  • 1,075
  • 3
  • 22
  • 38
  • Windows paths are with `\\` no? And you also need a name for the file. – Tudor Feb 16 '12 at 11:09
  • 3
    I think you are adding two character pointers. You want to concatenate the strings. Suggest using a stringstream, and pushing both onto it? Also, you don't actually seem to be putting in a file name, just the .txt extension. Haven't used Windows much recently, but won't it strop a bit about this? – BoBTFish Feb 16 '12 at 11:11
  • @Tudor C++ and C can use `/` for directory separators, even on Windows! You're right about the file name though, `.txt` is a lousy name. – Mr Lister Feb 16 '12 at 11:14
  • Aside from (I think) `.txt` not being a valid file name on Windows, your actual problem is with C++, not the OS. You cannot concatenate C strings the way you want to. No offense meant, but have you considered reading an introductory [C++ book](http://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list)? – sbi Feb 16 '12 at 11:22
  • @NewGuy You also need to decide which of the statements should be executed if the `SHGetFolderPath` call succeeds. You currently perform the `wcout` if it succeeds, and then the rest of the statements unconditionally. Is that what you want? – Mr Lister Feb 16 '12 at 11:44

4 Answers4

3

You cannot concatenate TCHAR array using appData +"/.txt". Use a stringstream to construct the path and extract the full path of the file from it:

#include <sstream>

...

std::ostringstream file_path;
file_path << appData << "\\filename.txt";

file.open(file_path.str().c_str());

EDIT:

The following compiles, and executes correctly, for me with VS2010:

#include <iostream>
#include <windows.h>
#include <fstream>
#include <direct.h>
#include <shlobj.h>
#include <sstream>
#include <tchar.h>
using namespace std;
int main ()
{
    ofstream file;  

    TCHAR appData[MAX_PATH];
    if (SUCCEEDED(SHGetFolderPath(NULL,
                                  CSIDL_DESKTOPDIRECTORY | CSIDL_FLAG_CREATE,
                                  NULL,
                                  SHGFP_TYPE_CURRENT,
                                  appData)))

    wcout << appData << endl;
    std::basic_ostringstream<TCHAR> file_path;
    file_path << appData << _TEXT("\\filename.txt");

    file.open(file_path.str().c_str());
    file<<"hello\n";
    file.close();

    return 0;
}
hmjd
  • 120,187
  • 20
  • 207
  • 252
  • it says file_path is undefined in `file_path << appData << "\\filename.txt";`? not sure why. and `file.open(file_path.str().c_str());` says too few arguments in function call – Learner_51 Feb 16 '12 at 11:26
  • @NewGuy, did you `#include ` and add the variable `std::ostringstream file_path;` ? – hmjd Feb 16 '12 at 11:29
  • yes, I did. I have updated my original question just like the way you explained – Learner_51 Feb 16 '12 at 11:40
  • Thanks, when I created a new project and compile again, it worked. but nothing is saving in the desktop. when I print out file_path using cout, it shows a number and not a path – Learner_51 Feb 16 '12 at 11:51
  • @NewGuy, updated answer using `TCHAR` for `ostringstream` character type and using `_TEXT()` macro for appending the file name. Also `#include `. If you are building for UNICODE environment `TCHAR` will be wide string so use `wcout`. If not building for UNICODE `TCHAR` will be `char` and use `cout`. – hmjd Feb 16 '12 at 11:56
0
file.open(appData +"/.txt");

In this file path there is no filename.

Also this function call is invalid. You should pass the second parameter as a open type.

file.open(appData +"/file.txt", fstream::out); 

is the correct one.

Batuhan Tasdoven
  • 798
  • 7
  • 19
  • 1
    However, + on a TCHAR array does not concatenate strings, it'll just add pointers , and you end up with a wild pointer – nos Feb 16 '12 at 11:15
  • Thanks for showing me with an example. but when I use `file.open(appData +"/file.txt", fstream::out);` it says, `"/file.txt"` can't be used in that way. Error: expression must have integarl or enum type – Learner_51 Feb 16 '12 at 11:17
  • I think `ios::out` is the default for `std::ostream`. There's no need to pass it explicitly. – sbi Feb 16 '12 at 11:19
0

You should use PathAppend to concatenate paths, which will handle missing and/or extra set of backslash (\) characters.

Ajay
  • 18,086
  • 12
  • 59
  • 105
0

I am not sure whether this is available:

file.open("%userprofile%\\Desktop\\file.txt", fstream::out);

You may try.

qpalz
  • 71
  • 2
  • 7