-1

I need some help with an assignment. This is what I have so far:

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

#define MAXN 100

int main(){

   int ch = 0;
   FILE *fi = NULL;
   FILE *fo = NULL;
   int numo = 0;
   int numi = 0;
   int nump = 0;

   fo = fopen("OutputFile.txt", "w+");
    if (!fo) {
        perror ("Error while opening the file.\n");
        exit (EXIT_FAILURE);
    }

   fi = fopen("InputFile.txt","r");

   if(!fi){
      perror("Error while opening the file.\n");
      exit(EXIT_FAILURE);
   }

   printf("\n The contents of %s file are :\n", "InputFile.txt");
   while( ( ch = fgetc(fi) ) != EOF )
      printf("%c",ch);






   numi = ch;

   numo = numi + 8;








   fprintf (fo, " %d\n", numo);  





   if (fo) fclose (fo);

   return 0;
}

Edit 3. Scrapped the array idea since it's causing me more trouble then success. I reduced the list to just one line in the inputfile.txt. The math is simple so I can see what I'm doing and where its going wrong. I've got everything working for the most part, it's just a bit glitched.

First off, The program will read the file just fine and display it in the program. The problem comes after that point and the point the results are saved into OutputFile.txt. Depending on which % I use (%s, %i, %d, %c) The result in OutputFile.txt is either -1, a character, or a longer list of numbers.

How do I get the number from InputFile.txt and save the number to numi?

This is what it looks like

The contents of InputFile.txt are: 10010110
numo=ch+8
Result (Numo) save to OutputFile.txt

When I open the OutputFile.txt the line read 7. So for some reason CH = -1 (Which I want it to equal 10010110) And I'm not sure where the -1 is coming from.

Zee
  • 9
  • 5
  • First thing you don't know how long is your file, so you will need dynamic allocating memory (`malloc()`, `realloc()`, `free()`) http://www.cplusplus.com/reference/cstdlib/malloc/. You will dynamically allocate memory of 2D array (array of pointers on your binary number) http://stackoverflow.com/questions/19920452/dynamically-allocated-2-dimensional-array. After you do calculations, save results to file using `fprinf()` http://www.tutorialspoint.com/c_standard_library/c_function_fprintf.htm. – Matjaž Dec 07 '14 at 20:52
  • Maybe you should save some time and memory and do calculations directly after you read whole line. Hope this will help you. – Matjaž Dec 07 '14 at 21:00
  • I scrapped the array idea and I got SOMETHING to print in the OutputFile.txt. updated the code in the original post. – Zee Dec 07 '14 at 21:46

1 Answers1

0

There are many ways to put the pieces of the puzzle together. Finding the tool for the job is 1/2 the battle. In this case strtol will covert base 2 to decimal. The key is to recognize, there is no reason to do character input and you can simplify your code using line-oriented input which will provide your data in a format ready for conversion.

Below are the pieces of the puzzle. They are left somewhat out of order so that you can work to rearrange them to produce a final output file with both the string and the decimal value contained within it. You will probably want to open your output file before you read the text file so that both file steams are available during your read loop.

Take a look and let me know if you have any questions. Note: this is just one of many, many ways to approach this problem:

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

#define MAXN 100

int main () {

    char file_input[25] = { 0 };    /* always initialize all variables  */
    char file_output[25] = { 0 };
    FILE *fi = NULL;
    FILE *fo = NULL;
    int integers[MAXN] = { 0 };
    int i = 0;
    int num = 0;

    printf ("\n Please enter the input filename: ");
    while (scanf ("%[^\n]%*c", file_input) != 1)
        fprintf (stderr, "error: read failed for 'file_input', try again\n  filename: ");

    fi = fopen (file_input, "r");   /* open input file and validate     */
    if (!fi) {
        perror ("Error while opening the file.\n");
        exit (EXIT_FAILURE);
    }

    printf ("\n The contents of file '%s' are :\n\n", file_input);

    char *line = NULL;              /* NULL forces getline to allocate  */
    size_t n = 0;                   /* max chars to read (0 - no limit  */
    ssize_t nchr = 0;               /* number of chars actually read    */

    while ((nchr = getline (&line, &n, fi)) != -1) {

        if (line[nchr - 1] == '\n')
            line[--nchr] = 0;       /* strip newline from end of line   */

        integers[i] = strtol (line, NULL, 2); /* convert to decimal     */

        printf ("  %s  ->  %d\n", line, integers[i]);

        if (i == MAXN - 1) {        /* check MAXN limit not exceeded    */
            fprintf (stderr, "error: input lines exceed %d\n", MAXN);
            exit (EXIT_FAILURE);
        }

        i++;
    }

    if (line) free(line);           /* free memory allocated by getline */
    if (fi) fclose (fi);            /* close file stream when done      */

    num = i;                        /* save number of elements in array */

    printf ("\n Conversion complete, output filename: ");
    while (scanf ("%[^\n]%*c", file_output) != 1)
        fprintf (stderr, "error: read failed for 'file_output', try again\n  filename: ");

    fo = fopen (file_output, "w+"); /* open output file & validate      */
    if (!fo) {
        perror ("Error while opening the file.\n");
        exit (EXIT_FAILURE);
    }

    for (i = 0; i < num; i++)       /* write integers to output file    */
        fprintf (fo, " %d\n", integers[i]);

    if (fo) fclose (fo);

    return 0;
}

Use/output:

$ ./bin/arrayhelp

 Please enter the input filename: dat/binin.txt

 The contents of file 'dat/binin.txt' are :

  01000101  ->  69
  11010110  ->  214
  11101110  ->  238

 Conversion complete, output filename: dat/binout.txt

$ cat dat/binout.txt
 69
 214
 238

Reading Character-by-character

While this isn't the easiest way to handle reading the file, there is nothing wrong with it. However, you have logic problems. Specifically, you read (and assign as integer) numi = ch; and then assign numo = numi + 8; to write to your output file. This results in adding 8 to the ASCII value of '0' (48) or '1' (49). If you add 8 to that, well, you can do the math. When you read from a file as text, you are reading the ASCII value, NOT the numeric value 1 or 0.

In order to accomplish what you appear to be attempting, you must save all characters in a line to a buffer (a string, a character array, I don't care what you call it). That is the only way, (short of doing a character-by-character conversion to a numeric 1 or 0 and then preforming the binary addition), you have to convert the string of '0's and '1's to a decimal value.

Here is an example using the character-by-character read from fi. Read though it and understand why it needs to be done this way. If you have questions, drop another comment.

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

#define MAXN 100

int main () {

    int ch = 0;
    FILE *fi = NULL;
    FILE *fo = NULL;
    // int numo = 0;
    // int numi = 0;
    // int nump = 0;
    char buffer[MAXN] = { 0 };              /* buffer to hold each line     */
    int idx = 0;                            /* index for buffer             */

    fo = fopen ("OutputFile.txt", "w+");    /* open output file & validate  */
    if (!fo) {
        perror ("Error while opening the file.\n");
        exit (EXIT_FAILURE);
    }

    fi = fopen ("InputFile.txt", "r");      /* open input file & validate   */

    if (!fi) {
        perror ("Error while opening the file.\n");
        exit (EXIT_FAILURE);
    }

    printf ("\n The contents of %s file are :\n\n", "InputFile.txt");

    fprintf (fo, "  binary        decimal\n");   /* header for output file  */

    while (1)   /* loop and test for both '\n' and EOF (-1) to parse file   */
    {
        // printf ("%c", ch);      /* we will store each ch in line in buffer  */

        if ((ch = fgetc (fi)) == '\n' || ch == EOF)
        {
            if (ch == EOF && idx == 0)  /* if EOF (-1) & buffer empty exit loop */
                break;
            buffer[idx] = 0;        /* null-terminate buffer (same as '\0' )    */
            idx = 0;                /* reset index for next line & continue     */
                                    /* write original value & conversion to fo  */
            fprintf (fo, "  %s  =>  %ld\n", buffer, strtol (buffer, NULL, 2));
                                    /* write fi contents to stdout (indented)   */
            printf ("  %s\n", buffer);
        }
        else
        {
            buffer[idx++] = ch;     /* assign ch to buffer, then increment idx  */
        }

        /* This makes no sense. You are reading a character '0' or '1' from fi,
        the unsigned integer value is either the ASCII value '0', which is
        decimal 48 (or hex 0x30), or the ASCII value '1', decimal 49/0x31.
        If you add 8 and write to 'fo' with '%d' you will get a 16-digit
        string of a combination of '56' & '57', e.g. 56575756....

            numi = ch;
            numo = numi + 8;
        */
    }

    if (fi)                         /* close both input and output file streams */
        fclose (fi);
    if (fo)
        fclose (fo);

    return 0;
}

output to stdout:

$ ./bin/arrayhelp2

 The contents of InputFile.txt file are :

  01000101
  11010110
  11101110

OutputFile.txt:

$ cat OutputFile.txt
  binary        decimal
  01000101  =>  69
  11010110  =>  214
  11101110  =>  238
David C. Rankin
  • 81,885
  • 6
  • 58
  • 85
  • Thank you kindly. I'll see if I can figure it out and post the outcome later :D – Zee Dec 07 '14 at 22:19
  • Edited the original post with where I'm at now. Your post was a big help in figuring out bits of this code, though I had some problems with ssize_t and scrapped the array idea... I'm at the last bit of code now and I'm just unsure why -1 is being saved as CH when I'm trying to get it to save the number in InputFile.txt. – Zee Dec 08 '14 at 00:52
  • See my addition titled **Reading Character-by-character** The `-1` that is saved to `ch` is the value for `EOF`... – David C. Rankin Dec 08 '14 at 04:58
  • The numo = numi+8 was some shenanigans I threw in there to check which parts of code was working. (I'm strange but it did let me know that the program was reading the file alright since it did display the inputfiles number correctly and it was also correctly saving a number to the outputfile.) :D The code works now thank you so very much for the explanation! – Zee Dec 08 '14 at 05:36