diff --git a/.gitignore b/.gitignore index a306d42..0a8d875 100644 --- a/.gitignore +++ b/.gitignore @@ -36,3 +36,8 @@ book # MacOS Meta Files .DS_Store + +# IDE Configs +.vs +.vscode +.idea diff --git a/.vs/HPC-Training/FileContentIndex/0c78780e-4851-40e0-a7de-a7db7cbb157d.vsidx b/.vs/HPC-Training/FileContentIndex/0c78780e-4851-40e0-a7de-a7db7cbb157d.vsidx deleted file mode 100644 index 73bf290..0000000 Binary files a/.vs/HPC-Training/FileContentIndex/0c78780e-4851-40e0-a7de-a7db7cbb157d.vsidx and /dev/null differ diff --git a/.vs/HPC-Training/FileContentIndex/19436db1-42a6-4ab7-85db-e559d74c0d13.vsidx b/.vs/HPC-Training/FileContentIndex/19436db1-42a6-4ab7-85db-e559d74c0d13.vsidx deleted file mode 100644 index 7dd7f4c..0000000 Binary files a/.vs/HPC-Training/FileContentIndex/19436db1-42a6-4ab7-85db-e559d74c0d13.vsidx and /dev/null differ diff --git a/.vs/HPC-Training/FileContentIndex/27142df3-a65f-4650-8aa8-e75ee6302afc.vsidx b/.vs/HPC-Training/FileContentIndex/27142df3-a65f-4650-8aa8-e75ee6302afc.vsidx deleted file mode 100644 index 9d1c69c..0000000 Binary files a/.vs/HPC-Training/FileContentIndex/27142df3-a65f-4650-8aa8-e75ee6302afc.vsidx and /dev/null differ diff --git a/.vs/HPC-Training/FileContentIndex/b04b123b-9651-44ce-a58f-de685ef29d40.vsidx b/.vs/HPC-Training/FileContentIndex/b04b123b-9651-44ce-a58f-de685ef29d40.vsidx deleted file mode 100644 index 3331fbb..0000000 Binary files a/.vs/HPC-Training/FileContentIndex/b04b123b-9651-44ce-a58f-de685ef29d40.vsidx and /dev/null differ diff --git a/.vs/HPC-Training/FileContentIndex/read.lock b/.vs/HPC-Training/FileContentIndex/read.lock deleted file mode 100644 index e69de29..0000000 diff --git a/.vs/HPC-Training/v17/.wsuo b/.vs/HPC-Training/v17/.wsuo deleted file mode 100644 index 03b2364..0000000 Binary files a/.vs/HPC-Training/v17/.wsuo and /dev/null differ diff --git a/.vs/ProjectSettings.json b/.vs/ProjectSettings.json deleted file mode 100644 index f8b4888..0000000 --- a/.vs/ProjectSettings.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "CurrentProjectSetting": null -} \ No newline at end of file diff --git a/.vs/VSWorkspaceState.json b/.vs/VSWorkspaceState.json deleted file mode 100644 index a4e3939..0000000 --- a/.vs/VSWorkspaceState.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "ExpandedNodes": [ - "", - "\\.github", - "\\.github\\workflows", - "\\src", - "\\src\\chapter2", - "\\src\\chapter3", - "\\src\\chapter5" - ], - "SelectedNode": "\\src\\chapter2\\scanf.md", - "PreviewInSolutionExplorer": false -} \ No newline at end of file diff --git a/.vs/slnx.sqlite b/.vs/slnx.sqlite deleted file mode 100644 index 3a53b6c..0000000 Binary files a/.vs/slnx.sqlite and /dev/null differ diff --git a/src/SUMMARY.md b/src/SUMMARY.md index ff51d94..78a89db 100644 --- a/src/SUMMARY.md +++ b/src/SUMMARY.md @@ -15,6 +15,7 @@ - [Compilation](./chapter2/compilation.md) - [Types & Variables](./chapter2/vars.md) - [Printing](./chapter2/printing.md) + - [Input](./chapter2/input.md) - [Arrays & Strings](./chapter2/array.md) - [Control Flow](./chapter2/ctrl-flow.md) - [Loops](./chapter2/loops.md) diff --git a/src/chapter2/input.md b/src/chapter2/input.md new file mode 100644 index 0000000..572014b --- /dev/null +++ b/src/chapter2/input.md @@ -0,0 +1,192 @@ +# Input + +We're now going to discuss how to take user input from the standard input (`stdin`) in C. + +## `scanf` + +`scanf()` allows you to read different data types from the user's input and store them in variables, making it a versatile function for interactive applications. It enables you to control the input format, extract data from the input stream, and store it in the appropriate variables. + +### Signature + +The general signature of `scanf()` is similar to `printf()`, it takes a format string indicating the format of the input sequence and a variadic list of addresses (pointers)where values are stores. `scanf()`'s format string uses a similar format specification to `printf()` however, the variable specifiers (denoted with `%`) indicate values that are to be read in and stored in program variables. As we are reading values in with `scanf()`, when we wish to store a variable we must pass the address of the variable we want to store the value in. This is because variables have copy semantics in C meaning we cannot pass a variable to a function and get the modified value with returning it or using a pointer. `scanf()` uses pointers. + +```c +scanf(char* fmtstring, ...); +``` + +### Example + +This simple program is similar to the `printf()` example we saw earlier in the book except, instead of hard coding values we are able to take input from the user in the form `x + y` and the program will return the result. + +```c +#include + +int main() +{ + double a = 0.0; + double b = 0.0; + double sum = 0.0; + + printf(">> ") + scanf("%f + %f", &a, &b); + sum = a + b; + printf("%f", sum); + + return 0; +} +``` + +### Formatting Specification + +The format specification is a mirror to that used by `printf()` (there are many `_f()` functions in the C standard library that all use similar format specifications) as values being read in must conform to a given C type. This allows us to easily convert the incoming string data as `int`, `double` or even substrings. + +The general format specification is as below: + +`_%\[width\]\[.precision\]\[length\]type-specifier_` + +There are a variety of different options for each part of the specification. Below is a series of tables breaking down the various options for each sub-specifier but note that only _type-specifier_ is needed, the others are optional. + +#### Type Specifiers + +| Type Specifier | Type | Example | +|:--------------:|:------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------:|:--------------------------:| +| `%` | Two sequential `%` will result in a single `%` being printed. | `%` | +| `d` or `i` | Signed Decimal Integer | `392` | +| `u` | Unsigned Decimal Integer | `7235` | +| `o` | Unsigned Octal Integer | `610` | +| `x` or `X` | Unsigned Hexadecimal Integer (X: uppercase variant) | `7fa` or `7FA` | +| `f` or `F` | Decimal Floating Point (F: uppercase variant for special numbers eg. `nan` vs `NAN`) | `392.65` | +| `e` or `E` | Scientific Notation (mantissa and exponent) (E: uppercase variant) | `3.9265e+2` or `3.9265E+2` | +| `g` or `G` | Use the shortest representation: `%e` or `%f` (G: uses uppercase variants) | `7fa` or `7Fa` | +| `a` or `A` | Hexadecimal Floating Point (A: uppercase variant) | `7fa` or `7Fa` | +| `c` | Character | `a` | +| `s` | String | `example` | +| `p` | Pointer Address | `0x7ffce531691c` | +| `n` | Prints nothing. The argument corresponding to this specifier must be pointer to a signed integer. Stores the number of character read so far. | | +| `[set]` | Matches a non-empty sequence of character from set of characters. If the first character of the set is `^`, then all characters not in the set are matched. If the set begins with `]` or `^]` then the `]` character is also included into the set. It is implementation-defined whether the character - in the non-initial position in the scanset may be indicating a range, as in `[0-9]`. If a width specifier is used, matches only up to _width_. Always stores a null character in addition to the characters matched (so the argument array must have room for at least _width+1_ characters) | | +| `*` | Assignment-suppressing character. If this option is present, the function does not assign the result of the conversion to any receiving argument (optional). | | + +#### Width + +| Width | Description | +|:--------:|:----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------:| +| _number_ | Minimum number of characters to be printed. If the value to be printed is shorter than this number, the result is padded with blank spaces. The value is not truncated even if the result is larger. | + +#### Precision + +| .precision | Description | +|:----------:|:-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------:| +| _.number_ | For integer specifiers (`d`, `i`, `o`, `u`, `x`, `X`): precision specifies the minimum number of digits to be read. If the value read is shorter than this number, the result is padded with leading zeros. The value is not truncated even if the result is longer. A precision of `0` means that no character is written for the value 0. For `a`, `A`, `e`, `E`, `f` and `F` specifiers: this is the number of digits to be printed after the decimal point (by default, this is 6). For g and G specifiers: This is the maximum number of significant digits to be printed. For `s`: this is the maximum number of characters to be printed. By default all characters are printed until the ending null character is encountered. If the period is specified without an explicit value for precision, `0` is assumed. | + +#### Length + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Type Specifier
Length Modifierd, iu, o, x, Xf, F, e, E, g, G, a, Acspn
(none)intunsigned intdoubleintchar*void*int*
hhsigned charunsigned charsigned char*
hshort intunsigned short intshort int*
llong intunsigned long intwint_twchar_t*long int*
lllong long intunsigned long long intlong long int*
jintmax_tuintmax_tintmax_t
zsize_tsize_tsize_t
tptrdiff_tptrdiff_tptrdiff_t
Llong double
diff --git a/src/chapter2/printing.md b/src/chapter2/printing.md index 1be7f3e..196c36b 100644 --- a/src/chapter2/printing.md +++ b/src/chapter2/printing.md @@ -17,7 +17,7 @@ printf(char* fmtstring, ...); > **Note:** > > - Ignore the use of `char*` for now. -> - `printf()` is that it doesn't pad the end if the output string with a newline so you will have to manually provide it. The newline character is `'\n'`. The backslash is a special character that indicates the proceeding character is "escaped". Escaped characters have special meanings for string and character data. +> - `printf()` is different to `puts()` in that it doesn't pad the end if the output string with a newline so you will have to manually provide it. The newline character is `'\n'`. The backslash is a special character that indicates the proceeding character is "escaped". Escaped characters have special meanings for string and character data. > If the format string doesn't have any positional arguments then `printf()` will just print the string like `puts()`. > `printf()` is not able to print data of any kind without a format string ie. `printf(10)` would fail to compile. diff --git a/src/chapter2/scanf.md b/src/chapter2/scanf.md deleted file mode 100644 index dcdf536..0000000 --- a/src/chapter2/scanf.md +++ /dev/null @@ -1,212 +0,0 @@ -# User input in C - -We're going to briefly discuss how to take user input in C. - -## scanf() -scanf() allows you to read different data types from the user's input and store them in variables, making it a versatile function for interactive applications. It enables you to control the input format, extract data from the input stream, and store it in the appropriate variables. - -### Signature - -The general siHere are some key points about the scanf() function and its variadic nature: - -1)Variadic Function: scanf() is a variadic function, which means it can accept a variable number of arguments. The first argument is always a format string that specifies the expected input format, while subsequent arguments (after the format string) are the memory addresses of variables where the data will be stored. - -2)Format Specifiers: The format string in scanf() consists of format specifiers, introduced by the % character, which indicates the expected type of input. For example, %d is used for integers, %f for floating-point numbers, %c for characters, %s for strings, etc. These format specifiers tell scanf() how to interpret and read the input data. - -3)Variable Input: With scanf(), you can read multiple values of different data types in a single call, as long as the format string and the subsequent variable arguments match in number and order. For instance, scanf("%d%f", &num, &flt); will read an integer and a floating-point number from the user. - -4)Address (&) Operator: Just like in printf(), when using scanf(), you need to provide the memory address of the variables where the data should be stored. This is done using the address-of operator &. For example, scanf("%d", &num); reads an integer from the user and stores it in the variable num. - -5)Positional Arguments: Unlike printf(), scanf() does not support positional argument indexing in the format string. The variadic arguments are consumed in the same order they appear in the format string. For instance, scanf("%d %f", &num, &flt); expects an integer followed by a floating-point number from the user. - -6)Handling Newlines: As mentioned before, scanf() can leave the newline character (\n) in the input stream, which may cause issues with subsequent input functions. To handle this, you can include a space before the format specifier, like scanf(" %c", &ch);, to skip any leading whitespace characters, including the newline.gnature of `scanf()` is quite unique in C and how it achieves it is a bit of compiler magic in order to actually implement but you do not have to worry about it. `scanf()` takes as its first argument a string that represents the output format of the printed text. The next argument is the `...`. This is called the ellipsis and it is used to represent a variable number of untyped function arguments. This allows you to pass ass many arguments as you want to `printf()` and it will print them all as long as there are an equivalent number of positional arguments in the format string. The variadic arguments are inserted in output string in the same order they are passed to `printf()` ie. there is now way to indicate in the format string which variadic argument to use at any given positional argument. The positional argument introducer character is the `%` followed by a modifier to indicate in incoming type. - -```c -The C library function int scanf(const char *format, ...) reads formatted input from stdin. -``` - - - -### Example - -// C program to implement -// scanf -#include - -int main() -{ - int a, b; - - printf("Enter first number: "); - scanf("%d", &a); - - printf("Enter second number: "); - scanf("%d", &b); - - printf("A : %d \t B : %d" , - a , b); - - return 0; -} - - - - -### Formatting Specification - -The general format for the scanf () function format string is: - -`%[*][width][length]specifier` - -Thus the format specifier has the following parts: - -1)Non-whitespace character:These are the characters except % that consume one identical character from the input stream.
-Whitespace character: All consecutive whitespace characters are considered as one whitespace character. The same goes forscape sequences too.
-2)Conversion specification: It has the following format:
-a)%: Character that specifies the beginning.
-b)*: Called assignment suppressing character. If present, the scanf does not assign the result to any receiving parameters. This parameter is optional.
-c)Field width:Optional parameter (a positive integer) that specifies a maximum field width.
-d)Length: Specifies the size of receiving an argument. - -There are a variety of different options for each part of the specification. Below is a series of tables breaking down the various options for each sub-specifier but note that only _type-specifier_ is needed, the others are optional. - -#### Type Specifiers - -| Type Specifier | Type | Example | -|:--------------:|:------------------------------------------------------------------------------------------------------------------------------------------------:|:--------------------------:| -| `%` | Two sequential `%` will result in a single `%` being printed. | % | -| `d` or `i` | Signed Decimal Integer | `392` | -| `u` | Unsigned Decimal Integer | `7235` | -| `o` | Unsigned Octal Integer | `610` | -| `x` or `X` | Unsigned Hexadecimal Integer (`X`: uppercase variant) | `7fa` or `7FA` | -| `f` or `F` | Decimal Floating Point (`F`: uppercase variant for special numbers eg. `nan` vs `NAN`) | `392.65` | -| `e` or `E` | Scientific Notation (mantissa and exponent) (`E`: uppercase variant) | `3.9265e+2` or `3.9265E+2` | -| `g` or `G` | Use the shortest representation: `%e` or `%f` (`G`: uses uppercase variants) | `7fa` or `7Fa` | -| `a` or `A` | Hexadecimal Floating Point (`A`: uppercase variant) | `7fa` or `7Fa` | -| `c` | Character | `a` | -| `s` | String | `example` | -| `p` | Pointer Address | `0x7ffce531691c` | -| `n` | Prints nothing. The argument corresponding to this specifier must be pointer to a signed integer. Stores the number of character written so far. | | | -| `[set]` |Matches non-.empty sequence of characters from the given set. If preceded by ^, then characters not in set are matched. |`scanf(%s[A-Z,_,a,b,c]s,str)`| | - - -#### Width - -| Width | Description | -|:--------:|:----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------:| -| _number_ | Minimum number of characters to be printed. If the value to be printed is shorter than this number, the result is padded with blank spaces. The value is not truncated even if the result is larger. | -| `*` | The **width** is not specified in the **format** string, but taken from the next variadic argument from `printf()`. | - - -#### Length - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Type Specifier
Length Modifierd, iu, o, x, Xf, F, e, E, g, G, a, Acspn
(none)intunsigned intdoubleintchar*void*int*
hhsigned charunsigned charsigned char*
hshort intunsigned short intshort int*
llong intunsigned long intwint_twchar_t*long int*
lllong long intunsigned long long intlong long int*
jintmax_tuintmax_tintmax_t
zsize_tsize_tsize_t
tptrdiff_tptrdiff_tptrdiff_t
Llong double