Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/70.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用windows.h和C截断文件_C_Struct_Replace_Binaryfiles_Truncate - Fatal编程技术网

使用windows.h和C截断文件

使用windows.h和C截断文件,c,struct,replace,binaryfiles,truncate,C,Struct,Replace,Binaryfiles,Truncate,我的任务是创建一个随机访问/二进制列表,并允许程序使用windows.h库及其句柄函数从中删除目标记录(struct)。 我写了下面的代码试图截断文件,而在文件的末尾擦除某些东西似乎是有效的,中间处理文件的部分似乎是在制造麻烦,而我却被难住了。 void erase_record(FILE *file, stct buffer, char *target) { HANDLE h; int jump=0; int mark; stct s; file = fopen("list.txt","rb+

我的任务是创建一个随机访问/二进制列表,并允许程序使用windows.h库及其句柄函数从中删除目标记录(struct)。 我写了下面的代码试图截断文件,而在文件的末尾擦除某些东西似乎是有效的,中间处理文件的部分似乎是在制造麻烦,而我却被难住了。
void erase_record(FILE *file, stct buffer, char *target)
{
HANDLE h;
int jump=0;
int mark;
stct s;
file = fopen("list.txt","rb+");
s.artist = (char*)malloc(20*(sizeof(char)));
s.name = (char*)malloc(20*(sizeof(char)));
while(1)
{
    jump++;
    fread(&buffer,sizeof(buffer),1,file);
    if(!strcmp(target,buffer.name)) // did we find a match? 
    {
        jump--;
        fread(&buffer,sizeof(buffer),1,file); // then check one more time.
        if(feof(file)) // is the match right before the eof?
        {
            fclose(file);
            h=CreateFile(L"list.txt",GENERIC_WRITE | GENERIC_READ,0,0,OPEN_ALWAYS,FILE_ATTRIBUTE_NORMAL,0);
            SetFilePointer(h,(jump)*sizeof(buffer),NULL,FILE_BEGIN); // truncate from last
            SetEndOfFile(h);
            CloseHandle(h);
            break;
        }
        else // is it in middle of the file?
        {
            mark = jump; // we mark the struct we wanted to delete
            while(1)
            {
                s.shelf = buffer.shelf;
                s.artist = buffer.artist;
                s.name = buffer.name;
                jump++;
                fread(&buffer,sizeof(buffer),1,file); // find the end of the file first
                if(feof(file))// when we DO find the end..
                {
                    break;
                }
            }
            fclose(file);
            h=CreateFile(L"list.txt",GENERIC_WRITE | GENERIC_READ,0,0,OPEN_ALWAYS,FILE_ATTRIBUTE_NORMAL,0);
            SetFilePointer(h,(jump)*sizeof(buffer),NULL,FILE_BEGIN); //deleting it!
            SetEndOfFile(h);
            CloseHandle(h);
            file = fopen("list.txt","rb+");
            fseek(file,mark*sizeof(buffer),SEEK_SET); // we erase the marked struct
            fwrite(&s,sizeof(s),1,file);
            break;
        }
    }
}
}


有谁能分享一些关于哪里出了问题的见解吗?

。显然,我忘了一些非常重要的事情。这就是关闭文件(如
fclose()
)。人们总是说这个问题会导致问题,这就是一个例子。

我认为问题与下面的问题有关。当你说下列话时,硬币掉了下来:

我用ferror()检查了一下,但它返回了0。节目刚刚结束 在我尝试运行我提到的部分和运行之后崩溃 通过调试工具,我得到“0x577514cf处未处理的异常” (msvcr100d.dll)在Project 5.exe中:0xC0000005:访问冲突读取 位置0xCDCD。“

0xcdcdcd

“…来自C运行时内部的调试值 当您在调试构建中分配内存块时,它是 初始化为这个伪值,希望捕获bug。 0xCDCD为非NULL,并且永远不是有效的内存指针 ().

因此,这意味着某些东西无法分配内存

我要做的第一件事是检查
malloc()
语句不返回
NULL

接下来,检查
fopen()
的返回值不是
NULL

接下来是以下几行

s.artist = buffer.artist;
s.name = buffer.name;
他们正在引入内存泄漏。您不是在这里复制字符串,而是在复制指针。因此,您以前为
artist
name
使用的
malloc()
内存现在已丢失,您将永远无法
释放它。例如,我想您可能打算使用
strcpy()
将字符串从
缓冲区
复制到
s.name

另外,您是否正在编写指向文件的指针?如果读回
buffer.name
,并且它是一个指针(我认为这一定是因为您将其视为指针),那么您正在读回创建文件时有效的任何旧地址,,但在本例中,您的程序可能完全无效然后尝试取消引用该指针将导致您头痛

我建议在将结构写入文件时,不要写入指针
s.name
s.artist
,而是将实际字符串写入文件。然后从文件中读回字符串,然后为它们创建指针

fwrite(&s,sizeof(s),1,file); // OOPS! You wrote pointer values to a file. 
// These pointers will be invalid addresses in the next program instance!
相反,你可以做一些像

fwrite(all non pointer members of struct)
fwrite(&s.label, LABEL_LEN, 1, file); // Note, include the string null-terminator
fwrite(&s.name, NAME_LEN, 1, file);   // Note, include the string null-terminator
然后在阅读时,将标签和名称作为实际字符串读回

fread(all non pointer members of struct)
fread(&stringBuffer, LABEL_LEN, 1, file);
s.label = strdup(stringBuffer);
fread(&stringBuffer, NAME_LEN, 1, file);
s.name= strdup(stringBuffer);

后来记得
free()
s.name
s.label
,因为
strdup()
已经创建了一个副本,你有责任处理它。

非常小的一点没有回答你的问题,但我注意到你投下了
malloc()
的回归。请参阅避免这样做的原因:)谢谢,它实际上非常具有信息性。它不回答您的问题,但您可以使用
fseek(文件,大小(缓冲区),SEEK__END)
然后
ftell()
来为您节省一个while循环,而不是遍历所有记录来查找最后一条记录吗?所有读/写/寻道是否成功确定。。。如果选中
ferror()
,是否检测到任何错误?从检查来看,似乎不错。。。我看不出它为什么不起作用。如果你能说出你所看到的错误或症状,可能会对原位有更多的了解?这实际上是一个很好的建议。我可能对代码太失望了,因为我尝试了各种不同的方法,但后来忘记了简化它。它似乎没有表现出任何怪癖,所以我真的很困惑失败的症状是什么?我将对此进行研究,但到目前为止,通过简单的fclose()操作文件似乎有效。感谢您的帮助虽然
fclose()
ing您的文件可能有助于解决这一问题,但我认为您可能存在内存泄漏,除非您在执行
s.name/label=buffer.name/label
之前释放
s.name/label
,而我没有发现它?同时存储指向文件的指针也是一个坏主意。你不能保证这些在程序的另一个实例中有任何意义:)谢谢你的评论。正如我们所说,我正在改进代码,尽管我没有提到我的程序最初使用“wb”处理程序重新打开文件(因此所有旧数据都会被删除)