在C ++中格式化数组和字符串的问题

时间:2012-09-17 20:43:03

标签: c++

我遇到一个简单的问题,一直让我疯狂。我试图在当前用户的桌面上打开一个文件而不知道当前用户的名字。

我的想法是,我将使用对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;
}

3 个答案:

答案 0 :(得分:2)

你在第9行丢失了一个分号:

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

分号在C ++中不是可选的,你需要它们用于工作程序。另外,如评论中所述,您不需要引用文件名称。

答案 1 :(得分:1)

我使用shlobj.h中的SHGetSpecialFolderPath

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);
}

答案 2 :(得分:0)

我会使用SHGetKnownFolderPath和FOLDERID_Desktop来获取桌面路径,然后在末尾添加文件名。您几乎肯定也希望在std::string上进行操作,然后在创建全名时,使用.c_str成员函数将名称检索为C风格的字符串。除非你有真正具体的理由否则,你最好还是使用std::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;
}