APPFS
Advanced practical programming for scientists
 All Data Structures Files Functions Variables Typedefs Macros
Macros | Functions
ex1a.c File Reference

Appfs Exercise 1: direct read input. More...

#include <stdio.h>
#include <stdbool.h>
#include <limits.h>
#include <unistd.h>
#include <fcntl.h>
#include <string.h>
#include <assert.h>

Go to the source code of this file.

Macros

#define MAX_NUMS   ((INT_MAX >> 5) + 1)
 Maximum number of 32 bit ints we need to store bits. More...
 
#define BUF_NUMS   4096
 read buffer size More...
 

Functions

int main (int argc, char **argv)
 Program to read a file with binary positive 32 bit integers, sort the numbers and print them sorted. More...
 

Detailed Description

Author
Thorsten Koch
Date
24Oct2014

gcc -O3 -Wall -std=c99 -o ex1 ex1.c

Using direct read() for input

Definition in file ex1a.c.

Macro Definition Documentation

#define BUF_NUMS   4096

Definition at line 21 of file ex1a.c.

#define MAX_NUMS   ((INT_MAX >> 5) + 1)

Definition at line 20 of file ex1a.c.

Function Documentation

int main ( int  argc,
char **  argv 
)

Actually, the numbers are not sorted. There is an array with one bit for each possible number. Upon reading the respective bit is set for the number recognized. At the end the array is scanned in order and the numbers present are printed.

Parameters
argv[1] name of file to read

Definition at line 31 of file ex1a.c.

32 {
33  const char* usage = "usage: %s filename\n";
34 
35  /* made static, because otherwise, the stack size might be too small.
36  */
37  static unsigned int have_num[MAX_NUMS];
38 
39  int buf[BUF_NUMS];
40  int fd;
41  int n;
42  int total_nums = 0;
43 
44  /* we assume 32 bit integers, otherwise it will not work
45  */
46  assert(sizeof(int) == 4);
47 
48  /* Check arguments, we need a filename.
49  */
50  if (argc < 2)
51  {
52  fprintf(stderr, usage, argv[0]);
53  exit(EXIT_FAILURE);
54  }
55  memset(have_num, 0, sizeof(have_num)); // Proably uneccessary
56 
57  /* Open file
58  */
59  if (0 > (fd = open(argv[1], O_RDONLY)))
60  {
61  perror(argv[1]);
62  exit(EXIT_FAILURE);
63  }
64 
65  /* Read from file until data exhausted
66  */
67  while(0 < (n = read(fd, buf, sizeof(buf))))
68  {
69  int nums_read = n / sizeof(buf[0]);
70 
71  assert(nums_read <= BUF_NUMS);
72 
73  total_nums += nums_read;
74 
75  /* Run through buffer of read numbers and set mark bits
76  */
77  for(int i = 0; i < nums_read; i++)
78  {
79  // fprintf(stderr, "%d\n", buf[i]);
80 
81  /* Check input: really >= 0 ? Otherwise ignore
82  */
83  if (buf[i] >= 0)
84  {
85  int idx = buf[i] >> 5; // n / 32
86  unsigned int msk = 1 << (buf[i] & 31); // bit number n mod 32
87 
88  assert(idx >= 0 && idx < MAX_NUMS);
89 
90  have_num[idx] |= msk;
91  }
92  }
93  }
94  if (close(fd))
95  {
96  perror("close: ");
97  exit(EXIT_FAILURE);
98  }
99  fprintf(stderr, "Total numbers read = %d\n", total_nums);
100 
101  for(int i = 0; i < MAX_NUMS; i++)
102  if (have_num[i]) // just for speed up
103  for(int k = 0; k < 31; k++)
104  if (have_num[i] & (1 << k))
105  printf("%d\n", (i << 5) + k);
106 
107  return EXIT_SUCCESS;
108 }
#define BUF_NUMS
read buffer size
Definition: ex1a.c:21
NUMS * nums_read(const char *filename)
Read numbers into data structure.
Definition: nums.c:52
#define MAX_NUMS
Maximum number of 32 bit ints we need to store bits.
Definition: ex1a.c:20