ページ 11

fopenとfopen_sについて

Posted: 2016年4月29日(金) 09:31
by Taka-OH
カットシステム社から出版されている「openCL入門」でopenCLを学習しているものです。
以下に添付した例題があります。本ではfopenで書かれていたのですが、C++コンパイラ
(VisualStudio2015を利用)がエラーを出すので、fopen_sで書き直したところ、実行時、
エラーは出さないものの、ファイルへの書き込みができていないようで、添付ソースの
1行目を追加して、fopenでコンパイルをしたところ、問題なくファイルが作成できました。
fopen_sでどこが悪いのかが、わかりません。ご教授頂きたく、よろしくお願いいたします。
readの方は、fopen_sでできているようですが、writeの方ができていないみたいです。
コメントアウトの部分は、適宜位置を変えて、コンパイルしています。

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>

#include "bitmapStruct.h"
static int mBitmapSize;
static int
readHeader(FILE* fp, const pBmpFileHdr pBmFHdr)
{
  if (fread(pBmFHdr, sizeof(bmpFileHdr), 1, fp) != 1)
  {
  fprintf(stderr, "error: failed fread.\n");
  return -1;
}
  if (pBmFHdr->bfType != 'M' * 256 + 'B')
  {
  fprintf(stderr, "error: file is't bitmap file.\n");
  return -2;
  }
  return 0;
}

static int
writeHeader(FILE* fp, const pBmpFileHdr pBmFHdr)
{
  if (fwrite(pBmFHdr, sizeof(bmpFileHdr), 1, fp) != 1)
  {
  fprintf(stderr, "error: failed fwrite.\n");
  return -1;
  }
  return 0;
}

static int
readBody(FILE* fp, const pBmpFileHdr pBmFHdr, const pBmpInfoHdr pDib)
{
   if (fread(pDib, mBitmapSize, 1, fp) != 1)
  {
  fprintf(stderr, "error failed fread.\n");
  return -1;
  }
  if (pDib->biBitCount != 24 && pDib->biBitCount != 32)
   {
  fprintf(stderr, "errr : no 24bpp or 32bpp bitmap.\n");
  return -2;
  }
  return 0;
}

static int
writeBody(FILE* fp, const pBmpFileHdr pBmFHdr, const pBmpInfoHdr pDib)
{
   if (fwrite(pDib, mBitmapSize, 1, fp) != 1)
  {
   fprintf(stderr, "error: failed fwrite.\n");
  return -1;
   }
  return 0;
}

int readBmp(char* fName, const pBmpFileHdr pBmFHdr, pBmpInfoHdr *pDib)
{
   FILE* fp;
  struct stat statbuf;
  errno_t error;
  if (error = fopen_s(&fp, fName, "rb") != 0)
   {
  fprintf(stderr, " error: failed fopen.\n");
  return -1;
   }
  
  /*if ((fp = fopen(fName, "rb")) == NULL)
  {
  fprintf(stderr, "error: failed fopen.\n");
  return -1;
  }*/
  if (readHeader(fp, pBmFHdr) != 0)
  {
  fclose(fp);
  return -1;
  }
  if (stat(fName, &statbuf) != 0)
  {
  fprintf(stderr, "error: failed stat.\n");
  return -1;
   }
   mBitmapSize = statbuf.st_size - sizeof(bmpFileHdr);
  *pDib = (bmpInfoHdr *)malloc(mBitmapSize);
  if (readBody(fp, pBmFHdr, *pDib) != 0)
  return -1;
  fclose(fp);

   return 0;
}

int
writeBmp(char* fName, const pBmpFileHdr pBmFHdr, const pBmpInfoHdr pDib)
{
   FILE* fp;
  errno_t error;
  if (error = fopen_s(&fp, fName, "wb") != 0)
  if (writeHeader(fp, pBmFHdr) == 0)
  writeBody(fp, pBmFHdr, pDib);
  else
  fprintf(stderr, "error: failed fopen.\n");
 
  /*if((fp=fopen(fName,"wb"))!=0)
  if (writeHeader(fp, pBmFHdr) == 0)
  writeBody(fp, pBmFHdr, pDib);
  else
  fprintf(stderr, "error: failed fopen.\n");*/
  fclose(fp);
  return 0;
}

Re: fopenとfopen_sについて

Posted: 2016年4月29日(金) 13:53
by yuni
こんにちは。

聞くのももちろん必要かとは思いますが、
自分で調べる事のほうが大切かもしれません。

fopen_sとfopenは戻り値が違います。
おそらく問題はそれだけだと思います。