- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我遇到了问题。
我正在尝试创建一个文件,然后再次读取它,将值保存在一个新结构中。但是当我尝试打印这些值时,我只在 7 个值之后得到 garbaje。
我做错了什么?
或者有写限制
#include<stdio.h>
#include<stdlib.h>
struct estructura_salida
{
int num_art;
int exist;
};
int main (void)
{
fflush(stdin);
int i,j;
long reg;
struct estructura_salida listado[100];
struct estructura_salida ventas[100];
struct estructura_salida listadol[100];
struct estructura_salida ventasl[100];
for(i=0;i<100;i++)
{
listado[i].num_art = i+1;
listado[i].exist = i+20;
ventas[i].num_art = i+1;
ventas[i].exist = i+10;
}
printf("\ncargados\n");
for(i=0;i<100;i++)
{
printf("\n%i\t%i\t%i",listado[i].num_art,listado[i].exist,ventas[i].exist);
}
FILE *fp1;
FILE *fp2;
fp1 = fopen("C://stock.dbf","wt");
fp2 = fopen("C://ventas.dbf","wt");
fwrite(listado,sizeof(struct estructura_salida),200,fp1);
fwrite(ventas,sizeof(struct estructura_salida),200,fp2);
fclose(fp1);
fclose(fp2);
printf("\nleyendo el archivo");
fp1 = fopen("C://stock.dbf","rt");
fp2 = fopen("C://ventas.dbf","rt");
while(!feof(fp1))
{
fread(listadol,sizeof(listadol),1,fp1);
}
while(!feof(fp2))
{
fread(ventasl,sizeof(ventasl),1,fp2);
}
fclose(fp1);
fclose(fp2);
printf("\narchivo leido\n");
for(i=0;i<100;i++)
{
printf("\n%i\t%i\t%i",listadol[i].num_art,listadol[i].exist,ventasl[i].exist);
}
return 0;
}
这就是控制台的样子,我只是得到了 garbaje。 console
谢谢!!
最佳答案
我相信您几乎肯定在 Windows 系统上工作,因为您在 fopen()
模式下使用了 "wt"
。 t
不被 C 标准或大多数 Unix 系统识别。也因为你used fflush(stdin)
这在非 Windows 系统上基本上没有意义,但被定义为在 Windows 系统上完成或多或少有用的任务。
您的主要问题是您使用 "wt"
打开一个文本文件进行写入,但是当您使用 fwrite()
时,您正在将二进制数据写入文本文件。这意味着包含 10 或 13 的条目可能会导致困惑。
使用"wb"
(阅读时使用"rb"
)。这是 C 标准支持的,表明您正在执行二进制 I/O,而不是文本 I/O,并防止 I/O 系统对您的数据造成严重破坏。
当您只有包含 100 条记录的数组时(正如 R Sahu 在他们的 answer 中指出的那样),您也写了 200 条记录——这也不是幸福的秘诀。
您使用 while (!feof(fp1))
的循环是错误的;使用 while (!feof(file))
is always wrong .您不断读取相同的元素 — listadol[0]
和 ventasl[0]
,因为您只是将数组名称传递给 fread()
.您可以在每个文件的一个 fread()
操作中读回所有记录,或者您需要正确索引数组(例如传递 &listadol[i]
)。
严格来说,您应该验证 fopen()
调用(尤其是)是否成功。可以说,您应该对 fread()
和 fwrite()
调用执行相同的操作。 super 狂热者会检查 fclose()
调用。如果数据文件很重要,您应该这样做,以防万一磁盘空间不足,或者出现其他严重错误。
将更改放在一起,并使用 NUM_ENTRIES
来确定条目数(并将其从 100 更改为 10 以实现输出的紧凑性),我得到:
#include <stdio.h>
#include <stdlib.h>
struct estructura_salida
{
int num_art;
int exist;
};
enum { NUM_ENTRIES = 10 };
int main(void)
{
struct estructura_salida listado[NUM_ENTRIES];
struct estructura_salida ventas[NUM_ENTRIES];
struct estructura_salida listadol[NUM_ENTRIES];
struct estructura_salida ventasl[NUM_ENTRIES];
for (int i = 0; i < NUM_ENTRIES; i++)
{
listado[i].num_art = i + 1;
listado[i].exist = i + 20;
ventas[i].num_art = i + 1;
ventas[i].exist = i + 10;
}
printf("\ncargados\n");
for (int i = 0; i < NUM_ENTRIES; i++)
{
printf("%i\t%i\t%i\n", listado[i].num_art, listado[i].exist, ventas[i].exist);
}
const char name1[] = "stock.dbf";
const char name2[] = "ventas.dbf";
FILE *fp1 = fopen(name1, "wb");
FILE *fp2 = fopen(name2, "wb");
if (fp1 == NULL)
{
fprintf(stderr, "Failed to open file %s for reading\n", name1);
exit(EXIT_FAILURE);
}
if (fp2 == NULL)
{
fprintf(stderr, "Failed to open file %s for reading\n", name2);
exit(EXIT_FAILURE);
}
fwrite(listado, sizeof(struct estructura_salida), NUM_ENTRIES, fp1);
fwrite(ventas, sizeof(struct estructura_salida), NUM_ENTRIES, fp2);
fclose(fp1);
fclose(fp2);
printf("\nleyendo el archivo");
fp1 = fopen(name1, "rb");
fp2 = fopen(name2, "rb");
if (fp1 == NULL)
{
fprintf(stderr, "Failed to open file %s for reading\n", name1);
exit(EXIT_FAILURE);
}
if (fp2 == NULL)
{
fprintf(stderr, "Failed to open file %s for reading\n", name2);
exit(EXIT_FAILURE);
}
int n;
for (n = 0; fread(&listadol[n], sizeof(listadol[n]), 1, fp1) == 1; n++)
;
int m;
for (m = 0; fread(&ventasl[m], sizeof(ventasl[m]), 1, fp2) == 1; m++)
;
fclose(fp1);
fclose(fp2);
printf("\narchivo leido\n");
if (n != m)
{
fprintf(stderr, "Read different numbers of records (%d from %s, %d from %s)\n",
n, name1, m, name2);
exit(EXIT_FAILURE);
}
for (int i = 0; i < n; i++)
{
printf("%i\t%i\t%i\n", listadol[i].num_art, listadol[i].exist, ventasl[i].exist);
}
return 0;
}
最好使用一个函数来打开文件,检查失败并报告错误并退出——读者的练习。
输出是:
cargados
1 20 10
2 21 11
3 22 12
4 23 13
5 24 14
6 25 15
7 26 16
8 27 17
9 28 18
10 29 19
leyendo el archivo
archivo leido
1 20 10
2 21 11
3 22 12
4 23 13
5 24 14
6 25 15
7 26 16
8 27 17
9 28 18
10 29 19
十六进制转储程序显示这两个数据文件包含您所期望的内容:
stock.dbf:
0x0000: 01 00 00 00 14 00 00 00 02 00 00 00 15 00 00 00 ................
0x0010: 03 00 00 00 16 00 00 00 04 00 00 00 17 00 00 00 ................
0x0020: 05 00 00 00 18 00 00 00 06 00 00 00 19 00 00 00 ................
0x0030: 07 00 00 00 1A 00 00 00 08 00 00 00 1B 00 00 00 ................
0x0040: 09 00 00 00 1C 00 00 00 0A 00 00 00 1D 00 00 00 ................
0x0050:
ventas.dbf:
0x0000: 01 00 00 00 0A 00 00 00 02 00 00 00 0B 00 00 00 ................
0x0010: 03 00 00 00 0C 00 00 00 04 00 00 00 0D 00 00 00 ................
0x0020: 05 00 00 00 0E 00 00 00 06 00 00 00 0F 00 00 00 ................
0x0030: 07 00 00 00 10 00 00 00 08 00 00 00 11 00 00 00 ................
0x0040: 09 00 00 00 12 00 00 00 0A 00 00 00 13 00 00 00 ................
0x0050:
除了奇怪的 CR 或 LF 之外,没有任何可打印的字符,因此右侧的信息并不是那么有用。 (在运行 macOS 10.13.6 High Sierra 的 Mac 上测试,使用 GCC 8.2.0。)
关于c - fread 和 fwrite 函数有问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51794111/
C语言sscanf()函数:从字符串中读取指定格式的数据 头文件: ?
最近,我有一个关于工作预评估的问题,即使查询了每个功能的工作原理,我也不知道如何解决。这是一个伪代码。 下面是一个名为foo()的函数,该函数将被传递一个值并返回一个值。如果将以下值传递给foo函数,
CStr 函数 返回表达式,该表达式已被转换为 String 子类型的 Variant。 CStr(expression) expression 参数是任意有效的表达式。 说明 通常,可以
CSng 函数 返回表达式,该表达式已被转换为 Single 子类型的 Variant。 CSng(expression) expression 参数是任意有效的表达式。 说明 通常,可
CreateObject 函数 创建并返回对 Automation 对象的引用。 CreateObject(servername.typename [, location]) 参数 serv
Cos 函数 返回某个角的余弦值。 Cos(number) number 参数可以是任何将某个角表示为弧度的有效数值表达式。 说明 Cos 函数取某个角并返回直角三角形两边的比值。此比值是
CLng 函数 返回表达式,此表达式已被转换为 Long 子类型的 Variant。 CLng(expression) expression 参数是任意有效的表达式。 说明 通常,您可以使
CInt 函数 返回表达式,此表达式已被转换为 Integer 子类型的 Variant。 CInt(expression) expression 参数是任意有效的表达式。 说明 通常,可
Chr 函数 返回与指定的 ANSI 字符代码相对应的字符。 Chr(charcode) charcode 参数是可以标识字符的数字。 说明 从 0 到 31 的数字表示标准的不可打印的
CDbl 函数 返回表达式,此表达式已被转换为 Double 子类型的 Variant。 CDbl(expression) expression 参数是任意有效的表达式。 说明 通常,您可
CDate 函数 返回表达式,此表达式已被转换为 Date 子类型的 Variant。 CDate(date) date 参数是任意有效的日期表达式。 说明 IsDate 函数用于判断 d
CCur 函数 返回表达式,此表达式已被转换为 Currency 子类型的 Variant。 CCur(expression) expression 参数是任意有效的表达式。 说明 通常,
CByte 函数 返回表达式,此表达式已被转换为 Byte 子类型的 Variant。 CByte(expression) expression 参数是任意有效的表达式。 说明 通常,可以
CBool 函数 返回表达式,此表达式已转换为 Boolean 子类型的 Variant。 CBool(expression) expression 是任意有效的表达式。 说明 如果 ex
Atn 函数 返回数值的反正切值。 Atn(number) number 参数可以是任意有效的数值表达式。 说明 Atn 函数计算直角三角形两个边的比值 (number) 并返回对应角的弧
Asc 函数 返回与字符串的第一个字母对应的 ANSI 字符代码。 Asc(string) string 参数是任意有效的字符串表达式。如果 string 参数未包含字符,则将发生运行时错误。
Array 函数 返回包含数组的 Variant。 Array(arglist) arglist 参数是赋给包含在 Variant 中的数组元素的值的列表(用逗号分隔)。如果没有指定此参数,则
Abs 函数 返回数字的绝对值。 Abs(number) number 参数可以是任意有效的数值表达式。如果 number 包含 Null,则返回 Null;如果是未初始化变量,则返回 0。
FormatPercent 函数 返回表达式,此表达式已被格式化为尾随有 % 符号的百分比(乘以 100 )。 FormatPercent(expression[,NumDigitsAfterD
FormatNumber 函数 返回表达式,此表达式已被格式化为数值。 FormatNumber( expression [,NumDigitsAfterDecimal [,Inc
我是一名优秀的程序员,十分优秀!