使用 fread 从 .txt 文件中读取 unsigned char 给出不同的值
Reading unsigned char from .txt file using fread give different values
我截取了以下代码以从 .txt 文件中读取 16 个无符号字符值。
#include<stdio.h>
#include<stdlib.h>
int main()
{
int i, j, k, load_size;
unsigned char *buf;
load_size = 16;
buf = (unsigned char *)malloc(load_size);
FILE *fin;
fin = fopen("demo_input1.txt", "r");
fread(buf, 1, load_size, fin);
for(i=0;i<16;i++){
printf("%d ", *buf);
buf++;
}
system("PAUSE");
}
文件 'demo_input1.txt' 包含值 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16。但是我在控制台值中得到输出 49 32 50 32 51 32 52 32 53 32 54 32 55 32 56 32。任何人都可以告诉我这里出了什么问题来帮助我吗?谢谢
另一种方法是使用 fgets()
将整行读取到缓冲区,使用 space 作为分隔符换行,然后将字符串转换为整数并存储它们,或者打印出来。
char buf[300];
int a[30],i=0;
while(fgets(buf,sizeof(buf),fin))
{
char *p = strtok(buf," ");
i = 0;
while( p != NULL)
{
a[i] = atoi(p);
printf("%d ",a[i]);
i++;
p = strtok(NULL," ");
}
}
PS:当使用fgets()
时,您需要预定义大数组来保存您的输入,否则可能会导致错误的结果。
fread
用于读取原始输入。由于您的文件是格式化文本,请使用以下内容:
int nums[SIZE];
int count = 0;
while( fscanf(fin, "%d", nums + count) == 1 ) {
if(++count == SIZE) break; /* More than expected numbers in file */
}
稍后您可以使用以下方式打印:
for(i = 0; i < count; i++) {
printf("%d ", nums[i]);
}
fscanf
是一种从文件中读取格式化输入的方法。您可以使用原始代码段中显示的 malloc
、walking pointers
或根据您的要求。
发生的事情是完全正确的,但不是你所期望的。发生什么了?您从文件中读取 1 个字节,放入 char
,然后使用 %d
输出它,它将输出为十进制。看看一个ascii table,如果你读char
1
,它的ASCII值是49
,32
是space,50
是 2
,依此类推。您不能像那样只读取普通数字,您的代码将 %d
替换为 %c
仅适用于二进制文件,但不适用于人类可读文件。
您想使用 fread
而不是 fscanf
,它的工作方式类似于 scanf
,但从文件中读取。在那里你可以指定读取一个整数,从而得到没有 spaces 的整数。这些你可以检查它们是否小于 256
,如果是,则转换为 char.
正在将 space 的 ascii 值视为 32(ASCII for space)。
只需在 for 循环中做一个简单的更改。
而不是 %d 使用 %c
for(i=0;i<16;i++)
{
printf("%c ", *buf);
buf++;
}
我截取了以下代码以从 .txt 文件中读取 16 个无符号字符值。
#include<stdio.h>
#include<stdlib.h>
int main()
{
int i, j, k, load_size;
unsigned char *buf;
load_size = 16;
buf = (unsigned char *)malloc(load_size);
FILE *fin;
fin = fopen("demo_input1.txt", "r");
fread(buf, 1, load_size, fin);
for(i=0;i<16;i++){
printf("%d ", *buf);
buf++;
}
system("PAUSE");
}
文件 'demo_input1.txt' 包含值 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16。但是我在控制台值中得到输出 49 32 50 32 51 32 52 32 53 32 54 32 55 32 56 32。任何人都可以告诉我这里出了什么问题来帮助我吗?谢谢
另一种方法是使用 fgets()
将整行读取到缓冲区,使用 space 作为分隔符换行,然后将字符串转换为整数并存储它们,或者打印出来。
char buf[300];
int a[30],i=0;
while(fgets(buf,sizeof(buf),fin))
{
char *p = strtok(buf," ");
i = 0;
while( p != NULL)
{
a[i] = atoi(p);
printf("%d ",a[i]);
i++;
p = strtok(NULL," ");
}
}
PS:当使用fgets()
时,您需要预定义大数组来保存您的输入,否则可能会导致错误的结果。
fread
用于读取原始输入。由于您的文件是格式化文本,请使用以下内容:
int nums[SIZE];
int count = 0;
while( fscanf(fin, "%d", nums + count) == 1 ) {
if(++count == SIZE) break; /* More than expected numbers in file */
}
稍后您可以使用以下方式打印:
for(i = 0; i < count; i++) {
printf("%d ", nums[i]);
}
fscanf
是一种从文件中读取格式化输入的方法。您可以使用原始代码段中显示的 malloc
、walking pointers
或根据您的要求。
发生的事情是完全正确的,但不是你所期望的。发生什么了?您从文件中读取 1 个字节,放入 char
,然后使用 %d
输出它,它将输出为十进制。看看一个ascii table,如果你读char
1
,它的ASCII值是49
,32
是space,50
是 2
,依此类推。您不能像那样只读取普通数字,您的代码将 %d
替换为 %c
仅适用于二进制文件,但不适用于人类可读文件。
您想使用 fread
而不是 fscanf
,它的工作方式类似于 scanf
,但从文件中读取。在那里你可以指定读取一个整数,从而得到没有 spaces 的整数。这些你可以检查它们是否小于 256
,如果是,则转换为 char.
正在将 space 的 ascii 值视为 32(ASCII for space)。
只需在 for 循环中做一个简单的更改。 而不是 %d 使用 %c
for(i=0;i<16;i++)
{
printf("%c ", *buf);
buf++;
}