gpt4 book ai didi

c - fwrite 在最后一次迭代中不起作用

转载 作者:行者123 更新时间:2023-12-02 00:04:15 26 4
gpt4 key购买 nike

我只是想对一组数字进行排序(虽然我发布的代码不是我要使用的方法,但我确实需要将代码中的输出写入二进制文件).
一切正常,除了“ordenar”的最后一次迭代:当我在订购后再次打印回数字时,除了最后一行之外的所有内容都已订购,我已验证 ordenar 已正确完成,并且 fwrite() 在最后一次迭代中返回值 10,但它似乎没有写入最后的输出。

代码是:

#define _CRT_SECURE_NO_DEPRECATE
#define SIZE 10
#define MAX 10

#include <time.h>
#include <stdio.h>
#include <stdlib.h>

int numbers[SIZE];


int genera_numeros() {
unsigned long i, j;
FILE *file;

file = fopen("number.dat", "wb");
if (!file) {
perror("fopen");
return 1;
}

srand(time(0));
for (i = 0; i < MAX; i++) {
for (j = 0; j < SIZE; j++) {
numbers[j] = rand()%1000;
printf("%i ", numbers[j]);
}
fwrite(numbers, sizeof(int), SIZE, file);
printf("\n");
}
fclose(file);
return 0;
}


int imprime_numeros() {
unsigned long i, j;
int numbers[SIZE];
FILE *file;

file = fopen("number.dat", "rb");
if (!file) {
perror("fopen");
return 1;
}

for (i = 0; i < MAX; i++) {
fread(numbers, sizeof(int), SIZE, file);
for (j = 0; j < SIZE; j++) {
printf("%i ",numbers[j]);
}
printf("\n");
}
fclose(file);
return 0;
}

int compare (const void * a, const void * b)
{
return ( *(int*)a - *(int*)b );
}


int ordenar(FILE* file, long int num_bloque)
{
int byte=0, written=0;
fseek(file, num_bloque * sizeof(int) * SIZE, SEEK_SET);
fread(numbers, sizeof(int), SIZE, file);
qsort (numbers, SIZE, sizeof(int), compare);
fseek(file, num_bloque * sizeof(int) * SIZE, SEEK_SET);
byte=ftell(file);
written=fwrite(numbers, sizeof(int), SIZE, file);
return 0;
}


int main(int argc, char* argv[]) {
FILE *file;
file = fopen("number.dat", "rb+");
long int i;

genera_numeros();
printf("\n\n Los numeros son:\n\n");
imprime_numeros();
printf("\n\n Ordenando...");

for (i=0; i<MAX; i++)
{
ordenar(file, i);
}

printf("\n\n Los numeros son:\n\n");
imprime_numeros();
printf("\n");

fclose(file);
system("PAUSE");
return 0;
}

最佳答案

对于初学者来说,因为我不知道你的代码到底应该做什么,所以删除给你段错误的东西。
你关你file都带有 imprime_numeros()和在main() .删除一个或另一个,您的程序就可以运行。



这是我对你的问题的解决方案,没有对最后一行进行排序。只需使用

再进行一次迭代
for(i=0;i<MAX+1;i++){

并且有效。我目前正在研究解决方案的“为什么”部分。
编辑 1
我花了一段时间,但现在是这样:
在你的 main() 你有 FILE* file=fopen(..)这是您唯一不检查它是否正确打开的地方。每次你的程序第一次运行时 - 它找不到那个文件和 file在 main() 中设置为 NULL。

然后它愉快地继续并调用函数 genera_numeros()它打开自己的文件(并创建 numbers.dat btw...)但在本地范围内,因为在 genera_numeros() 之外file仍然是 NULL。

因此它创建一个文件,填充它并继续到 imprima_numeros()打开之前创建的 numbers.dat (仍在本地范围内,您在使用后关闭此文件)。

然后是ordenar部分,事情开始变得有趣。
ordenar(file, i)获取您的 NULL 文件并...因段错误而崩溃。
(有趣 部分,也是让我受骗的地方,这将不会在您第二次运行该程序时发生,因为 numbers.dat 将保留在上一次运行中)。

编辑 2. 最后是的,我只是花了 2 个非付费的深夜时间来查找其他人代码中的错误。我可能就是那个人……总之……
问题在于多次打开同一个文件。
Bu 我的意思是,当你通过打开不存在的文件修复以前的错误,或者只是第二次运行程序时,你在 main() 中打开一个文件,然后用 imprime_numeros 打开和关闭这个文件几次。和 genera_numeros .那应该是 implementation-defined行为。
问题是在你最后一次调用 ordenar() 之后在你的循环中你用 imprime_numeros 重新打开它并写入最后排序的行在磁盘上的文件中尚不可见。这将在您关闭文件流后完成。因此,在向文件写入排序的最后一行之前,您会看到文件的状态。

现在为什么我的 MAX+1有效的解决方案是它强制永久写入最后一行,因此它在 imprime_numeros() 打开的文件中可见.
这就是几乎的全部。
请注意,通过添加 MAX+1,您将获得大小为 440 字节的文件(我有 4 字节 int),它应该是 400。
我也忘了提到如何解决这个问题,但你可以通过我的描述找到它。
提示
fclose(file) 在读取它之前。

所有正在阅读此答案的人,我将感谢您对语法和风格进行编辑。已经很晚了,这让我付出了很多代价。

关于c - fwrite 在最后一次迭代中不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19413348/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com