Appfs Exercise 1: direct read input, split main into several functions.
More...
#include <sys/types.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdint.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.
|
static bool | is_little_endian (void) |
| Check if the architecture is little endian. More...
|
|
static int32_t | reverse_int32 (int32_t val) |
| Reverse the 4 bytes of an int between little and big endian. More...
|
|
static int | store_numbers (const char *filename, uint32_t *have_num, const unsigned int max_nums) |
| Read numbers from file and set bits in provided array. More...
|
|
static void | output_numbers (FILE *fp, uint32_t *have_num, const unsigned int max_nums) |
| Read through the marked bits and print out the numbers in ascending order. More...
|
|
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...
|
|
- Author
- Thorsten Koch
- Date
- 24Oct2014
gcc -O3 -Wall -std=c99 -o ex1a3 ex1a3.c
Using direct read() for input Improvements to ex1a2: Split main into several functions.
Definition in file ex1a3.c.
#define MAX_NUMS ((INT32_MAX >> 5) + 1) |
static bool is_little_endian |
( |
void |
| ) |
|
|
inlinestatic |
This check is constant and can be optimized away by the compiler during compile time. All conditionals depending on it are then decided at compile time
- Returns
- true if the machine uses little endian, false otherwise.
Definition at line 30 of file ex1a3.c.
32 union { uint32_t u;
char c[
sizeof(uint32_t)]; } bint = { 0x01020304 };
34 return bint.c[0] == 4;
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 148 of file ex1a3.c.
150 const char* usage =
"usage: %s filename\n";
161 fprintf(stderr, usage, argv[0]);
164 if (NULL == (have_num = calloc(
MAX_NUMS,
sizeof(*have_num))))
166 fprintf(stderr,
"calloc of size %lu failed\n",
MAX_NUMS *
sizeof(*have_num));
173 fprintf(stderr,
"Total numbers read = %d\n", total_nums);
static void output_numbers(FILE *fp, uint32_t *have_num, const unsigned int max_nums)
Read through the marked bits and print out the numbers in ascending order.
static int store_numbers(const char *filename, uint32_t *have_num, const unsigned int max_nums)
Read numbers from file and set bits in provided array.
#define MAX_NUMS
Maximum number of 32 bit ints we need to store bits.
static void output_numbers |
( |
FILE * |
fp, |
|
|
uint32_t * |
have_num, |
|
|
const unsigned int |
max_nums |
|
) |
| |
|
static |
- Parameters
-
fp | output file pointer. |
have_num | array of size #max_nums * sizeof(*have_num) |
max_nums | maximum number of entries in have_num |
Definition at line 125 of file ex1a3.c.
131 assert(NULL != have_num);
133 for(
int i = 0; i < max_nums; i++)
135 for(
int k = 0; k < 31; k++)
136 if (have_num[i] & (1 << k))
137 fprintf(fp,
"%d\n", (i << 5) + k);
static int32_t reverse_int32 |
( |
int32_t |
val | ) |
|
|
inlinestatic |
Byte order 1 2 3 4 ist reversed to 4 3 2 1
- Parameters
-
- Returns
- reversed value
Definition at line 42 of file ex1a3.c.
44 val = ((val << 8) & 0xFF00FF00) | ((val >> 8) & 0xFF00FF);
46 return (val << 16) | ((val >> 16) & 0xFFFF);
static int store_numbers |
( |
const char * |
filename, |
|
|
uint32_t * |
have_num, |
|
|
const unsigned int |
max_nums |
|
) |
| |
|
static |
- Returns
- the total number of numbers read. Be aware that some of the numbers may have beend discarded.
- Parameters
-
filename | Path/Name of file to read |
have_num | array of size #max_nums * sizeof(*have_num) |
max_nums | maximum number of entries in have_num |
Definition at line 52 of file ex1a3.c.
62 assert(NULL != filename);
63 assert(0 < strlen(filename));
64 assert(NULL != have_num);
69 if (0 > (fd = open(filename, O_RDONLY)))
77 while(0 < (n = read(fd, buf,
sizeof(buf))))
101 uint32_t msk = 1 << (num & 31);
103 assert(idx >= 0 && idx < max_nums);
105 have_num[idx] |= msk;
static int32_t reverse_int32(int32_t val)
Reverse the 4 bytes of an int between little and big endian.
static bool is_little_endian(void)
Check if the architecture is little endian.
NUMS * nums_read(const char *filename)
Read numbers into data structure.
#define BUF_NUMS
read buffer size