C ++ fwrite не пишет в текстовый файл, понятия не имею, почему? - PullRequest
3 голосов
/ 01 сентября 2011

У меня есть этот код, который в основном читает из файла и создает новый файл и записывает содержимое из исходного файла в целевой файл.Он читает буфер и создает файл, но fwrite
не записывает содержимое во вновь созданный файл, я понятия не имею, почему.
вот код.(Я должен использовать только это с _sopen, частью устаревшего кода)

#include <stdio.h>
#include <stdlib.h>
#include <io.h>
#include <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;
}

Вы можете создать основной файл и попробовать, если он работает для вас.

Ответы [ 6 ]

2 голосов
/ 01 сентября 2011

Третий параметр fwrite - это sizeof (буфер), который составляет 4 байта (указатель). Вместо этого вам нужно указать количество байтов для записи (lSize).

Обновление: также похоже, что вы пропустили флаг, указывающий, что файл должен быть Чтение / Запись: _O_RDWR

Это работает для меня ...

   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); 
2 голосов
/ 01 сентября 2011

sizeof (buffer) - это размер указателя, то есть 4, а не количество элементов в буфере.

Если buffer является массивом, то sizeof (buffer) потенциально будет работать, так как он возвращает числобайтов в массиве.

1 голос
/ 01 сентября 2011

Измените свой код на следующий, а затем сообщите свои результаты:

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;
}

[править]

для других плакатов, чтобы показать использование / результаты fwrite - чтовыводится следующее?

#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]

1 голос
/ 01 сентября 2011

Поскольку я не могу найти информацию о _sopen, я могу посмотреть только на man open. Он сообщает:

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

Ваш звонок _sopen(szdes.c_str(),_O_CREAT,_SH_DENYNO,_S_IREAD | _S_IWRITE); не совпадает ни с одним из них, у вас, кажется, есть флаги, «что-то» и режимы / что такое SH_DENY?

Каков результат man _sopen?

Наконец, не следует ли закрыть дескриптор файла из _sopen после того, как вы закроете указатель файла?

Ваши последние строки должны выглядеть следующим образом, кстати:

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

Поскольку вы в настоящее время пишете файл независимо от того, успешно ли выполнено fdopen после O_CREAT. Вы также делаете то же самое наверху, вы обрабатываете чтение (и запись) независимо от успеха fdopen файла RDONLY: (

0 голосов
/ 01 сентября 2011

Похоже, @ PJL и @ jschroedl обнаружили реальную проблему, но также в целом:

Документация для fwrite состояния:

fwrite возвращает количество фактически записанных полных элементов, которое может быть меньше, чем count, если произошла ошибка.Кроме того, если возникает ошибка, индикатор положения файла не может быть определен.

Поэтому, если возвращаемое значение меньше, чем переданное число, используйте ferror , чтобы выяснить, что произошло.

Подпрограмма ferror (реализованная как функция и как макрос) проверяет наличие ошибок чтения или записи в файле, связанном с потоком.Если произошла ошибка, индикатор ошибки для потока остается установленным до тех пор, пока поток не будет закрыт или перемотан или пока не будет вызван clearerr.

0 голосов
/ 01 сентября 2011

Вы используете смесь C и C ++. Это сбивает с толку. Оператор sizeof не делает то, что вы ожидаете.

...