mirror of
https://github.com/TrudeEH/web.git
synced 2025-12-06 08:23:37 +00:00
[BREAKING] Simplify URL paths
This commit is contained in:
720
content/notes/c-language.md
Normal file
720
content/notes/c-language.md
Normal file
@@ -0,0 +1,720 @@
|
||||
---
|
||||
title: C Language
|
||||
description: The C Programming Language
|
||||
summary: The C Programming Language
|
||||
draft: false
|
||||
tags:
|
||||
- c
|
||||
- programming
|
||||
author: TrudeEH
|
||||
showToc: true
|
||||
---
|
||||
|
||||
## Tools
|
||||
|
||||
- `indent` (format code)
|
||||
- `gcc` / `clang` (compile code)
|
||||
- `man <function/topic>` (read documentation)
|
||||
- `tldr <command>` (quick command usage examples)
|
||||
- `valgrind` (Look for memory leaks)
|
||||
- `valgrind —tool=massif` (check a program's RAM usage)
|
||||
- View the output with `Massif-Visualizer`
|
||||
- `gdb` (debugger)
|
||||
- `gdb —args <program>` (if the program has command line args)
|
||||
- Type `run` to start debugging, and `backtrace` for error details.
|
||||
- `file` Check file information and, if it is an executable, compilation details.
|
||||
- `perf stat -r 10 -d <program>` Benchmark a program.
|
||||
|
||||
## Data Types and Variables
|
||||
|
||||
The binary length of each data type depends on the CPU, OS, and compiler, but in general, they follow the C specifications. To check the exact values for your platform, see `limits.h`.
|
||||
|
||||
| Type | C SPEC | x64 Linux (Example) |
|
||||
| ------------- | --------- | ------------------- |
|
||||
| `char` | ≥ 8 bits | 8 bits |
|
||||
| `short` | ≥ 16 bits | 16 bits |
|
||||
| `int` | ≥ 16 bits | 32 bits |
|
||||
| `long` | ≥ 32 bits | 64 bits |
|
||||
| `long long` | ≥ 64 bits | 64 bits |
|
||||
| `float` | | 32 bits |
|
||||
| `double` | | 64 bits |
|
||||
| `long double` | | 128 bits |
|
||||
|
||||
| Unsigned Bytes (8 bits) | Maximum Decimal Value |
|
||||
| ----------------------- | --------------------------------------------------- |
|
||||
| 1 | 255 |
|
||||
| 2 | 65.535 |
|
||||
| 4 | 4.294.967.295 |
|
||||
| 8 | 18.446.744.073.709.551.615 |
|
||||
| 16 | 340.282.366.920.938.463.463.374.607.431.768.211.455 |
|
||||
| 32 | 1.157 × 10^76 |
|
||||
|
||||
Examples
|
||||
|
||||
```C
|
||||
char a = 'C'; // single character %c ''
|
||||
char b[] = "Trude" // array of characters %s ""
|
||||
unsigned int // Unsigned. The number must be positive.
|
||||
int // Signed. Negative and positive numbers.
|
||||
char f = 100; // %d (number) %c (character)
|
||||
unsigned char g = 255; // %d (number) %c (character)
|
||||
short h = 32767; // %d
|
||||
unsigned short i = 65535; // %d
|
||||
int j = 2147483647; // %d
|
||||
unsigned int k = 4294967295; // %u
|
||||
long long l = ... // %lld
|
||||
unsigned long long m = ...32U // %llu
|
||||
float c = 3.141592; // %f
|
||||
double d = 3.141592653589793; // %lf
|
||||
```
|
||||
|
||||
### Format Specifiers
|
||||
|
||||
These format codes indicate which data type is being used. They are needed for `printf` and `scanf`, for example.
|
||||
|
||||
| `%` | Description |
|
||||
| ------ | ------------------------------------------- |
|
||||
| `%%` | `%` |
|
||||
| `%-` | left align |
|
||||
| `%.1` | decimal precision |
|
||||
| `%1` | minimum field width |
|
||||
| `%c` | character |
|
||||
| `%d` | signed integer of base 10 |
|
||||
| `%e` | scientific notation |
|
||||
| `%f` | float |
|
||||
| `%hd` | small decimal (short) |
|
||||
| `%hhd` | very small decimal (char) |
|
||||
| `%i` | integer of any base (detects automatically) |
|
||||
| `%lf` | double |
|
||||
| `%o` | octal (base 8) |
|
||||
| `%p` | address/pointer |
|
||||
| `%s` | string (array of characters) |
|
||||
| `%u` | unsigned integer of base 10 |
|
||||
| `%x` | hexadecimal (base 16) |
|
||||
|
||||
```C
|
||||
float item1 = 5.75;
|
||||
printf("Item1: %-8.2\n", item1);
|
||||
```
|
||||
|
||||
## Numbers
|
||||
|
||||
`C` handles multiple numeric bases.
|
||||
|
||||
```C
|
||||
int x = 255; // Decimal
|
||||
int y = 0xff; // Hexadecimal
|
||||
int z = 0b10; // Binary (not native for C, but GCC and Clang support this syntax)
|
||||
```
|
||||
|
||||
### Type Casting
|
||||
|
||||
Convert a type into another.
|
||||
|
||||
```C
|
||||
int x = 1, y = 10;
|
||||
float z = (float) x / (float) y;
|
||||
```
|
||||
|
||||
## ANSI Escape Sequences
|
||||
|
||||
Escape sequences are used to allow typing characters in a string that would otherwise be interpreted as `C` instructions.
|
||||
|
||||
| Seq | Name | Description |
|
||||
| ------ | ------------------ | -------------------------------------------------------------------------------------- |
|
||||
| `\a` | Alarm or Beep | It is used to generate a bell sound in the C program. |
|
||||
| `\b` | Backspace | It is used to move the cursor one place backward. |
|
||||
| `\f` | Form Feed | It is used to move the cursor to the start of the next logical page. |
|
||||
| `\n` | New Line | It moves the cursor to the start of the next line. |
|
||||
| `\r` | Carriage Return | It moves the cursor to the start of the current line. |
|
||||
| `\t` | Horizontal Tab | It inserts some whitespace to the left of the cursor and moves the cursor accordingly. |
|
||||
| `\v` | Vertical Tab | It is used to insert vertical space. |
|
||||
| `\\` | Backlash | Use to insert backslash character. |
|
||||
| `\'` | Single Quote | It is used to display a single quotation mark. |
|
||||
| `\"` | Double Quote | It is used to display double quotation marks. |
|
||||
| `\?` | Question Mark | It is used to display a question mark. |
|
||||
| `\ooo` | Octal Number | It is used to represent an octal number. |
|
||||
| `\xhh` | Hexadecimal Number | It represents the hexadecimal number. |
|
||||
| `\0` | `NULL` | It represents the NULL character. |
|
||||
| `\e` | Escape sequence | It represents the ASCII escape character. |
|
||||
| `\s` | Space Character | It represents the ASCII space character. |
|
||||
| `\d` | Delete Character | It represents the ASCII DEL character. |
|
||||
|
||||
## Constants
|
||||
|
||||
Add `const` before a variable declaration to prevent the value from being changed.
|
||||
|
||||
```C
|
||||
const float PI 3.14159;
|
||||
```
|
||||
|
||||
## Macros
|
||||
|
||||
### Object-Like Macros
|
||||
|
||||
Another alternative to `const` is to use `define`.
|
||||
|
||||
```C
|
||||
#define MAX 9
|
||||
int test = MAX;
|
||||
|
||||
#undef MAX # Delete the macro
|
||||
#define MAX 11 # Create a new macro with the same name
|
||||
```
|
||||
|
||||
This command replaces the 'MAX' word with '9', using the preprocessor (before compiling); No memory is required.
|
||||
|
||||
### Function-Like Macros
|
||||
|
||||
Function-Like Macros behave in the same way as previous macros, but they can accept arguments to replace in the final code:
|
||||
|
||||
```c
|
||||
#define Max(a,b) ((a)>(b)) ? (a):(b))
|
||||
int i = Max(4,5);
|
||||
```
|
||||
|
||||
In this example, the code pre-compiles to:
|
||||
|
||||
```c
|
||||
int i = ((4)>(5)) ? (4):(5));
|
||||
```
|
||||
|
||||
Read the [GNU's C Preprocessor](https://gcc.gnu.org/onlinedocs/cpp/) manual for more details.
|
||||
|
||||
> Macros have no type safety checks, so, if possible, avoid using them. To build the final C code (before it is compiled), use `gcc -E`.
|
||||
|
||||
## Arithmetic Operators
|
||||
|
||||
```C
|
||||
// + (addition)
|
||||
// - (subtraction)
|
||||
// * (multiplication)
|
||||
// / (division)
|
||||
// % (modulus / remainder)
|
||||
// ++ (increment)
|
||||
// -- (decrement)
|
||||
int x = 1;
|
||||
int y = 2;
|
||||
int z = x + y; // 3
|
||||
// Augmented assignment operators
|
||||
x++; // x = x + 1
|
||||
y--; // y = y - 1
|
||||
x+=2; // x = x + 2
|
||||
x*=2; // x = x * 2
|
||||
```
|
||||
|
||||
## Control Flow
|
||||
|
||||
### Boolean Values
|
||||
|
||||
In `C`, there are no `true` or `false` keywords, so integers are used instead.
|
||||
- `0` usually represents `false`.
|
||||
- Any non-zero value (`1`, `-1`, etc…) represents `true`.
|
||||
|
||||
### IF Statement
|
||||
|
||||
```C
|
||||
if(a == 1) printf("A is 1.\\n");
|
||||
```
|
||||
|
||||
Use `{}` for multiple items.
|
||||
|
||||
```C
|
||||
if(age == 18){
|
||||
printf("You are 18.");
|
||||
}
|
||||
else if(age < 0){
|
||||
printf("You haven't been born yet.");
|
||||
}
|
||||
else{
|
||||
printf("You are not 18.");
|
||||
}
|
||||
```
|
||||
|
||||
### Switch Statement
|
||||
|
||||
Generally faster than `IF` when over 5 cases.
|
||||
|
||||
```C
|
||||
switch(grade){
|
||||
case 'A':
|
||||
printf("perfect.\n");
|
||||
break;
|
||||
case 'B':
|
||||
printf("good.\n");
|
||||
break;
|
||||
case 'C':
|
||||
printf("okay.\n");
|
||||
break;
|
||||
case 'D':
|
||||
printf("meh.\n");
|
||||
break;
|
||||
case 'F':
|
||||
printf("failed.\n");
|
||||
break;
|
||||
default:
|
||||
printf("Enter only valied grades.\n");
|
||||
}
|
||||
// If break; is missing, the next case is also executed.
|
||||
```
|
||||
|
||||
## Operators
|
||||
|
||||
### Logical Operators
|
||||
|
||||
#### AND (`&&`)
|
||||
|
||||
```C
|
||||
if(temp >= 0 && temp <= 30){
|
||||
printf("\nThe weather is good.")
|
||||
}
|
||||
```
|
||||
|
||||
#### OR (`||`)
|
||||
|
||||
```C
|
||||
if(temp <= 0 || temp >= 30){
|
||||
printf("\nThe weather is good.")
|
||||
}
|
||||
```
|
||||
|
||||
#### NOT (`!`)
|
||||
|
||||
```C
|
||||
if(!(temp <= 0 || temp >= 30)){
|
||||
printf("\nThe weather is bad.")
|
||||
}
|
||||
```
|
||||
|
||||
##### **NOT** Truth Table
|
||||
|
||||
| `condition` | `!(condition)` |
|
||||
| ----------- | -------------- |
|
||||
| 1 | 0 |
|
||||
| 0 | 1 |
|
||||
|
||||
### Ternary Operator
|
||||
|
||||
Shorthand syntax for if/else when assigning or returning a value.
|
||||
|
||||
```C
|
||||
// (condition) ? value if true : value if false
|
||||
int max = (x > y) ? x : y;
|
||||
```
|
||||
|
||||
### Bitwise Operators
|
||||
|
||||
Special operators used in bit-level programming. (Logic gates)
|
||||
|
||||
```C
|
||||
int x = 6; // 6 = 00000110
|
||||
int y = 12; // 12 = 00001100
|
||||
int z = 0; // 0 = 00000000
|
||||
z = x & y; // AND - 00000100 (4)
|
||||
z = x | y; // OR - 00001110 (14)
|
||||
z = x ^ y; // XOR - 00001010 (10)
|
||||
z = x << 1; // Left Shift - 00001100 (12) (Shift all bits to the left.)
|
||||
z = x >> 1; // Right Shift - 00000011 (3) (Shift all bits to the right.)
|
||||
```
|
||||
|
||||
## Functions
|
||||
|
||||
Functions are snippets of code that can be reused multiple times across the same file. These can receive multiple arguments as input, but can only return a single value.
|
||||
|
||||
```C
|
||||
void myFunction(); // Function Prototype
|
||||
int main() {
|
||||
myFunction(); // Call function
|
||||
return 0;
|
||||
}
|
||||
void myFunction() { // Function Definition
|
||||
//...
|
||||
}
|
||||
```
|
||||
|
||||
### Arguments
|
||||
|
||||
```C
|
||||
void greet(char x[], int y);
|
||||
int main() {
|
||||
char name[] = "Trude";
|
||||
int age = 132;
|
||||
greet(name, age);
|
||||
}
|
||||
void greet(char x[], int y) {
|
||||
printf("\nHello %s, you are %d years old.", x, y);
|
||||
}
|
||||
```
|
||||
|
||||
### Return Values
|
||||
|
||||
```C
|
||||
double square(double x);
|
||||
int main() {
|
||||
double x = square(3.14);
|
||||
printf("%lf", x);
|
||||
return 0;
|
||||
}
|
||||
double square(double x) {
|
||||
return x * x;
|
||||
}
|
||||
```
|
||||
|
||||
### Recursion
|
||||
|
||||
A function can call itself, creating a loop.
|
||||
|
||||
```C
|
||||
int i = 0;
|
||||
void plusOne(int n) {
|
||||
printf("%d", n);
|
||||
if (n < 10000) plusOne(n);
|
||||
}
|
||||
```
|
||||
|
||||
### Function Prototypes
|
||||
|
||||
Function declaration without a body, before `main()`.
|
||||
Prototypes ensure that calls to a function are made with the correct arguments, and allow functions to be defined after the function call.
|
||||
|
||||
```C
|
||||
void hello(char[], int); // Function Prototype
|
||||
int main() {
|
||||
hello(//...);
|
||||
return 0;
|
||||
}
|
||||
void hello(char name[], int age){
|
||||
//...
|
||||
}
|
||||
```
|
||||
|
||||
> **Note:** Many C compilers don't check for parameter matching, so missing arguments can lead to unexpected behavior.
|
||||
>
|
||||
> Function prototypes flag errors when arguments are missing.
|
||||
>
|
||||
> While not necessary if functions are declared before `main()`, using prototypes first and then declaring functions after `main()` improves readability and aids debugging.
|
||||
|
||||
## Loops
|
||||
|
||||
### For Loop
|
||||
|
||||
Loop through an interval.
|
||||
|
||||
```C
|
||||
for(int i = 0; i < 10; i++){
|
||||
printf("%d\n", I); //0-9
|
||||
}
|
||||
//Multiple initial variables
|
||||
for(int i = 0, int y = 1; i < 10; i++){
|
||||
printf("%d\n", I); //0-9
|
||||
}
|
||||
```
|
||||
|
||||
### While Loop
|
||||
|
||||
Loop until a condition is met.
|
||||
|
||||
```C
|
||||
while(test == 1){
|
||||
printf("Test is not 1.\n");
|
||||
}
|
||||
```
|
||||
|
||||
### Do While Loop
|
||||
|
||||
Run the code once, then repeat until a condition is met.
|
||||
|
||||
```C
|
||||
do {
|
||||
printf("Enter a number above 0: ");
|
||||
scanf("%d", &number)
|
||||
} while (number > 0);
|
||||
```
|
||||
|
||||
### Endless Loop
|
||||
|
||||
```C
|
||||
while (true) {
|
||||
...
|
||||
}
|
||||
```
|
||||
|
||||
### Continue & Break Statements
|
||||
|
||||
- `continue` - Skips rest of code and forces the next iteration of the loop.
|
||||
- `break` - Exits a loop/switch.
|
||||
|
||||
## Structs
|
||||
|
||||
Structs can group values. They are similar to classes, but can't hold methods.
|
||||
Being able to group variables avoids repetition and name collision (when two variables have the same name).
|
||||
|
||||
```C
|
||||
struct Player {
|
||||
char name[12];
|
||||
int score;
|
||||
};
|
||||
int main(){
|
||||
struct Player player1;
|
||||
struct Player player2;
|
||||
strcpy(player1.name, "Trude");
|
||||
player1.score = 4;
|
||||
strcpy(player2.name, "JCionx");
|
||||
player2.score = 7;
|
||||
player1.score; //4
|
||||
}
|
||||
```
|
||||
|
||||
### Arrays of Structs
|
||||
|
||||
```C
|
||||
struct Student {
|
||||
char name[12];
|
||||
float gpa;
|
||||
};
|
||||
int main() {
|
||||
struct Student s1 = {"Peter", 3.0};
|
||||
struct Student s2 = {"Jean", 4.0};
|
||||
struct Student s3 = {"David", 2.5};
|
||||
struct Student students[] = {s1, s2, s3};
|
||||
printf("%f\n", students[0].gpa); // Print the student 1 gpa.
|
||||
return 0;
|
||||
}
|
||||
```
|
||||
|
||||
## Typedef
|
||||
|
||||
Create a shortcut for a type of data.
|
||||
|
||||
```C
|
||||
typedef char user[25];
|
||||
int main() {
|
||||
user user1 = "Trude";
|
||||
}
|
||||
```
|
||||
|
||||
Typedef can be used to simplify structs.
|
||||
|
||||
```C
|
||||
typedef struct {
|
||||
char name[25];
|
||||
char password[12];
|
||||
int id;
|
||||
} User;
|
||||
|
||||
int main(){
|
||||
User user1 = {"Trude", "hello123", 12335};
|
||||
}
|
||||
```
|
||||
|
||||
## Nul Character
|
||||
|
||||
```C
|
||||
\0 // This character represents 00000000 and marks the end of a string.
|
||||
// Same as 0x0 and null.
|
||||
```
|
||||
|
||||
## Command-Line Arguments
|
||||
|
||||
- `argc` is the number of arguments in `argv`.
|
||||
- `argv[0]` is the name of the program, all others are the user arguments (the entire command used to initialize the program is stored).
|
||||
|
||||
```C
|
||||
int main(int argc, char argv[]) {
|
||||
if (argc == 2) {
|
||||
printf("hello, %s\n", argv[1]);
|
||||
} else {
|
||||
printf("You need to add 1 argument.\n");
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
```
|
||||
|
||||
## Enums
|
||||
|
||||
Enums are a list of constant values that help make programs more readable.
|
||||
Enums are treated as integers.
|
||||
|
||||
```C
|
||||
// enum Day{Sun, Mon, Tue, Wed, Thu, Fri, Sat}; (This enum starts from 0 to 6.)
|
||||
enum Day{Sun = 1, Mon = 2, Tue = 3, Wed = 4, Thu = 5, Fri = 6, Sat = 7};
|
||||
int main(){
|
||||
enum Day today = Sun;
|
||||
if(today == Sun || today == Sat){
|
||||
printf("It's the weekend.");
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Memory Management
|
||||
|
||||
- `a` - A variable
|
||||
- `&a` - The address of the variable `a` in memory. (The formatter is `%p`)
|
||||
- `int *p` - A pointer. Holds the memory address of another variable. (8 bits usually, depends on the CPU architecture (max RAM supported).
|
||||
- `*p` - Dereference a pointer. Returns the value in the address stored. (go to address's variable)
|
||||
|
||||
```C
|
||||
int age = 21;
|
||||
int *pAge = &age;
|
||||
int valueOfAge = *pAge;
|
||||
printf("%p and %p are the same.", &age, pAge);
|
||||
```
|
||||
|
||||
> A pointer must be `int`, as it stores a memory address.
|
||||
|
||||
### Strings
|
||||
|
||||
Strings are arrays of characters.
|
||||
A string can be returned as a memory address.
|
||||
A string ends in `\0`, the null character.
|
||||
|
||||
```C
|
||||
/* Use char[] when:
|
||||
- The maximum string length is known.
|
||||
- No need to modify the whole string.
|
||||
- No need to pass the string to a function [that modifies it]
|
||||
*/
|
||||
char name[] = "Trude"; // 6 bits on stack memory.
|
||||
name[0] = 'T'; // Elements of an array can be modified.
|
||||
/* Use char* when:
|
||||
- The maximum string length is NOT known.
|
||||
- The string will later be modified.
|
||||
- The string will be passed to a function [that modifies it].
|
||||
*/
|
||||
const char *name = "Trude"; // 8 bits in stack + 6 bits read-only.
|
||||
name = "TrudeEH"; // Pointers can be overwritten.
|
||||
name++; // rudeEH - Works because the pointer is shifted to the next value.
|
||||
peintf("%c\n", *(name+1)); // Prints 'r'.
|
||||
printf("%c\n", name[1]); // Works with both for reading.
|
||||
printf("%s\n", name); // Print a string.
|
||||
// The string in memory:
|
||||
// [T][r][u][d][e][\\0]
|
||||
// The memory address of T is stored.
|
||||
```
|
||||
|
||||
### String Operations
|
||||
|
||||
#### Compare String
|
||||
|
||||
```C
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
char s* = "Trude";
|
||||
char t* = "Trude";
|
||||
if (strcmp(s, t) == 0) {
|
||||
printf("Same string.");
|
||||
}
|
||||
```
|
||||
|
||||
#### Copy String (`malloc` example) Manually
|
||||
|
||||
```C
|
||||
#include <stdlib.h>
|
||||
char *s = "Trude";
|
||||
char *t = malloc(strlen(s) + 1);
|
||||
// 2 variables are declared, so strlen isn't called with every iteration.
|
||||
for (int i = 0, n = strlen(s) + 1; i < n; i++) {
|
||||
t[i] = s[i];
|
||||
)
|
||||
//...
|
||||
free(t);
|
||||
```
|
||||
|
||||
#### Copy String (string.h)
|
||||
|
||||
```C
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
char *s = "Trude";
|
||||
char *t = malloc(strlen(s) + 1);
|
||||
strcpy(t, s);
|
||||
//...
|
||||
free(t);
|
||||
```
|
||||
|
||||
Note: Use `valgrind` to detect memory leaks (lack of `free()`)
|
||||
|
||||
> **Always** initialize variables to a value, or random garbage values may be still in the variable's memory address.
|
||||
|
||||
### Input
|
||||
|
||||
#### Get Integer
|
||||
|
||||
```C
|
||||
#include <stdio.h>
|
||||
int main(void){
|
||||
int x;
|
||||
scanf("%i", &x);
|
||||
}
|
||||
```
|
||||
|
||||
#### Get String (Length is Known, safe)
|
||||
|
||||
`scanf` reads up to a whitespace.
|
||||
|
||||
```C
|
||||
#include <stdio.h>
|
||||
int main(void){
|
||||
char s[4];
|
||||
scanf("%4s", s); //No &, s is an address already.
|
||||
}
|
||||
```
|
||||
|
||||
`fgets` reads whitespaces.
|
||||
|
||||
```C
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
char name[25];
|
||||
fgets(name, 25, stdin); // name of variable, max size, input.
|
||||
name[strlen(name)-1] = '\0'; // removes the line break fgets adds. String library is required.
|
||||
```
|
||||
|
||||
## Files
|
||||
|
||||
### Write to a File
|
||||
|
||||
```C
|
||||
#include <stdio.h>
|
||||
int main() {
|
||||
FILE *file = fopen("test.txt", "w"); // w - overwrite / a - append
|
||||
fprintf(file, "Some Text");
|
||||
fclose(file);
|
||||
return 0;
|
||||
}
|
||||
```
|
||||
|
||||
### Delete a File
|
||||
|
||||
```C
|
||||
#include <stdio.h>
|
||||
int main() {
|
||||
if(remove("test.txt") == 0){
|
||||
printf("File removed.\n");
|
||||
} else {
|
||||
printf("Failed to delete file.\n");
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
```
|
||||
|
||||
### Read a File
|
||||
|
||||
```C
|
||||
#include <stdio.h>
|
||||
int main() {
|
||||
FILE *pF = fopen("test.txt", "r") // r - read.
|
||||
char buffer[255]; // Will hold 1 line of the file.
|
||||
if(pF == NULL){
|
||||
printf("File does not exist.");
|
||||
return 1;
|
||||
}
|
||||
fgets(buffer, 255, pF);
|
||||
printf("%s", buffer); // Print first line of file. Use in a while loop to print all of them.
|
||||
fclose(pF);
|
||||
return 0;
|
||||
}
|
||||
```
|
||||
|
||||
File manipulation accepts relative and absolute file paths.
|
||||
Reference in New Issue
Block a user