-1

我有一个简单的问题让我整天发疯。我试图在不知道当前用户名的情况下打开当前用户桌面上的文件。

这个想法是我将使用对 API 的 GetCurrentUser 调用来获取用户名。然后格式化一个字符串以给出完整路径目录,并将该变量传递给 fopen 以打开文件。这是我正在处理的代码,我没有收到编译器错误,它编译得很好,但没有写入文件。

int main() {

  char pathName[200]; // declaring arrays

  char userName[100];

  DWORD userNameSize = sizeof(userName); // storage for user name

  if (!GetUserName(userName, &userNameSize)) { cout << "user not found"; }

  else { cout "hello" << userName;} // error checking


  // format for Windows 7 desktop
  sprintf(pathName, "\"C:\\Users\\%s\\Desktop\\text.txt\"", userName); 

  cout << pathName << "\n"; // confirms correct location

  const char* fileLocation = pathName; // pointer to full path to pass into fputs

  const char* test = "test";  // test information to write to file to confirm

  FILE *f = fopen(fileLocation,"a+"); // open file in append mode

  fputs(test, f); // write to file

  fclose(f); // flush and exit

  return 0;
}

也许我需要使用不同的调用来格式化字符串?或者将 fileLocation 声明为不同的变量类型?

我对 C++ 相当陌生,如果有任何提示可以帮助我能够在当前用户的桌面上打开文件,我将不胜感激。谢谢。

针对 JERRY 的建议进行编辑:

这就是我最近的评论所指的:

#include <iostream>
#include <cstring>
#include <string>
#include <conio.h>
using namespace std;

string location ("C:\\Users\\testuser\\Desktop\\log.dat");

char cstr = char* [location.size()]; //This is a problematic line

strcpy (cstr, location.c_str());

void write(const char* c)
{
    const char* fileLocation = cstr;
    //const char* fileLocation = g_pathName;
    FILE *f = fopen(fileLocation,"a+"); // This is the problematic line right here. 
    if(f!=NULL)
    {
        fputs(c,f); // append to end of file 
        fclose(f);  // save so no entries are lost without being flushed
        }
}


int main ()
{  
  write("test");

  cout << "done";

  _getch();

  return 0;
}
4

3 回答 3

2

您在第 9 行缺少一个分号,上面写着:

...{ cout << "user not found" }...

分号在 C++ 中不是可选的,工作程序需要它们。此外,如评论中所述,您不需要在文件名周围加上引号。

于 2012-09-17T20:47:00.030 回答
1

我会使用SHGetSpecialFolderPath来自shlobj.h

const char *szFileName = "text.txt";
const char *szContent = "test string";

char szPath[_MAX_PATH];

SHGetSpecialFolderPath(NULL, szPath, CSIDL_DESKTOPDIRECTORY, FALSE);

strcat(szPath, "\\");
strcat(szPath, szFileName);

FILE *pFile = fopen(szPath, "a+");

if(pFile != NULL)
{
    fputs(szContent, pFile);
    fclose(pFile);
}
于 2012-09-17T22:12:51.307 回答
0

我会使用SHGetKnownFolderPathFOLDERID_Desktop 来获取桌面的路径,然后在末尾添加一个文件名。您几乎肯定也想对std::strings 进行操作,然后在创建全名后,使用.c_str成员函数将名称检索为 C 样式字符串。除非您有一个非常具体的理由不这样做,否则最好使用 astd::ofstream而不是 C 样式FILE *(在这种情况下,如果您的编译器是最新的,您可能可以std::string直接将对象作为名称传递)。

编辑:一些快速演示代码创建并写入用户桌面上的文件:

#include <windows.h>
#include <Shlobj.h>
#include <objbase.h>
#include <string>
#include <fstream>

#pragma comment(lib, "ole32.lib")
#pragma comment(lib, "shell32.lib")

std::string GetKnownFolderPath(REFKNOWNFOLDERID f) {
    PWSTR sys_path;

    SHGetKnownFolderPath(f, 0, NULL, &sys_path);

    DWORD size = WideCharToMultiByte(CP_ACP, 0, sys_path, -1, 0, 0, NULL, NULL);

    std::string path(size, ' ');

    WideCharToMultiByte(CP_ACP, 0, sys_path, -1, &path[0], size, NULL, NULL);

    // We're finished with the string the system allocated:
    CoTaskMemFree(sys_path);

    // WideCharToMultiByte leaves space for a NUL terminator we don't need
    path.resize(path.size()-1);   
    return path;
}

int main() {
    std::string path(GetKnownFolderPath(FOLDERID_Desktop));

    path += "\\test.txt";

    std::ofstream test(path.c_str());

    test << "This is a test";

    return 0;
}
于 2012-09-17T20:47:29.127 回答