C++ 在构造函数c+中打开文件+;

C++ 在构造函数c+中打开文件+;,c++,file-handling,C++,File Handling,我试图在构造函数中打开一个文件,并从其他函数写入该文件,但该文件并没有创建 #include<iostream> #include<fstream> #include<cstring> #define BAD_FILE_NAME_PATTERN "MYFILE_" #define BAD_FILE_PATH "$HOME/" class A { private: std::ofstream m_badReprtLogFil

我试图在构造函数中打开一个文件,并从其他函数写入该文件,但该文件并没有创建

#include<iostream>
#include<fstream>
#include<cstring>

#define BAD_FILE_NAME_PATTERN "MYFILE_"
#define BAD_FILE_PATH "$HOME/"


class A
{
        private:
        std::ofstream m_badReprtLogFilePtr;
        char *m_badReprtLogFilePtrName;

        public:
        void rechargeEventBadFileHandler();
        void writeToFile();
        A();
};

A::A()
{
        time_t     now = time(0);
        struct tm  tstruct;
        char dateTime[80];
        tstruct = *localtime(&now);
        strftime(dateTime, sizeof(dateTime), "%F_%H%M%S", &tstruct);
        m_badReprtLogFilePtrName = new char[strlen(BAD_FILE_NAME_PATTERN) + sizeof(dateTime)];
        strcpy(m_badReprtLogFilePtrName,BAD_FILE_PATH);
        strcat(m_badReprtLogFilePtrName,BAD_FILE_NAME_PATTERN);
        strncat(m_badReprtLogFilePtrName,dateTime,sizeof(dateTime));
        strcat(m_badReprtLogFilePtrName,".bad");
        std::cout<< "Bad File Name " << m_badReprtLogFilePtrName << std::endl;
        m_badReprtLogFilePtr.open(m_badReprtLogFilePtrName, std::ios::out | std::ios::app);
        if(!m_badReprtLogFilePtr.is_open())
        {
           std::cout<<"Error opening Bad file"<<std::endl;
        }
}

void A::writeToFile()
{
        m_badReprtLogFilePtr << "Writting to BAD FILE"<<std::endl;
}

/*
A::~A()
{
        m_badReprtLogFilePtr.close();
}
*/

int main()
{
        A obj;
        obj.writeToFile();
        return 0;
}
#包括
#包括
#包括
#定义错误的文件名模式“MYFILE”
#定义错误的文件路径“$HOME/”
甲级
{
私人:
std::of Stream m_BadreprtLogFiler;
char*m_badReprtLogFilePtrName;
公众:
void-eventbadfilehandler();
void writeToFile();
A();
};
A::A()
{
现在时间=时间(0);
struct-tm-tstruct;
字符日期时间[80];
tstruct=*本地时间(&now);
strftime(dateTime,sizeof(dateTime),%F\uh%M%S,&t结构);
m_badReprtLogFilePtrName=新字符[strlen(坏文件名模式)+sizeof(日期时间)];
strcpy(m_badReprtLogFilePtrName,BAD_FILE_路径);
strcat(m_badReprtLogFilePtrName,BAD_FILE_NAME_PATTERN);
strncat(m_badReprtLogFilePtrName、dateTime、sizeof(dateTime));
strcat(m_badReprtLogFilePtrName,“.bad”);
问题在于:

#define BAD_FILE_PATH "$HOME/"
您可以在Unix上使用
getenv(“HOME”)
,也可以在Windows上连接
getenv(“HOMEDRIVE”)
getenv(“HOMEPATH”)
的结果

e、 g.在Unix上

需要解决的问题:

  • m_badReprtLogFilePtrName
    数组的大小错误。只有名称和日期(而不是路径、扩展名和空终止字符)有空间

  • strncat(m_badReprtLogFilePtrName,dateTime,sizeof(dateTime));

    strncat
    的size参数是目标中已经存在的字符串结束后剩余的空间量。您使用的是源大小

  • 内存泄漏(析构函数应该删除
    m_badReprtLogFilePtrName

  • 您应该展开
    $HOME
    路径(
    std::getenv
    )。要使
    getenv
    正常工作,应将
    坏文件路径定义为:

    #define BAD_FILE_PATH "HOME"
    
    (看一看)

  • 您应该使用
    std::string

比如:

#include <cstdlib>
#include <cstring>
#include <iostream>
#include <fstream>
#include <string>

#define BAD_FILE_NAME_PATTERN "MYFILE_"
#define BAD_FILE_PATH "HOME"

class A
{
public:
  A();

  // ...

private:
  std::ofstream m_badReprtLogFilePtr;
  std::string m_badReprtLogFilePtrName;
};

A::A()
{
  time_t now = time(0);

  struct tm tstruct;
  char dateTime[80];
  tstruct = *localtime(&now);

  strftime(dateTime, sizeof(dateTime), "%F_%H%M%S", &tstruct);

  char *path = std::getenv(BAD_FILE_PATH);
  if (path)
    m_badReprtLogFilePtrName = std::string(path) + "/";

  m_badReprtLogFilePtrName += BAD_FILE_NAME_PATTERN;
  m_badReprtLogFilePtrName += dateTime;
  m_badReprtLogFilePtrName += ".bad";

  std::cout << "Bad File Name " << m_badReprtLogFilePtrName << "\n";

  m_badReprtLogFilePtr.open(m_badReprtLogFilePtrName.c_str(),
                            std::ios::out | std::ios::app);

  if (!m_badReprtLogFilePtr.is_open())
    std::cout << "Error opening Bad file\n";
}
#包括
#包括
#包括
#包括
#包括
#定义错误的文件名模式“MYFILE”
#定义错误的文件路径“HOME”
甲级
{
公众:
A();
// ...
私人:
std::of Stream m_BadreprtLogFiler;
std::字符串m_badReprtLogFilePtrName;
};
A::A()
{
现在时间=时间(0);
struct-tm-tstruct;
字符日期时间[80];
tstruct=*本地时间(&now);
strftime(dateTime,sizeof(dateTime),%F\uh%M%S,&t结构);
char*path=std::getenv(错误的文件路径);
如果(路径)
m_badReprtLogFilePtrName=std::string(path)+“/”;
m_badReprtLogFilePtrName+=错误的文件名模式;
m_badReprtLogFilePtrName+=日期时间;
m_badReprtLogFilePtrName+=“.bad”;

std::cout有两件事不对

一个C或C++程序(大多数代码使用C技术,即使你用C++编译器构建),也不解释“代码> $home”/代码>的含义。这取决于shell(UNIX下的),并且需要以其他方式扩展(例如使用<代码> GETEN()/COD>)。 分配给

m_badReprtLogFilePtrName
的字符数等于
strlen(坏文件名模式)+sizeof(日期时间)
strcpy()
strcat()
strncat()
调用潜在的写
strlen(坏文件名路径)+strlen strlen(坏文件名模式)+min(日期时间),sizeof dateTime)+strlen(“.bad”)+1个
字符到该缓冲区。很可能,写入的字符数超过了分配的长度,因此结果是未定义的行为

尝试使用标准的
std::string
类来管理字符串,而不是使用运算符
new
手动分配字符数组。这样,当对象被销毁时,字符串将得到很好的清理,而不是像现在这样泄漏


哦:“写作”在C++中有更多的C。请帮我一个忙,运行一次程序,然后修改程序,在打开文件时添加下面的标志。STD::iO::NoeLoad。文件在运行程序的第二次打开吗?环境变量,比如“代码> $home <代码>不是文件系统的一部分。除非你有。一个名为“$HOME”的目录,你需要自己扩展它(例如,请参见
getenv
)。我无法重现这个问题:我猜:你忘记创建目录了。Offtopic:你可以将这个strcpy/strcat部分缩短为:
snprintf(m_badReprtLogFilePtrName,“%s%s.bad”,错误的文件路径,错误的文件名,日期时间)
谢谢您提供的信息:)
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <fstream>
#include <string>

#define BAD_FILE_NAME_PATTERN "MYFILE_"
#define BAD_FILE_PATH "HOME"

class A
{
public:
  A();

  // ...

private:
  std::ofstream m_badReprtLogFilePtr;
  std::string m_badReprtLogFilePtrName;
};

A::A()
{
  time_t now = time(0);

  struct tm tstruct;
  char dateTime[80];
  tstruct = *localtime(&now);

  strftime(dateTime, sizeof(dateTime), "%F_%H%M%S", &tstruct);

  char *path = std::getenv(BAD_FILE_PATH);
  if (path)
    m_badReprtLogFilePtrName = std::string(path) + "/";

  m_badReprtLogFilePtrName += BAD_FILE_NAME_PATTERN;
  m_badReprtLogFilePtrName += dateTime;
  m_badReprtLogFilePtrName += ".bad";

  std::cout << "Bad File Name " << m_badReprtLogFilePtrName << "\n";

  m_badReprtLogFilePtr.open(m_badReprtLogFilePtrName.c_str(),
                            std::ios::out | std::ios::app);

  if (!m_badReprtLogFilePtr.is_open())
    std::cout << "Error opening Bad file\n";
}