Hello,
I want to read a text file in C and the output file must be created and want to reverse the data in tat output file created.
So i used the below coding but not reversing the data in the output
file created.
eg: input file contains this data
abc
123
output file must be
123
abc

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

#define MAX_STRING_LENGTH 1000
#define BUFFER_SIZE 50

/* Global variables */
FILE *pInFile = NULL;                   /* File pointer to input file     */
FILE *pOutFile = NULL;                  /* File pointer  to output file   */
char *infilename = "C:\\myfile.txt";    /* Name of the file to be read    */
char *outfilename = "C:\\outfile.txt";  /* Name of the file to be written */
char *buffer = NULL;
size_t buffer_size = BUFFER_SIZE;


void main()
{
  size_t str_length = 0;
  int str_count = 0;
  fpos_t *positions = NULL;
  int i = 0;

  buffer = (char*)malloc(buffer_size);            /* Create initial buffer */

  if((pInFile = fopen(infilename, "r")) == NULL)  /* Open the input file   */
  {
    printf("Error opening %s for reading. Program terminated.", infilename);
    abort();
  }

  /* Find out how many strings there are */
  for(;;)
  {
    fread(&str_length, sizeof(size_t), 1, pInFile);  /* Read the string length */
    if(feof(pInFile))                                /* If it is end of file   */
      break;                                         /* We are finished        */

    /* Check buffer is large enough and increase if necessary */
    if(str_length>buffer_size)
    {
      buffer_size = str_length+1;
      free(buffer);
      buffer = (char*)malloc(buffer_size);
    }
    fread(buffer, str_length, 1, pInFile);   /* Read the string */
    ++str_count;
  }
  printf("\nThere are %d strings in the input file.", str_count);

  /* Now get the position for the beginning of each record in the file */
  /* The buffer is now large enough to hold the longest string         */
  rewind(pInFile);
  positions = (fpos_t*)malloc(str_count*sizeof(fpos_t));  /* Array to store the positions */
  for(i = 0 ; i<str_count ; i++)
  {
    fgetpos(pInFile, positions+i);                    /* Get the positions      */
    fread(&str_length, sizeof(size_t), 1, pInFile);   /* Read the string length */
    fread(buffer, str_length, 1, pInFile);            /* Read the string        */
 }

  /* Open the output file */
  if((pOutFile = fopen(outfilename, "w")) == NULL)
  {
    printf("Error opening %s for reading. Program terminated.", outfilename);
    abort();
  }

  /* Read the records in reverse order from the input file and write to the new file */
  for(i = 0 ; i<str_count ; i++)
  {
    fsetpos(pInFile, positions+str_count-i-1);            /* Set the file position  */
    fread(&str_length, sizeof(size_t), 1, pInFile);       /* Read the string length */
    fwrite(&str_length, sizeof(size_t), 1, pOutFile);     /* Write to new file      */
    fread(buffer, str_length, 1, pInFile);                /* Read the string        */
    fwrite(buffer, str_length, 1, pOutFile);              /* Write to new file      */
  }

  fclose(pInFile);                                        /* Close input file  */
  fclose(pOutFile);                                       /* Close output file */
  printf("\nNew file write complete\n");

  /* List contents of output file */
  if((pOutFile = fopen(outfilename, "r")) == NULL)        /* Open the new file to read it */
  {
    printf("Error opening %s for reading. Program terminated.", outfilename);
    abort();
  }
  printf("\nThe strings in the new file are:");
  for(i = 0 ; i<str_count ; i++)
  {
    fread(&str_length, sizeof(size_t), 1, pOutFile);
    fread(buffer, str_length, 1, pOutFile);
    buffer[str_length] = '\0';
    printf("\n%s", buffer);
  }
  printf("\n");
  fclose(pOutFile);                                    /* Close file */

  /* Free the memory we allocated */
  if(buffer != NULL)
    free(buffer);
  if(positions != NULL)
    free(positions);
 }

Recommended Answers

All 10 Replies

Hello,
I need string Reversing in C
Read the output of a file as

ABCDEFGHIFSFSA
1242487132
FSFSA
*
Print the output as

*
FSFSA
1242487132
ABCDEFGHIFSFSA

hint: One function and use multiple times for double reverse.

Reverse entire string.
Parse whitespace, mark 1st and last character per word, then reverse that data, skip whitespace repeat!

have fun!

I see you're planning to give the drive some exercise!

May I suggest an alternative? Read the entire file iinto memory, then parse it in memory by working from end of load to beginning of load. Saves all that hard drive thrashing!

Use recursion:

#include <stdio.h>

void PrintFileBackward(FILE *fp);

int main()
{
    FILE *fp = fopen("test.dat", "r");
    PrintFileBackward(fp);
    return 0;
}

void PrintFileBackward(FILE *fp)
{
    char s[20];
    if (!fgets(s, 20, fp)) return;
    PrintFileBackward(fp);
    fputs(s, stdout);
}

Each time you call PrintFileBackward, the next line is read from the file. Then when the functions are rolling back up the stack, each line is printed. But because lines are printed from the inside out in the opposite order that they were read, they get printed in reverse.

Cool, huh?

With that solution increase your buffer size slightly (Not too much as its recursion) and added an fopen() error check and don't forget your fclose().
Also note "rt" on the fopen() if you need your line terminator translation.
/r/n vs /n

With that solution increase your buffer size slightly

It should be no less than the largest expected line length. I picked 20 because none of the lines in the example file were longer than that.

don't forget your fclose()

You don't need to fclose() if the program ends. When the program ends normally, all open files are flushed and closed.

Also note "rt" on the fopen() if you need your line terminator translation.

"r" is already text mode where whatever line terminator combination is used on the OS, it becomes '\n' inside your program. "rb" is binary mode, and those translations aren't made. "rt" isn't portable.

There's a line between "help" and "spoon-feeding the complete answer".

If I cross the line then one of the moderators will let me know, but I'll keep those links in mind when I post.

commented: or maybe the users will. dont be such a smartass -2

. "rt" isn't portable.

Whatever gave you that idea? True, text mode is the default, but there is nothing wrong with specifying 't' in the mode string. If there was then it would be in the c standards.

I believe it is undefined per the standard.

This is from n1124:

7.19.5.3 The fopen function
3 The argument mode points to a string. If the string is one of the following, the file is open in the indicated mode. Otherwise, the behavior is undefined.231)

r open text file for reading
w truncate to zero length or create text file for writing
a append; open or create text file for writing at end-of-file
rb open binary file for reading
wb truncate to zero length or create binary file for writing
ab append; open or create binary file for writing at end-of-file
r+ open text file for update (reading and writing)
w+ truncate to zero length or create text file for update
a+ append; open or create text file for update, writing at end-of-file
r+b or rb+ open binary file for update (reading and writing)
w+b or wb+ truncate to zero length or create binary file for update
a+b or ab+ append; open or create binary file for update, writing at end-of-file

[edit]Ah, but C90 had more wiggle room:

The argument mode points to a string beginning with one of the following sequences:103

"r" open text file for reading "w" truncate to zero length or create text file for writing "a" append; open or create text file for writing at end-of-file "rb" open binary file for reading "wb" truncate to zero length or create binary file for writing "ab" append; open or create binary file for writing at end-of-file "r+" open text file for update (reading and writing) "w+" truncate to zero length or create text file for update "a+" append; open or create text file for update, writing at end-of-file "r+b" or "rb+" open binary file for update (reading and writing) "w+b" or "wb+" truncate to zero length or create binary file for update "a+b" or "ab+" append; open or create binary file for update, writing at end-of-file

103 Additional characters may follow these sequences.

[edit=2]And n1124's footnote was

231) If the string begins with one of the above sequences, the implementation might choose to ignore the remaining characters, or it might use them to select different kinds of a file (some of which might not conform to the properties in 7.19.2).

[edit=3]I just avoid it.

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.