A3 - debugging and standard IO
common bugs
- syntax and compilation errors: caught by compilers before running
- logical errors
- memory management errors
- off-by-one errors
- using uninitialized variables
standard IO
-
standard IO streams:
- standard input (stdin): keyboard command line input
- standard output (stdout): command line output
- standard error (stderr): special error stream
-
format specifier help the compiler know what data type is being used:
| format specifier | description | example output |
|---|---|---|
%d or %i |
signed decimal integer | 42, -7 |
%u |
unsigned decimal integer | 42 |
%o |
unsigned octal integer | 52 |
%x |
unsigned hexadecimal integer (lowercase) | 2a |
%x |
unsigned hexadecimal integer (uppercase) | 2A |
%f or %F |
decimal floating point | 3.141593 |
%e |
scientific notation (lowercase e) | 3.141593e+00 |
%e |
scientific notation (uppercase E) | 3.141593E+00 |
%g |
use %e or %f (whichever is shorter, removes trailing zeros) |
3.14 |
%G |
same as %g but with uppercase E if scientific |
3.14 |
%a |
hexadecimal floating point (lowercase) | 0x1.91eb86p+1 |
%A |
hexadecimal floating point (uppercase) | 0X1.91EB86P+1 |
%c |
single character | a |
%s |
string of characters | hello |
%p |
pointer address | 0x7ffeedcba123 |
%n |
writes number of characters printed so far into an integer variable | (no output) |
%% |
literal percent sign | % |
| modifier | meaning | used with |
|---|---|---|
h |
short integer | %hd, %hu |
hh |
signed/unsigned char | %hhd, %hhu |
l |
long integer | %ld, %lu |
ll |
long long integer | %lld, %llu |
l |
long double | %lf, %le |
z |
size_t type |
%zu |
t |
ptrdiff_t type |
%td |
j |
intmax_t / uintmax_t |
%jd, %ju |
standard output
-
found in
<stdio.h>, eg:printf,putchar,fflush,stdout -
C stores IO in temporary memory called buffer:
- line buffering: transmitted as a block when a new-line character is added
- full buffering: transmitted as a block when a buffer is filled
- no buffering: transmitted as they are written
-
printfis line buffered -
it will not be printed until a new line is added, ie.
/n -
fflush(stdout)prints the output buffer -
to change the buffering mode of stdout to unbuffered:
setvbuf(stdout, NULL, _IONBF, 0) \\_IONBF = no buffering -
to reset it:
setvbuf(stdout, NULL, _IOLBF, 0) \\_IOLBF = line buffering
standard input
- found in
<stdio.h>, eg:scanf, 'getchar', 'fgets',stdin
#include <stdio.h>
#include <string.h>
#define BUFFER_SIZE 1000
int main() {
char name[50];
char buffer[BUFFER_SIZE];
int age;
char c;
printf("enter your name: ");
scanf("%49s", name); // Limit input to avoid buffer overflow
printf("enter your age: ");
scanf("%d", &age); // takes a reference to the age variable
printf("your name is %s and you are %d years old.\n", name, age);
// scanf can leave a newline character in the input buffer
// clear the input buffer before using fgets
while ((c = getchar()) != '\n' && c != EOF);
printf("enter a character: ");
c = getchar(); // reads a single character
printf("you entered: %c\n", c);
// printf("enter a line of text (gets - unsafe): ");
// gets(buffer); // unsafe, can cause buffer overflow
// printf("you entered: %s\n", buffer);
printf("enter a line of text (fgets - safe): ");
fgets(buffer, BUFFER_SIZE, stdin); // safely reads up to BUFFER_SIZE - 1 characters
printf("you entered: %s\n", buffer);
while ((c = getchar()) != '\n' && c != EOF); // clear the input buffer again
while (fgets(buffer, BUFFER_SIZE, stdin) != NULL) {
if (strcmp(buffer, "exit\n") == 0) {
break; // exit the loop if the user types "exit" and presses Enter
}
printf("you entered: %s", buffer);
}
return 0;
}