簡體   English   中英

從文件中讀取浮點數時 c 中的 fread() 問題

[英]fread() problem in c while reading floating point numbers from a file

使用的庫

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

創建具有隨機浮點數的數據集並在新創建的文件上打印

void createdataset(int Datasetsize,char * filename)
{
  FILE *f;
  int su;
  float v[Datasetsize];    

  srand((unsigned int)time(NULL));

  for(int i = 1; i<=Datasetsize;i++) 
    *(v+i)=((float)rand()/(float)(RAND_MAX)) * 100;

  f=fopen(filename,"wb");
  su=fwrite(v ,sizeof(float) , Datasetsize , f);
  printf("%d\n",su);
  fclose(f);
}

使用 fread() 讀取新創建的文件並顯示成功嘗試的次數。 它總是嘗試不成功,例如從 1000 條記錄中讀取 120 條記錄,並且 rest 已損壞。 我需要解決這個問題。

void loadDataset (int DataSetSize, char *filename, float *v) 
{
  FILE *fp;
  int s;

  fp = fopen( filename , "r" );
  if( fp==NULL) 
    printf("File cant be opened");

  s=fread(v , sizeof(float), DataSetSize, fp );
  printf("%d\n",s);
  for( int i=0; i<DataSetSize; i++)
  {
    printf("\t%f",*(v+i));
  }

  fclose(fp);
}

主function

void main()  
{ 
    char ch;
    FILE *fp;
    int datasetsize;
    char filein[50];
    char *fi=filein, ds; 

    printf("Enter the size of the datasetsize: ");
    scanf("%d",&datasetsize);

    float v[datasetsize];

    printf("%d\n",datasetsize);
    printf("Enter input file name: ");
    scanf("%s",filein);
    printf("%s\n",filein);
    createdataset(datasetsize,fi);
    loadDataset(datasetsize, fi, v);
}

包括conio.h你在 Windows 下

正在做

su=fwrite(v,sizeof(float), Datasetsize, f); ... s=fread(v, sizeof(float), DataSetSize, fp );

你寫和讀二進制,在 windows 下寫和讀二進制文件你需要使用“wb”和“rb”所以你需要替換

f=fopen(filename,"w"); ... fp = fopen( filename, "r" );

經過

f=fopen(filename,"wb"); ... fp = fopen( filename, "rb" );

但另見下面的評論


其中:

createdataset 中

你不檢查你是否能夠打開文件,你需要檢查fp是不是NULL ,例如使用perror來說明原因:

if (fp == NULL)
{
  perror("cannot open file to write"); 
  exit(-1);
}

也要做

*(v+i)=...

設置數組元素不是很可讀,只需執行

v[i] = ...

loadDataset你不能做

if( fp==NULL) printf("File cant be opened");

並繼續像沒有錯誤一樣,您需要停止執行 function 進行return或將 rest 放在else分支中,您可以再次使用perror來指示問題:

if (fp == NULL)
{
   perror("cannot open the file to read");
   exit(-1);
}

也要做

printf("\t%f",*(v+i));

訪問數組元素不是很可讀,只需執行

printf("\t%f", v[i]);

主要

 scanf("%d",&datasetsize);

如果用戶未輸入有效的 int,則由於未設置datasetsize ,因此行為未定義,例如:

if ((scanf("%d",&datasetsize) != 1) || (datasetsize < 1)) {
  puts("invalid size);
  return -1;
}

char filein[50]; ... scanf("%s",filein);

如果用戶輸入超過 49 個字符,則行為未定義,請執行

 scanf("%49s",filein);

甚至最好檢查scanf返回 1 以防stdin在空輸入文件中重定向

布魯諾的回答指出了基本問題。 作為演示,我在這里發布了工作代碼,因為評論中不可能:

#include<stdio.h>
#include<stdlib.h>
#include<conio.h>
#include<time.h>
void createdataset(int Datasetsize, char *filename, float *v)
{
    FILE *f;
    int su;

    f = fopen(filename, "wb");
    if (!f)
    {
        printf("Error creating file. Program aborted...\n");
        abort();
    }

    printf("Writing %d entries to file \"%s\".\n", Datasetsize, filename);
    srand((unsigned int)time(NULL));
    for (int i = 1; i <= Datasetsize; i++)
    {
        *(v + i) = ((float)rand() / (float)(RAND_MAX)) * 100;
        printf("\t%f\n",*(v+i));
    }
    su = fwrite(v, sizeof(float), Datasetsize, f);
    printf("Wrote %d floats to file\n", su);
    fclose(f);
}

void loadDataset(int DataSetSize, char *filename, float *v)
{
    FILE *fp;
    int s;
    fp = fopen(filename, "rb");
    if (fp == NULL)
    {
        printf("File cant be opened");
        return;
    }

    s = fread(v, sizeof(float), DataSetSize, fp);
    printf("Read data set composed of %d entries.\n", s);
    for (int i = 0; i < DataSetSize; i++)
    {
        printf("\t%f\n", *(v + i));
    }

    fclose(fp);
}

int main(int argc, char *argv[])
{
    char ch;
    FILE *fp;
    int datasetsize;
    char filein[50];
    char *fi = filein, ds;

    printf("Enter the size of the datasetsize: ");
    scanf("%d", &datasetsize);
    printf("%d\n", datasetsize);

    float v_out[datasetsize];
    float v_in[datasetsize];

    printf("Enter input file name: ");
    scanf("%s", filein);
    printf("%s\n", filein);

    createdataset(datasetsize, fi, v_out);
    loadDataset(datasetsize, fi, v_in);

    int errors=0;
    for (int i=0; i<datasetsize; i++)
        if (v_in[i] != v_out[i])
        {
            printf("Error in/out in position %d, v_in=%f, v_out=%f\n", i, v_in[i], v_out[i]);
            errors++;
        }

    printf("Completed with %d error(s).\n", errors);
}

我修復了打印件以獲得更易讀的外觀並添加了錯誤檢查(即使比較浮點數不完全正確)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM