Hello All;

I am trying to make a copy of a file in another file using C. But the content of the file should be repeted the quantity of times of the lines of a third file

{
int num = 0;
int x;
char cont;
FILE *file;
file = fopen("string.csv","r");//w= write r=read a=alterar
        if(file == NULL){
        printf("Arquivo não encontrado!\n");
        getchar();
        return 0;}
        while( (cont=fgetc(file))!= EOF ){
            if(cont == '\n')
              num--;}
              printf("Existem %d linhas no arquivo\n", num);
        fclose(file);
FILE *file2, *file3;
file2 = fopen("string.txt","r");//w= write r=read a=alterar
        if(file2 == NULL){
        printf("Arquivo não encontrado!\n");
        getchar();
        return 0;}
file3 = fopen("string2.txt","w");//w= write r=read a=alterar    
char texto[1000];//The problem is the repetition
        while(fgets(texto,1000,file2)!= NULL){
        while{
        for(x=0;x<=num;x++){
        fputs(texto,file3);
        }
        fclose(file3);  
  return 0; 

Can anyone to help me ?

Thanks !

Recommended Answers

All 14 Replies

I would sincerely cut the program into functions.
One function would do nothing but count lines in a file (using any technique you wish).
One function would copy from source to destination based on the number of lines counted.
Avoid printing (or screen writes) inside of the functions.
Please forgive some of this style as it has been a number of decades since I wrote C code.
Also, you may need to change some of the header use based on your compiler.

#include "stdafx.h"
#include <stdio.h>
#include <string.h>

int GetLinesInFile(char* pstrFileName)
{
   FILE* pFile = fopen(pstrFileName, "r");
   int ch = '\t';
   int intNumLines = 0;

   do
   {
      ch = fgetc(pFile);
      if ('\n' == ch)
      {
         intNumLines++;
      }
   } while (ch != EOF);

   fclose(pFile);

   return intNumLines;
}

bool CopyToFileBySize(char* pstrSourceFile, char* pstrDestFile, int intNumLinesToCopy, char* pstrError)
{
   FILE* pFileSource = NULL;
   FILE* pFileDest = NULL;
   char* pstrData = new char[1024];
   bool blnRetVal = true;

   if (NULL == (pFileSource = fopen(pstrSourceFile, "r")))
   {
      strcpy(pstrError, "Bad input file");
      return false;
   }

   if (NULL == (pFileDest = fopen(pstrDestFile, "w")))
   {
      strcpy(pstrError, "Bad input file");
      return false;
   }

   for (int i = 0; i < intNumLinesToCopy; i++)
   {
      if (NULL == fgets(pstrData, 1024, pFileSource))
      {
         blnRetVal = false;
         strcpy(pstrError, "Could not copy all lines.");
         break;
      }

      fputs(pstrData, pFileDest);
   }

   fclose(pFileSource);
   fclose(pFileDest);
   delete pstrData;
   return blnRetVal;
}

int main(int argc, char** argv)
{  /* args=c:\science\data\daniweb\DW_508351.txt c:\science\data\daniweb\Fred1.txt c:\science\data\daniweb\Fred2.txt */
   int intTargetLines = 0;
   char* pstrError = new char[1024];
   char* pstrSampleFile = argv[1];
   char* pstrSourceFile = argv[2];
   char* pstrDestFile = argv[3];

   if (4 != argc)
   {
      puts("Usage: file1 file2 file3\r\nWhere file1 is the sample, file2 is the source-input, file3 is the new output file");
      return -1;
   }

   intTargetLines = GetLinesInFile(pstrSampleFile);

   if (!CopyToFileBySize(pstrSourceFile, pstrDestFile, intTargetLines, pstrError))
   {
      printf("Could not copy %d lines from %s to %s.\r\n%s\r\n", intTargetLines, pstrSourceFile, pstrDestFile, pstrError);
      return -1;
   }

   delete pstrError;
   return 0;
}

BTW -- reduce the size in the "fgets" to be at least 1 less than the buffer size.
fgets(pstrData, 1023, pFileSource))

@thines01, thank your help ! I am using cygwin to compiler, I try to do it , but I didn't have sucess. Which compiler have you used ?

I used Visual Studio (2010 and 2013).
You probably need to make minor changes.
Remove the first line "stdafx.h" and replace it with:

#include <io.h> 

I used Visual Studio 2013, but minor changes would be needed to use a different compiler.

@thines01, thank you again !

C
I put the library but the result was not positive. I change de code to c++ and de code run.

 $ gcc -g dani.c -o dani
dani.c: In function ‘CopyToFileBySize’:
dani.c:25:21: error: ‘new’ undeclared (first use in this function)
char* pstrData = new char[1024];//
                 ^

---------------------------//------------------------------------
c++

 $ g++ new.cpp -o new
 $ ./new
 Usage: file1 file2 file3
Where file1 is the sample, file2 is the source-input, file3 is the new output file

How can I change the code to C ? 

Thank a lot !

Sorry for the confusion.
It's been a long time since I wrote raw C.
This file has a .c extension and was built with Visual Studio.
I removed "new" and "delete" and inserted "malloc" and "free".
I also created a definition for BOOL.
The _CRT_SECURE_NO_WARNINGS is specifically so VS won't complain.

#define _CRT_SECURE_NO_WARNINGS

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

typedef enum {FALSE, TRUE} BOOL;

int GetLinesInFile(char* pstrFileName)
{
   FILE* pFile = fopen(pstrFileName, "r");
   int ch = '\t';
   int intNumLines = 0;

   do
   {
      ch = fgetc(pFile);
      if ('\n' == ch)
      {
         intNumLines++;
      }
   } while (ch != EOF);

   fclose(pFile);

   return intNumLines;
}

BOOL CopyToFileBySize(char* pstrSourceFile, char* pstrDestFile, int intNumLinesToCopy, char* pstrError)
{
   FILE* pFileSource = NULL;
   FILE* pFileDest = NULL;
   char* pstrData =  (char*)malloc(1024);
   BOOL blnRetVal = TRUE;
    int i=0;

   if (NULL == (pFileSource = fopen(pstrSourceFile, "r")))
   {
      strcpy(pstrError, "Bad input file");
      return FALSE;
   }

   if (NULL == (pFileDest = fopen(pstrDestFile, "w")))
   {
      strcpy(pstrError, "Bad input file");
      return FALSE;
   }

   for (i = 0; i < intNumLinesToCopy; i++)
   {
      if (NULL == fgets(pstrData, 1023, pFileSource))
      {
         blnRetVal = FALSE;
         strcpy(pstrError, "Could not copy all lines.");
         break;
      }

      fputs(pstrData, pFileDest);
   }

   fclose(pFileSource);
   fclose(pFileDest);
    free(pstrData);
   return blnRetVal;
}

int main(int argc, char** argv)
{  /* args=c:\science\data\daniweb\DW_508351.txt c:\science\data\daniweb\Fred1.txt c:\science\data\daniweb\Fred2.txt */
   int intTargetLines = 0;
   char* pstrError = (char*)malloc(1024);
   char* pstrSampleFile = argv[1];
   char* pstrSourceFile = argv[2];
   char* pstrDestFile = argv[3];

   if (4 != argc)
   {
      puts("Usage: file1 file2 file3\r\nWhere file1 is the sample, file2 is the source-input, file3 is the new output file");
      return -1;
   }

   intTargetLines = GetLinesInFile(pstrSampleFile);

   if (!CopyToFileBySize(pstrSourceFile, pstrDestFile, intTargetLines, pstrError))
   {
      printf("Could not copy %d lines from %s to %s.\r\n%s\r\n", intTargetLines, pstrSourceFile, pstrDestFile, pstrError);
      return -1;
   }
    free (pstrError);
   return 0;
}

@thines01, sorry to make stupid question, but is the first time I see the structure with arg. I have two file in my directory(string.csv, string.txt). I saw that you put de coments about the file location, but my doubt is, what is the moment on the code that the file is used ?

{  /* args=c:\science\data\daniweb\DW_508351.txt c:\science\data\daniweb\Fred1.txt c:\science\data\daniweb\Fred2.txt */

I have to put something like that ?

   args = string.csv string.txt 

Thank you.

That is to show what I typed at the command-line.
Instead of hard-coding the values in the program, I allow the user to type in the names of the files to be processed.

If you named your program "new" and you had your files in the c:\science\data\DaniWeb directory (in DOS/Windows), the command would look like this:

new c:\science\data\daniweb\SampleFile.txt c:\science\data\daniweb\FileSource.txt c:\science\data\daniweb\FileDest.txt

...running on Linux/Unix:

./new /science/data/DaniWeb/SampleFile.txt /science/data/DaniWeb/FileSource.txt /science/data/DaniWeb/FileDest.txt

Did it work?

I had problem with acess :-(

./new  /cygdrive/c/Users/aluno/Desktop/FACULDADE/PRINT/string.csv /cygdrive/c/Users/aluno/Desktop/FACULDADE/PRINT/string.txt /cygdrive/c/Users/aluno/Desktop/FACULDADE/PRINT/strin2.txt
-bash: ./new: Permission denied

Can you move the files to a directory where you have access?
Do you think the problem is reading the input or writing the output?

I will try to do this in another pc, it is a company pc.

Thank you a lot !

Although the advises (to use functions and to make the code flexible) are great, I think the issue with the original code isn't explained.

int num = 0;

So num is initialized at 0.

while( (cont=fgetc(file))!= EOF ){
    if(cont == '\n')
        num--;
}

So num will always be zero or less. I think this would have worked without the typo: num--;. It should have been num++. Haven't you ever noticed the minus sign? Perhaps the message by printf("Existem %d linhas no arquivo\n", num); was so verbose/overwhelming that it has 'hidden' the unexpected minus sign ... (?)

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.