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

时间:2015-11-06 09:50:15

标签: 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_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;
}

我遇到了问题,问题在于路径,但如何解决这个问题

3 个答案:

答案 0 :(得分:1)

问题在于:

#define BAD_FILE_PATH "$HOME/"

您可以在Unix上使用getenv("HOME")或在Windows上连接getenv("HOMEDRIVE")getenv("HOMEPATH")的结果。

e.g。在Unix上

strcpy(m_badReprtLogFilePtrName,getenv("HOME"));
strcat(m_badReprtLogFilePtrName,"/");

答案 1 :(得分:1)

要解决的问题:

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

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

    strncat的大小参数是字符串末尾之后留在目标中的空间量。 您正在使用来源尺寸

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

  • 您应该展开$HOME路径(std::getenv)。 getenv工作BAD_FILE_PATH应定义为:

    #define BAD_FILE_PATH "HOME"
    

    (看看getenv on cppreference.com)。

  • 您应该使用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";
}

可能有效(当然还有很多其他事情需要改进)。

答案 2 :(得分:0)

有一些问题。

C或C ++程序(大多数代码使用C技术,即使您使用C ++编译器构建它)也不解释$HOME的含义。这取决于shell(在unix下),需要以其他方式扩展(例如使用getenv())。

分配给m_badReprtLogFilePtrName的字符数等于strlen(BAD_FILE_NAME_PATTERN) + sizeof(dateTime)strcpy()strcat()strncat()调用可能会将strlen(BAD_FILE_PATH) + strlen(BAD_FILE_NAME_PATTERN) + min(strlen(dateTime), sizeof dateTime) + strlen(".bad") + 1个字符写入该缓冲区。可能性是,写入的字符数超过了分配的长度,因此结果是未定义的行为。

尝试使用标准new类来管理字符串,而不是手动分配带有运算符std::string的字符数组。然后,当对象被破坏时,字符串将被很好地清理,而不是像当前那样泄露。

哦:&#34;写作&#34;拼写为一个&#39;。