Now we can use string.h yay We go over user input. scanf reads ints and floats
int x;
float y;
printf("gimme int and float");
scanf("%d %f", x, y);
The memory model looks kinda like this: main 989 ⇒ x: int = Junk 990 ⇒ h: float = junk 991 ⇒ ret: int = junk scanf
- copies the addresses of the arguments passed (after the string literal of course) whatever data isn’t inputted will instead result in junk’
i.e. for the above example, had we only inputted 1 number, the other float will just be junk.
#define STR_LEN 300
print_str(char str[STR_LEN])
{
// Changing the str here will also change the array in main
printf("The string was: %s", str);
}
main()
{
char a_string[STR_LEN] = "Hello world!";
print_str(a_string);
}passing an array does not copy it; it just passes the address to where the array is.
problem
Argument in functions asking for the specific size of STR_LEN string is just a suggestion. C doesn’t enforce that kind of thing. equivalent to having the arg being:
char str[]char*#note WRONG. VERY WRONG.- String literals are 1 single pointer; 8 bytes. A parameter asking for a string of size 1024 is asking for a string of that size. Passing a string without the right size will be shoehorned afaik. This means you can pass a pointer into the 1024 param but it will throw a warning.
- Solution to prevent it: use empty brackets or
char*. Those are actually exclusive. - todo need to deal with this for real. I made a code example right below (this was not from the lecture; i made this. clearly with the bazingas.)
- Solution to prevent it: use empty brackets or
#include<stdio.h>
#include<string.h>
void bazinga(char* updated, char* string_literal)
{
strcpy(updated, string_literal);
}
void not_bazinga(char* updated, char string_array[1024])
{
strcpy(updated, string_array);
}
int main()
{
char test[1024];
char other[1024] = "hello";
// strcpy(test, other);
not_bazinga(test, "HIIHIHi"); // this works but gives a warning though.
// strcpy(test, "Hello");
printf("%s", test);
}take this example now:
void print_str(char str[])
{
printf("%s", str);
strcpy(str, "Bazinga bazinga bazinga lololololol");
}
int main()
{
char tiny_string[5] = "Hi!";
char big_string[300] = "This is a random string with no meaning whatsoever";
print_str(tiny_string);
printf("Tiny string is now: %s\n", tiny_string);
printf("Big string is now: %s\n", big_string);
}Observe how when tiny string copies bazinga bazinga etc., the size of tiny_string does not limit how far strcpy goes, and so it bleeds into our other reserved data (specifically big_string, since it’s right next to tiny_string in memory) and override the data. Had big_string not existed, it would probably cause a segfault.
He suggests passing the length of the string as another argument to implement safe guards (i.e. avoiding the messy situation like above.)
void print_str(char* str)
{
printf("%s\n");
}
int main(void)
{
char[10] str1 = "Hello!";
char[10] str1 = "BAzinGA!";
// These are equivalent.
print_str(&str1[0]);
print_str(str2); // This is the same as the above since the first entry of an array is also the start of the array.
}when using fgets() and you use a length that is smaller than the string, then it will only fill the suitable # of character (len-1 characters, cuz we need a spot for the delimiter). If you choose a length that’s too long, well you’ll get a segfault. easy peasy.
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<math.h>
void turn_back(double* b, int len)
{
double* max = b + len;
while (b < max)
{
*(b++) = *b * *b;
}
// for (int i = 0; i < len; i++)
// {
// *(b+i) *= *(b+i);
// }
}
int main(void)
{
double a[100];
for (int i = 0; i < 100; i++)
{
*(a+i) = sqrt((double) i);
}
printf("Before: \n");
for (int i = 0; i<100; i++) printf("%lf, ", *(a+i));
turn_back(a, 100);
printf("\nAfter: \n");
for (int i = 0; i<100; i++) printf("%d, ", (int) *(a+i) );
return 0;
}- The above makes a double array with each entry being the sqrt of the index
- and then we turn that back into the squared, regular index.
- cuz i’m crazy i used a while loop.
int* p, q
- THIS IS SO CRINGE ONLY P IS A POINTER.
- I recon the same happens with
int p, q[100]; only q is an array. #todo Go over this
Tutorial
This is probably quite important for tech interviews yeah “problem solving” yay.
- this is probably something i should practice it.
- I took a photo; should look thru ittodo.
So we have a string where all 4th words are swapped with 2nd words We accept a string via fgets. We go through and store each “word”, and then pass that “word” alongside its length into a function which then swaps it.
- The length and position of the start of the word is stored, probably outside the loop.
- To do this, we have a while loop and loop until we hit either a space, EoS delimeter, or punctuation. The “word” is just gonna be a pointer to the point in the string array where it occurs
in the case of don’t, we’d only switch o and t.
Okay here we go.
Edge cases to consider: Ress', don't, the,, etc.
Goal: to swap only the 2nd and 4th letters in each word larger than 4 or equal to characters.
We first get the string via fgets.
We use a while loop to go through the entire string until we hit a delimeter.
We get each individual “word”, separated by spaces and keep track of its size.
- the start of each word will be a pointer to the point in the string Once we hit a space, we pass the word and len of word into a function that swaps the two letters.
- The function has a while loop that indices each time a character is read.
- Once the index hits 2, it stores that as the position of the first letter
- Once the index hits 4, it stores that as the position of the second letter Then we just swap them.