开发者

C++ fwrite doesn't write to text file, have no idea why?

开发者 https://www.devze.com 2023-04-01 16:03 出处:网络
I have this code that basically reads from file and creates new file and write the content from the source to the destination file. It reads the buffer and creates the file, but fwrite

I have this code that basically reads from file and creates new file and write the content from the source to the destination file. It reads the buffer and creates the file, but fwrite

doesn't write the content to the newly created file, I have no idea why.

here is the code. (I have to use only this with _sopen, its part of legacy code)

#include <stdio.h>
#include <stdlib.h>
#include <io.h>
#i开发者_运维问答nclude <fcntl.h>
#include <string>
#include <share.h>
#include <sys\stat.h>


int main () {
  std::string szSource = "H:\\cpp\\test1.txt";
  FILE* pfFile;
  int iFileId = _sopen(szSource.c_str(),_O_RDONLY, _SH_DENYNO, _S_IREAD);
  if (iFileId >= 0) 
     pfFile = fdopen(iFileId, "r");
   //read file content to buffer 
   char * buffer;
   size_t result;
   long lSize;
   // obtain file size:
   fseek (pfFile , 0 , SEEK_END);
   lSize = ftell (pfFile);
   fseek(pfFile, 0, SEEK_SET);
 //   buffer = (char*) malloc (sizeof(char)*lSize);
   buffer = (char*) malloc (sizeof(char)*lSize);

   if (buffer == NULL)
   {

       return false;
   }

   // copy the file into the buffer:
   result = fread (buffer,lSize,1,pfFile);   
   std::string szdes = "H:\\cpp\\test_des.txt";
   FILE* pDesfFile;
   int iFileId2 = _sopen(szdes.c_str(),_O_CREAT,_SH_DENYNO,_S_IREAD | _S_IWRITE);
  if (iFileId2 >= 0) 
     pDesfFile = fdopen(iFileId2, "w+");

   size_t f = fwrite (buffer , 1, sizeof(buffer),pDesfFile );
   printf("Error code: %d\n",ferror(pDesfFile));

   fclose (pDesfFile);

  return 0;
}

You can make main file and try it see if its working for you .

Thanks


Change your code to the following and then report your results:

int main () {
  std::string szSource = "H:\\cpp\\test1.txt";
  int iFileId = _sopen(szSource.c_str(),_O_RDONLY, _SH_DENYNO, _S_IREAD);
  if (iFileId >= 0) 
  {
    FILE* pfFile;
    if ((pfFile = fdopen(iFileId, "r")) != (FILE *)NULL)
    {
      //read file content to buffer 
      char * buffer;
      size_t result;
      long lSize;
      // obtain file size:
      fseek (pfFile , 0 , SEEK_END);
      lSize = ftell (pfFile);
      fseek(pfFile, 0, SEEK_SET);
      if ((buffer = (char*) malloc (lSize)) == NULL)
        return false;

      // copy the file into the buffer:
      result = fread (buffer,(size_t)lSize,1,pfFile);   
      fclose(pfFile);

      std::string szdes = "H:\\cpp\\test_des.txt";
      FILE* pDesfFile;
      int iFileId2 = _sopen(szdes.c_str(),_O_CREAT,_SH_DENYNO,_S_IREAD | _S_IWRITE);
      if (iFileId2 >= 0) 
      {
        if ((pDesfFile = fdopen(iFileId2, "w+")) != (FILE *)NULL)
        {
          size_t f = fwrite (buffer, (size_t)lSize, 1, pDesfFile);
          printf ("elements written <%d>\n", f);

          if (f == 0)
            printf("Error code: %d\n",ferror(pDesfFile));

          fclose (pDesfFile);
        }
      }
    }
  }

  return 0;
}

[edit]

for other posters, to show the usage/results of fwrite - what is the output of the following?

#include <stdio.h>

int main (int argc, char **argv) {
   FILE *fp = fopen ("f.kdt", "w+");

   printf ("wrote %d\n", fwrite ("asdf", 4, 1, fp));

   fclose (fp);
}

[/edit]


sizeof(buffer) is the size of the pointer, i.e. 4 and not the number of items in the buffer

If buffer is an array then sizeof(buffer) would potentially work as it returns the number of bytes in the array.


The third parameter to fwrite is sizeof(buffer) which is 4 bytes (a pointer). You need to pass in the number of bytes to write instead (lSize).

Update: It also looks like you're missing the flag indicating the file should be Read/Write: _O_RDWR

This is working for me...

   std::string szdes = "C:\\temp\\test_des.txt"; 
   FILE* pDesfFile; 
   int iFileId2;
   err = _sopen_s(&iFileId2, szdes.c_str(), _O_CREAT|_O_BINARY|_O_RDWR, _SH_DENYNO, _S_IREAD | _S_IWRITE); 
   if (iFileId2 >= 0)  
      pDesfFile = _fdopen(iFileId2, "w+"); 

   size_t f = fwrite (buffer , 1, lSize, pDesfFile ); 
   fclose (pDesfFile); 


Since I can't find info about _sopen, I can only look at man open. It reports:

int open(const char *pathname, int flags);
int open(const char *pathname, int flags, mode_t mode);

Your call _sopen(szdes.c_str(),_O_CREAT,_SH_DENYNO,_S_IREAD | _S_IWRITE); doesn't match either one of those, you seem to have flags and 'something' and modes / what is SH_DENY?

What is the result of man _sopen?

Finally, shouldn't you close the file descriptor from _sopen after you fclose the file pointer?

Your final lines should look like this, btw :

if (iFileId2 >= 0) 
{
  pDesfFile = fdopen(iFileId2, "w+");
  size_t f = fwrite (buffer , 1, sizeof(buffer),pDesfFile ); //<-- the f returns me 4
  fclose (pDesfFile);
}

Since you currently write the file regardless of whether or not the fdopen after the O_CREAT succeeded. You also do the same thing at the top, you process the read (and the write) regardless of the success of the fdopen of the RDONLY file :(


You are using a mixture of C and C++. That is confusing. The sizeof operator does not do what you expect it to do.


Looks like @PJL and @jschroedl found the real problem, but also in general:

Documentation for fwrite states:

fwrite returns the number of full items actually written, which may be less than count if an error occurs. Also, if an error occurs, the file-position indicator cannot be determined.

So if the return value is less than the count passed, use ferror to find out what happened.

The ferror routine (implemented both as a function and as a macro) tests for a reading or writing error on the file associated with stream. If an error has occurred, the error indicator for the stream remains set until the stream is closed or rewound, or until clearerr is called against it.

0

精彩评论

暂无评论...
验证码 换一张
取 消