fclose,fopen和fwrite编写多个文件的问题

时间:2013-08-20 22:16:59

标签: c++ file-io fopen fwrite fclose

我有一个程序可以记录来自串口的数据。每隔一段时间,我就想分割文件,使数据日志不会变得非常大。问题是,在我重新创建FILE *并尝试写入它之后,程序崩溃了。之前没有编译器错误/警告...

程序会在第一个时间间隔创建一个日志,但是一旦创建新数据日志,它就会在fwrite崩溃。

首先,初始化/声明。

char * DATA_DIR = "C:\DATA";
sprintf(path,"%s%s%s",DATA_DIR,curtime,".log"); //curtime is just the current time in a string
FILE * DATA_LOG = fopen(path, "wb+");   

稍后在一个循环中

if(((CURRENT_TIME-PREVIOUS_TIME) > (SEC_IN_MINUTE * MINUTE_CHUNKS) ) && (MINUTE_CHUNKS != 0) && FIRST_TIME == 0) //all this does is just checks if its time to make a new file
{
    fclose(DATA_LOG); //end the current fileread

    char * path; 
    char curtime[16];

    //gets the current time and saves it to a file name
    sprintf(curtime , "%s" , currentDateTime());
    sprintf(path,"%s%s%s",DATA_DIR,curtime,".log");

    DATA_LOG = fopen(path, "wb+"); //open the new file

    //just some logic (not relevant to problem)
    PREVIOUS_TIME = CURRENT_TIME; 
    newDirFlag = 1;
}
fwrite(cdata , sizeof(char) , numChars , DATA_LOG); //crashes here. cdata, sizeof, and numChars don't change values

任何想法为什么会发生这种情况?我很难过。

2 个答案:

答案 0 :(得分:1)

一些问题,路径没有分配内存(你正在写一些随机内存地址,这是坏事)。您还应该检查fwrite fopen的返回值是否有错误。如果有一次使用perror,那么您就知道问题所在。很可能是fopen失败了,或者你写了path来破坏你的筹码。

同样使用snprintf它比仅仅sprintf更容易受到缓冲区溢出的影响。

编辑:刚刚看到你的评论是c ++。为什么不使用std::stringfstream呢?它们比你现在做的更安全(也可能更容易)。

答案 1 :(得分:0)

您的主要问题是char * path;没有分配内存。这意味着您正在写入内存中的某些RANDOM [1]位置。

我建议您使用char path[PATH_MAX]; - 这样您就不必担心分配并随后为您的路径释放存储空间。

或者,您可以使用:

stringstream ss;

ss << DATA_DIR << currentDateTime() << ".log";
string path = ss.str();
fopen(path.c_str(), "wb+")

这是一个更加C ++风格的解决方案。

[1]随机而言,我并不是指一个真正的随机数,而是恰好位于堆栈中该位置的一些未知值。它几乎总是不是存储字符串的好地方。