【问题标题】:Random writing order to output file?输出文件的随机写入顺序?
【发布时间】:2013-11-21 22:58:54
【问题描述】:

我编写了一个将信息写入文件的程序。文件的输出不是我期望的顺序。我有一个标题行和三个带有数字信息的附加行。标题首先出现,然后是第三行、第一行和第二行。

请注意,文件是以a 模式打开的,而不是a+。根据各种消息来源,像fseek() 这样的重新定位运算符应该被忽略。有一段时间,我实际上是在写第三行 before 第一行 after 那一行。如果省略fseek() 行,则第三行实际上写在标题之前..

如果fseek()函数被留下注释(不管是aa+模式)输出如下图所示。

我写了一些代码来看看输出应该如何写。文件中的文字肯定不是它应该的样子..

我尝试在每次写入之前使用fseek() 函数查找EOF 之前的位置,但无济于事。

我还注意到,如果我使用fflush(writeP),我会得到与包含fseek() 函数相同的效果。如图所示,文件仍然乱序,但第三行不再位于标题行之前。

我错过了什么?

void quickSortHelper(int* num, long startTime, long endTime, int size){
FILE *writeP = fopen(QUICKSORT_FILE, "a");
    if(writeP == NULL){
        fputs("Error opening file\n", stderr);
        exit(1);
    }

static int times = 0;
long deltaT; //change in time

if(size < STEPSIZE){//first time, write header to file
    printf("Writing header!\n");
    fprintf(writeP, " --- QUICKSORT ---\nCOUNT\tTIME\tMEDIAN\n");
}

deltaT = (clock() - startTime)/(CLOCKS_PER_SEC/1000);
//fflush(writeP);
fseek(writeP, -1, SEEK_END);

printf("Writing: %d\t%ld\t%d\n", size, deltaT, findMedian(num, size));
fprintf(writeP, "%d\t%ld\t%d\n", size, deltaT, findMedian(num, size));

if(++times == 3)
    fclose(writeP);

return;

}

注释fseek() 行后,输出为:

【问题讨论】:

  • 你能发布更多代码吗?这是单个函数的一部分还是return 来自哪里?
  • 我发布了更多内容以包含函数参数,如果这有帮助的话,但程序确实没有更多内容。基本上,我将快速排序算法的开始和结束时间发送给这个函数。 quickSort 算法被调用 3 次,排序要求越来越多(显示在输出的左列中)。这是撰写本文时唯一打开的文件。我调用该函数一次并以append 模式打开文件。我返回调用函数,文件保持打开状态。调用此函数三次后,我关闭文件并退出。
  • 您必须在文件中工作吗?我的意思是我会更容易将数据从文件中提取出来并在缓冲区或其他东西中使用它,而不是输出它或将它写回文件并输出它?
  • 我只是写入那个文件。我排序的数据是按照您的建议完成的。

标签: c file pointers output fseek


【解决方案1】:

在调用函数的前 3 次,您没有关闭 writeP。因此,文件由几个FILE 句柄打开,这些句柄在退出时关闭。 "a" 仅适用于相同的 FILE 句柄或数据已到达磁盘时。

【讨论】:

  • 我尝试只打开一次文件,但遇到了一个奇怪的问题。如果我声明 FILE 指针并在某些 IF 语句中打开文件,该语句仅在第一次运行程序时评估为真,我只会得到一行 OUTPUT,就好像文件已关闭或其他东西一样。不过你说的还是有道理的。我今天在这个程序的其他部分工作太久了,甚至无法尝试更改它。谢谢。
  • 你的意思是static FILE *writeP; if (!writeP) writeP = fopen(...);。这应该有效(但很难看)。建议在外面打开,作为参数或者全局变量传递。
  • 我试过了,但编译器抱怨 writeP 不是常量。
  • 真的吗?或者你试过static FILE *writeP = fopen(...)(这是被禁止的)?
  • 我认为这是我尝试过的。如果后者不合法,第一个建议怎么可能合法?首先,您将指针声明为静态,然后对其进行更改。静态数据可以定义一次吗?
【解决方案2】:

问题在于您在每次函数调用时打开同一个文件,但仅在第三次调用时关闭它。我建议将文件打开和关闭逻辑移出该函数,并将FILE * 句柄作为参数传递给函数;这也将避免必须将要关闭的调用号硬编码到该函数中。

所以你调用函数的地方看起来像这样:

FILE *writeP = fopen(QUICKSORT_FILE, "w"); // "a" changed to "w"
if (!writeP) {
    perror(QUICKSORT_FILE);
    exit(1);
}
// perhaps write the header into the file here
for (int i = 0; i < 3; ++i) {
    // do the quicksort
    write_quicksort_results(writeP, …);
}
(void) fclose(writeP);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-01-07
    • 1970-01-01
    • 2012-10-24
    • 2016-09-06
    • 2015-01-26
    • 2020-08-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多