text: int **array1 = (int **)malloc(nrows * sizeof(int *));
  for(i = 0; i < nrows; i++)
  array1[i] = (int *)malloc(ncolumns * sizeof(int));
  array1[1][2] = 0;
  Hint 2 (student generated): it may be easier to test your code for correctness by reducing the maximum length of the file and length of the line. Once that works, you can experiment on larger files.
  reverse-lines filename.txt
  Note that the lines of the file may be very short (blank) or very long
  (up to hundreds of characters).
  This input:
  <!--#include file="base-head.html" -->
  <title>CS 537: Operating Systems</title>
  <!--#include file="base-top.html" -->
  <h2>Overview</h2>
  <p> Welcome to your first the Wisconsin Operating Systems course. This
  course will describe a number of topicsincluding basic operating
  system structure, process and thread synchronization and concurrency,
  file systems and storage servers, memory management techniques,
  process scheduling and resource management, system security, and a few
  other "hot" topics.
  should produce this output:
  .scipot "toh" rehto
  wef a dna ,ytiruces metsys ,tnemeganam ecruoser dna gniludehcs ssecorp
  ,seuqinhcet tnemeganam yromem ,srevres egarots dna smetsys elif
  ,ycnerrucnoc dna noitazinorhcnys daerht dna ssecorp ,erutcurts metsys
  gnitarepo cisab gnidulcniscipot fo rebmun a ebircsed lliw esruoc
  sihT .esruoc smetsyS gnitarepO nisnocsiW eht tsrif ruoy ot emocleW >p<
  >2h/<weivrevO>2h<
  >-- "lmth.pot-esab"=elif edulcni#--!<
  >eltit/<smetsyS gnitarepO :735 SC>eltit<
  >-- "lmth.daeh-esab"=elif edulcni#--!<
  String length: You may assume no line in the input file is longer than
  512 bytes. If you encounter a line that is too long, you should print error
  message LINE_TOO_LONG (as detailed below) and skip the rest of this line.
  Let's say the max size of an input line is 8
  characters (and not 512). Which of these lines should be in the final
  output?
  abcdef
  abcdefg
  abcdefgh
  abcdef
  abcdefg
  abcdefgh
  All error messages encountered while reading the input file should be of this format:
  Error in line XXX: specific error message
  Error in line XXX: specific error message
  FILE_TOO_LONG: You should print the following message: File too long
  File too long
  LINE_TOO_LONG: You should print the following message: Line too long
  Line too long
  INVALID_FILE: If the user specifies exactly one file (as
  desired) but it can't be opened (for whatever reason), you should
  print the following message:
  Error: Cannot open file FILE
  where FILE is what the user passed in.
  Error: Cannot open file FILE
  Error: Cannot open file FILE
  If you encounter a line that has both of these errors, you should print both error messages.
  There are some other possible errors too. For example, if the user doesn't
  properly specify the input file on the command line (by say, not giving one,
  or by giving too many files), you should print:
  usage: reverse <file>
  usage: reverse <file>
  Important: On any error code, you should print the error to the screen
  using fprintf() , and send the error message to stderr (standard
  error) and not stdout (standard output). This is accomplished in your C
  code as follows:
  fprintf()
  stderr
  stdout
  fprintf(stderr, “usage: ...
  ”);
  fprintf(stderr, “usage: ...
  ”);
  emperor01(1)% man fgets
  GETS(3) BSD Library Functions Manual
  FGETS(3)
  NAME
  fgets, gets -- get a line from a stream
  LIBRARY
  Standard C Library (libc, -lc)
  SYNOPSIS
  #include <stdio.h>
  char *
  fgets(char *restrict s, int n, FILE *restrict stream);
  char *
  gets(char *s);
  To invoke the compiler, run the command line:
  emperor01(1) gcc -g -o programname filename.c
  Start small, and get things working incrementally. For example, first
  get a program that simply reads in the input file, one line at a time, and
  prints out what it reads in. Then, slowly add features and test them as you
  go.reverse.c working (say, that just reads in the
  file); type cp myreverse.c myreverse.v1.c to make a copy into the file
  myreverse.v1.c . More sophisticated developers use version control systems like
  CVS , but we'll not get into that here (yet).
  myreverse.c
  cp myreverse.c myreverse.v1.c
  myreverse “”
  emperor01(5)% gdb programname)
  (gdb) run < filename.c
  (gdb) break main
  Breakpoint 1 at 0x8048419: file filename.c, line 8.
  (gdb) break filename.c:11
  Breakpoint 3 at 0x804841e: file filename.c, line 11.
  (gdb)
  gdb) print stdin
  $3 = (struct _IO_FILE *) 0x2ae420
  (gdb)
  (gdb) list main
  1 #include <stdio.h>
  2 #include <string.h>
  3
  4 int main(int argc, char * argv[])
  5 {
  6 char buffer[200];
  7 char * tmp;
  8 while (!feof(stdin)) {
  9 int len;
  10 int i;
  (gdb)
  After execution stops at a breakpoint, you can continue exection with
  the "cont" command:
  (gdb) run < filename.c
  Starting program: /afs/cs.wisc.edu/u/s/w/swift/tmp/programname <
  filename.c
  Breakpoint 1, main () at filename.c:8
  8 while (!feof(stdin)) {
  (gdb) cont
  Continuing.
  Breakpoint 1, main () at filename.c:12
  12 while (!feof(stdin)) {
  (gdb) next
  15 tmp = fgets(buffer, 200, stdin);
  (gdb) next
  16 if (tmp == 0){
  (gdb) next
  19 len = strlen(tmp);
  (gdb) next
  20 for (i = len-2; i >= 0; i--) {
  (gdb) next
  21 printf("%c",myfunction(tmp[i]));
  (gdb) step
  myfunction (c=62 '>') at filename.c:5
  5 return((int)c);
  (gdb)