# Data input and datatypes

(including-libraries)=
## Including libraries

We can stand on the shoulder of code that others have written by including libraries. In other words, *reusable code* is packaged into libraries. In C, a library consists of dozens of *header files*. We use an *include directive* to include a header file.

For example, the C standard library includes the standard input output header file `stdio`, that includes functions like `scanf` and `printf`. To make these functions *available to us*, we write:

```c
#include <stdio.h>
```

:::{wpd} include directive
replaces a #include directive line with the content of the file specified
:::

Libraries are typically included in the beginning of a file. This way the code in the included library is available for the whole file.

:::{wpd} standard library
The library made available across implementations of a programming language, e.g., [C standard library](https://devdocs.io/c/) and [Python standard library](https://docs.python.org/3/library/).
:::

The standard library is like the Swiss knife of a programming language. If you need to implement functionality and this functionality is already available in the standard library, you should prioritize functions in the standard library over implementing yourself.

:::{tip}
You find a link to the standard library for browsing on the navigation bar.
:::

:::{activity}
:label: including-libraries-activity

Browse the C standard library.

1. How many header files are there?
1. Which header file/s could be interesting for:
   - generating random numbers
   - for calculating the length of an English word we store in the memory?
1. (optional) Compare the C and Python standard libraries regarding the functionality they provide. <!--high-level, however a systems programming language-->

Process:
- 3 min research
- We review
:::

For example using <time.h>:
```c
#include <stdio.h>
#include <time.h>

int main() {
  time_t now = time(NULL);
  printf("Now: %s", ctime(&now));
}
```

## Data input & output on the console

- `scanf`: inputs data by *scanning* from the console
- `printf`: outputs data by *printing* to the console

`f` stands for *formatted*. These functions use a *format string*. A format string uses one or many *format specifiers*.

:::{commons-figure} https://commons.wikimedia.org/wiki/File:Printf.svg
:image_url: https://upload.wikimedia.org/wikipedia/commons/thumb/2/2c/Printf.svg/525px-Printf.svg.png
How `printf` statement generates its output. The red string is the *format string*. A word beginning with `%` is a *format specifier*. Each argument is paired with a format specifier. Text below shows the final string generated by the format string.
:::

format string
: a string containing placeholders, called format specifiers, which describe how variable text should be displayed.

:::{wpd} format specifier
:id: Printf#Format_specifier
a placeholder that follows the format `%[parameter][flags][width][.precision][length]type`{l=python}, which describes how data read from a variable should be displayed.
:::

The format string is a template language, e.g.: "%s is %d years old." includes a string (hence `%s` format specifier) and an integer decimal (`%d`), which could resemble a name and their age. This template can then be filled with data (`printf`) or used to *parse* data from a sentence in this format (`scanf`).

:::{wpd} parser
a software component that takes input data (typically text) and builds a data structure
:::

```c
#include <stdio.h>
#define MAX_WORD_LENGTH 120

char word[MAX_WORD_LENGTH];
int number;

int main() {
  printf("Enter a word press Enter: ");
  scanf("%s", word);
  // %s stands for string
  // scanf reads the input into the character array `word`

  printf("Your message was: %s\n", word);
  // This time %s used 

  printf("Enter an integer number: ");
  scanf("%d", &number);
  // %d stands for decimal integer
  // Use `&` if you read the input into a non-array.
  // `&` means *get-the-address* of the variable (instead of only the value)

  printf("The square of %d is: %d\n", number, number * number);
  
  puts("Bye!");
  // If you don't need to output a variable and need a newline (`\n`), use
  // `puts`. `puts` automatically includes a newline.
```

:::{wpd} decimal
a number that uses the base ten.
:::

The format string is a markup language itself. To see what is possible, refer [here](https://en.wikipedia.org/wiki/Printf#Format_specifier).

:::{tip}
`%d` and `%i` have the same meaning in `printf`, but [I recommend using `%d`](project:#why_format_specifier_d_over_i).
:::
:::::{activity} Using a format specifier
You want to print a column of prices in DKK as follows, but not like on the right:

::::{grid} 2
:::{grid-item-card} aligned
```text
0:  13 DKK
1: 140 DKK
2: 900 DKK
3:   2 DKK
4:   0 DKK
```
:::
:::{grid-item-card} not-aligned
```text
0: 13 DKK
1: 140 DKK
2: 900 DKK
3: 2 DKK
4: 0 DKK
```
:::
::::

You expect the prices up to ~900 DKK. Which format specifiers and format strings would you use in the following code?

You can use the [syntax here](https://en.wikipedia.org/wiki/Printf#Syntax). `[]` denotes optional elements in the syntax string.

```{literalinclude} ../code/masked/aligning_tabular_data_using_format_specifier.c
:language: c
```
:::::

<!--
## Values vs pointers

-->

(data-types)=
## Data types

A computer works with zeroes and ones. These can be interpreted in different ways:

For example, *1110*:

1. four Boolean values (a Boolean can be *true* or *false*): true, true, true, false.
2. an integer: *-1* (uses two's complement)
   <!--if we add 1 to 0111 (7) we should get the lowest negative number -8 => so 1000 should be -8 => two's complement works by inverting and adding +1.
   
   Why the naming? One's complement: if we add -n and +n we get only ones. In twos complement: 0111 + 1001 we get 10000, but we throw the first one away. So it is 2^n modulo. Maybe 2 comes from this.
   
   It is also derived from one's complement by adding 1. Maybe also a reason for naming.
   -->
3. an unsigned integer: *14*
4. a floating point number: $-1 \cdot 2^{-2} = 0.25$ (its decimal dot can *float* to the right). In this example the dot is shifted two times to the right. First `1` is the sign.
5. as a letter; `0110` binary corresponds to 6 in decimal, so sixth letter: *F*
6. as two letters; second (`01`) and third (`10`) letters in sequence: *BC*

Note that C does not have a built-in type for four bits, so these are just example interpretations and now how C interprets *1110*.

Some C types that are similar to the interpretations above:
1. array of `bool`s
2. `int`
3. `unsigned int`
4. `double` (more precise version of `float`)
5. `char`
6. array of `char`

The main datatype that uses the smallest number of bits is `bool`, even pads seven bits with zeroes, i.e., in `0000_0001`, seven bits on the left of `1` are not used. The reason lies in the architecture of most computers. The smallest bit width a computer can address is one byte.

{#different-interpretations-of-a-byte}
The next large main datatype after `bool` is `char`, which must have at least 8 bits. So let us see some example interpretations of a byte in C:

::::{grid} 2
:::{grid-item-card} Code
```c
#include <stdio.h>
char data = 0b1000'0110; // Single quotation mark for better readability

int main() {
  printf("byte count: %lu\n", sizeof data);
  printf("as int: %hhd\n", data);
  printf("as unsigned: %hhu\n", data);
  printf("as char: %c\n", data);
}
```
:::
:::{grid-item-card} Output
```text
as int: -122
as unsigned: 134
as char: �
```
:::
::::

string
: a sequence of `chars` that ends with a null character

:::{wpd} null character
a non-visible character with the value zero
:::

We define a string using double quotes (`"`) and a `char` using single quotes (`'`). If we use `"`, then a null character is automatically added to the end of the letters we write. When `printf` reads a string, it reads character by character, until a null character is reached.

Both variables generate the same output:
```c
#include <stdio.h>

char msg_as_str[] = "bye!";
char msg_as_array_of_chars[] = {'b', 'y', 'e', '!', '\0'};

int main() {
  puts(msg_as_str);
  puts(msg_as_array_of_chars);
}
```


Refer to [this table about main datatypes](https://en.wikipedia.org/wiki/C_data_types#Main_types) for:
1. all main types
2. their format specifiers

:::{card} Question to ponder
Select datatypes for the following variables:

- human height in meters
- number of people in a city
- door is open or not
- price of a product in EUR
- capacity of a modern hard-disk in bytes
- gender: divers, female, male <!--enum but we did not introduce. We could also use an int-->
:::

(arguments-and-return-value-in-functions)=
## Arguments and return value in functions

These act like input and output to a function.

:::{mermaid} ../industrial-programming/img/function-input-output.mmd
:::

Functions can have zero, one or many *arguments* and one *return value*. Usually arguments are used as input and the return value as output, but it is also possible to input *addresses* instead of *values*. If we input an address, then a function can use an argument to output values.

Examples:

:::{list-table}
:header-rows: 1

* - function
  - arguments
  - return value
* - `printf("Hej Geko 👋");`{l=c}
  - `"Hej Geko 👋"`: *string*
  - 13: int (9+4 bytes written)
* - `scanf("%d %u", &n1, &n2);`{l=c}
  - `%d`: format string: *string*, `&n1`: *int*, `&n2`: *unsigned*
  - number of successfully matched items, e.g., 2: *int*
* - `rand();`{l=c}
  - none
  - random number: *int*
:::
`&n1` means *the address* of the variable `n1`.

If we use a function in a wrong way, we get an error:

```c
int matched_item_count = scanf();
```

Output of clangd in the editor:
```text
Too few arguments to function call, at least argument '__format' must be specified
```
Fortunately, our IDE pings us already while we write code:

![](../img/ide-hovered-over-an-error-show-error-message.png)


## Conversion between datatypes

`printf` converts many datatypes to strings, and `scanf` converts vice-versa. We can also a non-string datatype to another non-string datatype:

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

int main() {
  // Implicit conversion (safe, no data loss)
  // Small numeric types → larger numeric types
  int wholeNumber = 42;
  double bigNumber = wholeNumber; // implicit
  printf("%f\n", bigNumber);      // 42.000000

  // Implicit conversion – we may lose data
  double piDouble = 3.14159;
  int piInt = piDouble; // truncates to 3 (we lost data)
  printf("%d\n", piInt);

  // String to numbers
  char temperature_str[] = "23.45";
  double temperature = strtod(temperature_str, NULL);
  printf("%f\n", temperature); // 23.450000

  char age_str[] = "23";
  unsigned age = strtoul(age_str, NULL, 10);
  printf("%u\n", age); // 23
}
```

:::{card} Question to ponder
Why do we use strings and numeric datatypes? Can't we just use only strings or numeric datatypes?
:::

(math-expressions)=
## Math expressions

```c
int a = 5;
int b = 2;
int sum       = a + b;        // 7
int diff      = a - b;        // 3
int product   = a * b;        // 10
int quotient  = a / b;        // 2
int remainder = a % b;        // 1

double x = 5.0;
double y = 2.0;
double quotient2 = x / y;         // 2.5
```

<!--
// Exponentiation and root
double power = Math.Pow(3, 4);   // 3⁴ = 81
double sqrt  = Math.Sqrt(16);    // 4

// Trigonometric functions (angles in radians)
double angle = Math.PI / 4;      // 45°
double sin   = Math.Sin(angle);  // 0.7071...
double cos   = Math.Cos(angle);  // 0.7071...

// Rounding
double raw   = 3.14159;
double round = Math.Round(raw, 2); // 3.14
-->

:::{card} Question to ponder
Come up with an example where any of the math expressions be useful in Conveyor Belt Capacity Check problem?
:::
<!--you want to create a visualization of where the robot arm moves if it should rotate around a point 30 degrees. We need a trigonometric function-->


## Using variables and constants

```c
// First define a variable
int age = 30;

// Then use it (`age`)
if (age > 30)
  printf("Crisis?");

// Constants 
// Convention: CAPITAL letters
const double PI = 3.1415926535;
```

We don't have to use `const` for functionality, but we humans make mistakes and this extra information lowers the chance of a mistake later. The compiler will warn us if we try to change the variable.

## Program structure

`main()` is where your program starts.

```c
#include <stdio.h>

// Variables
int time;

int main() {
  puts("Welcome to the time machine 👋");
  time += 10;
  printf("Now the time is: %d\n", time);
}
```

## Back to the problem

:::{activity}
:label: conveyor-belt-capacity-check-code
Now come back to the problem {ref}`conveyor-belt-capacity-check-intro` and try again.

Steps:
- 10 min [pair-programming](project:#tapps)
- we review
:::

## Appendix

- `fgets` can also read input from the console. I chose to introduce `scanf` first, which can convert string to other datatypes.
- `scanf` may overflow during scanning of input, if the user types more characters than the size of the buffer. A secure practice is to use `fgets` which reads a limited number of characters and then use `sscanf` on the buffer. We will introduce security aspects later.
<!--
- `puts` and `fgets` are the stepping stones to `printf` and `scanf`. I chose to introduce the latter first, so the students can solve the first problem easier.
-->
