0

I tried to make the following code.

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

void main()
{
  FILE *fp1,*fp2,*fp3;
  int n,i,size;
  printf("Enter no.of digits: ");
  scanf("%d",&size);
  fp1=fopen("NUMBER.txt","w");
  printf("Enter the numbers: \n");
  for(i=0;i<size;i++)
  {
    fflush(stdin);
    scanf(" %d",&n);
    fputc(n,fp1);
  }
  fclose(fp1);
  
  fp1=fopen("NUMBER.txt","r");
  fp2=fopen("EVEN.txt","w");
  fp3=fopen("ODD.txt","w");
  while((n=fgetc(fp1))!=EOF)
  {
    if(n%2==0)
    fputc(n,fp2);
    else
    fputc(n,fp3);
  }
  fclose(fp1);
  fclose(fp2);
  fclose(fp3);

  fp1=fopen("NUMBER.txt","r");
  fp2=fopen("EVEN.txt","r");
  fp3=fopen("ODD.txt","r");
  
  printf("The content of number file are: ");
  while((n=fgetc(fp1))!=EOF)
  printf(" %d",n);
  
  printf("\nThe content of even file are: ");
  while((n=fgetc(fp2))!=EOF)
  printf(" %d",n);
  
  printf("\nThe content of odd file are: ");
  while((n=fgetc(fp3))!=EOF)
  printf("  %d",n);

  fclose(fp1);
  fclose(fp2);
  fclose(fp3);
}

The problem I face is that the contents of the files are in hex or binary. I want it to be readable with text editor not a hex editor. The other problem I face is the scanf() doesn't accept 3 digit numbers. The output is given below.

Enter no.of digits: 5 Enter the numbers: 123 34 456 67 789 The content of number file are: 123 34 200 67 21 The content of even file are: 34 200 The content of odd file are: 123 67 21

I tried to write the following code:

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

int main()
{
    FILE *fp1,*fp2,*fp3;
    int size,n,a,b;
    printf("Enter the size: ");
    scanf("%d",&size);
    fp1=fopen("numbers1.txt","w");
    fp2=fopen("even1.txt","w");
    fp3=fopen("odd1.txt","w");
    
    printf("Enter the integers: ");
    
    for(int i=0;i<size;i++)
    {
      scanf("  %d",&n);
      //putc(n,fp1); reads as 12, 234 etc but digits in file is not visible
      fprintf(fp1," %d\n",n);//reads 12, 234 as 12234 but digits in file are visible
      
    }
    
    fclose(fp1);
    fp1=fopen("numbers1.txt","r");
    
    n=getc(fp1);
    
    while(n!=EOF)
    {
        if(n%2==0)
        putc(n,fp2);
        
        else if(n%2==1)
        putc(n,fp3);
        
        n=getc(fp1);
    }

    
    fclose(fp1);
    fclose(fp2);
    fclose(fp3);
    
    
    return 0;
}

In the above code the content in the files are in text, but the odd and even files read char by char. The contents of odd, even and number files are given blow.

odd file: 133577

even file: 2 4 46 6 8

Number file: 123 34 456 67 78

Please help me

SachC
  • 5
  • 2
  • 5
  • 2
    Look into `fprintf` instead of `fputc`. – AKX May 26 '21 at 17:53
  • You do know that [`fgetc`](https://en.cppreference.com/w/c/io/fgetc) reads a single *character* and not a number? So the input "123" will be the *three* characters `'1'`, `'2'` and `'3'`. – Some programmer dude May 26 '21 at 17:54
  • I don't know to rectify my problem @Someprogrammerdude. Could you please send a corrected version of my code if you can? – SachC May 26 '21 at 18:02
  • Byte storage. `456` modulo `256` is the `200` you are reading, and `789` modulo `256` is the `21` you are reading. – Weather Vane May 26 '21 at 18:08
  • Don't `fflush(stdin)`: https://stackoverflow.com/a/22902085/140750 – William Pursell May 26 '21 at 18:23
  • Ok @WeatherVane – SachC May 26 '21 at 18:34
  • Why does it modulo with 256 and how to rectify it @WeatherVane. I am a newbie in file handling. – SachC May 26 '21 at 18:38
  • Ok @WilliamPursell, will rectify it. – SachC May 26 '21 at 18:40
  • You read the input values with `scanf` but `fputc` writes *one character* to file. That byte storage can hold data in the range 0..255 and so the data is truncated modulo 256. – Weather Vane May 26 '21 at 18:42
  • I request some one to rectify my code. I have no idea how to rectify it. It would be really helpful for me. Thank you. – SachC May 26 '21 at 18:43
  • You can't store one litre in a half-litre jug. The first comment suggests using `fprintf`. – Weather Vane May 26 '21 at 18:45
  • I tried to use fprintf() @WeatherVane. But it writes into the file char by char. It writes into the file as '1' '2' '3' instead of 123. – SachC May 26 '21 at 18:45
  • In that case explore using `fwrite` to write the multi-byte integer which you read with `fread`. But they are for binary files, and yours are text files. – Weather Vane May 26 '21 at 18:45
  • Should I use structure to do this program @WeatherVane – SachC May 26 '21 at 18:50
  • The question states that you want it to be a text file. `fprintf` outputs your numbers as text. That is why the integer `123` is written as "123". It's a text file, which is digit by digit. – Weather Vane May 26 '21 at 18:53

1 Answers1

0

It is almost always a bad idea to require the number of data points to be specified before the data is given. Generally, the only reason to do that is to simplify the code so that you don't need to grow data structures. In this case, however, you are writing all the data to a file so you don't even need to do that, since the file provides the storage for you.

To write human readable integers, you need to format the data. The most common way to do that is with printf. There are a lot of ways to do what you're asking, and this is just one idea:

#include <limits.h>                                                                
#include <stdio.h>                                                                 
#include <stdlib.h>                                                                
                                                                                   
struct named_file {                                                                
        const char *name;                                                          
        FILE *fp;                                                                  
};                                                                                 
                                                                                   
void xfopen(struct named_file *f, const char *mode);                               
void xfclose(struct named_file *f);                                                
void display(const struct named_file *f);                                          
                                                                                   
int                                                                                
main(void)                                                                         
{                                                                                  
        struct named_file f[3];                                                    
        int n;                                                                     
                                                                                   
        f[0].name = "NUMBER.txt";                                                  
        f[1].name = "EVEN.txt";                                                    
        f[2].name = "ODD.txt";                                                     
                                                                                   
        xfopen(f, "w");                                                            
        while( scanf("%d", &n) == 1 ){                                             
                fprintf(f[0].fp, "%d\n", n);                                       
        }                                                                          
        xfclose(f);                                                                
                                                                                   
        xfopen(f + 0, "r");                                                        
        xfopen(f + 1, "w");                                                        
        xfopen(f + 2, "w");                                                        
                                                                                   
        while( fscanf(f[0].fp, "%d", &n) == 1 ){                                   
                FILE *out = n % 2 ? f[2].fp : f[1].fp;                             
                fprintf(out, "%d\n", n);                                           
        }                                                                          
        for( int i = 0; i < 3; i += 1 ){                                           
                xfclose(f + i);                                                    
                xfopen(f + i, "r");                                                
                display(f + i);                                                    
                xfclose(f + i);                                                    
        }                                                                          
}                                                                                  
     
void                                                                               
xfopen(struct named_file *f, const char *mode)                                     
{                                                                                  
        f->fp = fopen(f->name, mode);                                              
        if( f->fp == NULL ){                                                       
                perror(f->name);                                                   
                exit(EXIT_FAILURE);                                                
        }                                                                          
}                                                                                  
                                                                                   
void                                                                               
xfclose(struct named_file *f)                                                      
{                                                                                  
        if( fclose(f->fp) ){                                                       
                perror(f->name);                                                   
                exit(EXIT_FAILURE);                                                
        }                                                                          
}                                                                                  
                                                                                   
void                                                                               
display(const struct named_file *f)                                                
{                                                                                  
        int n;                                                                     
        printf("The contents of %s: ", f->name);                                   
        while( fscanf(f->fp, "%d", &n) == 1 ){                                     
                printf(" %d",n);                                                   
        }                                                                          
        putchar('\n');                                                             
}  
William Pursell
  • 204,365
  • 48
  • 270
  • 300
  • Ran your code in Onlinegdb. It didn't run as expected @WilliamPrusell. The program gets my numbers infinite times and doesn't come out. – SachC May 27 '21 at 03:34
  • That is correct. You are expected to close the input stream when you are done adding data. eg, `echo 5 4 3 5 7 | ./a.out` or, if entering data interactively, close the stream with `^d`. – William Pursell May 27 '21 at 11:30
  • If you want the program to impose a limit, you can add that logic. Just change the input while loop to `while( scanf("%d", &n) == 1 && counter++ < limit )` – William Pursell May 27 '21 at 11:31
  • Will do it @WilliamPursell – SachC May 27 '21 at 13:24
  • The last digit I enter is not being read into the number file when I use the above limit logic @WilliamPursell. Please help me – SachC May 28 '21 at 12:46
  • @SachC How are you closing the input stream? Does it work for you non-interactively? (eg, `echo 1 2 3 4 | ./a.out`) I cannot reproduce your issue. – William Pursell May 28 '21 at 13:06
  • it works non-interactively. How do I send my code for you to check? @WilliamPursell – SachC May 29 '21 at 14:33
  • Enter the limit: 5 123 34 456 67 78 The contents of NUMBER.txt: 123 34 456 67 The contents of EVEN.txt: 34 456 The contents of ODD.txt: 123 67 This is the output @WilliamPursell – SachC May 29 '21 at 14:34
  • Looks like you have an off by one error in the logic for the limit. – William Pursell May 29 '21 at 14:36
  • How can it happen like that. I've tried different methods to tackle this problem but I just could not solve it. <= too doesn't solve the problem @WilliamPursell – SachC May 29 '21 at 15:11
  • Enter the limit: 5 123 34 456 67 78 90 The contents of NUMBER.txt: 123 34 456 67 78 The contents of EVEN.txt: 34 456 78 The contents of ODD.txt: 123 67 This happens when I initialize limit to 0. @WilliamPursell – SachC May 29 '21 at 16:00
  • I used the exact same logic that you said in the above comment @WilliamPursell while( scanf("%d", &n) == 1 && counter++ < limit ) – SachC May 29 '21 at 16:09
  • Did you initialize counter to zero and properly set the limit? Put your code in a gist, or edit the question, or ask a new question. – William Pursell May 29 '21 at 16:19
  • Can you send me your email id @WilliamPursell because I can neither edit the question nor could I ask a new answer because I couldn't solve the formatting issue. I request you. And I do not think it is an off by one error – SachC May 29 '21 at 16:57