510 likes | 526 Views
Learn about declaring and manipulating strings in C programming, including arrays of strings, pointers, string initialization, and user inputs. Explore memory usage, array dimensions, and string filling methods.
E N D
STRINGS STRINGS IN C FUNCTIONS DEALING WITH CHARACTERS FUNCTIONS DEALING WITH STRINGS
How to Declare a String? • 1. Need to have a name for the string • 2. Need to know the length of the string • 3. Actual memory space needed is length of the string + 1 • (to take care of the NULL character) • 4. Data type is char • Example: • char Str[20];
Arrays of strings • It is also possible to have arrays of strings. Since strings are themselves arrays, then we need to add a second size. • An array of strings is in fact an array with two dimensions, width (columns) and height (rows). • char list_cities[100][15]; will be able to contain 100 city names with a maximum of 14 letters per city. Why not 15?
Arrays of strings (cont.) • Example: An array containing the names of the months. • char months [12][10] = {“January”, “February”, “March”, “April”, “May”, “June”, “July”, “August”, “September”, “October”, “November”, “December”};
Arrays of strings (cont.) • Example: An array containing the names of the months. • char months [12][10] = {"January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"}; • Can you find the value of months[3]? • How about months [7][3]?
Using Pointers for String Manipulation • /* PROGRAM # 96 */ • /* DEMONSTRATES DISPLAYING STRING USING POINTER*/ • #include <stdio.h> • #define ssize 6 • main( ){ • char *ptr, str[ ] = "BIRDS"; • int i; • ptr = str; • printf("Our string is %s.\n", str); • /*Display character string contains, using pointer */ • puts(“Our string is made out of the following characters:”); • for(i=0; i<ssize; i++) • printf("%c ", *(ptr+i)); • puts(“Our string is made out of the following characters:”); • for(i=0; i<ssize; i++) • printf("%c ", str[i]); • }
Initializing Strings • Different ways: • char str1 [ ]="BIRDS"; • char str2 [6]="BIRDS"; • char str3[ ]={'B', 'I', 'R', 'D', 'S', ‘\0' }; • Manual initialization: • str1[0]='B'; • str1[1]='I'; • str1[2]='R'; • str1[3]='D'; • str1[4]='S'; • str1[5]='\0'; Necessary to indicate where string ends • Input by user [scanf, gets] • NOTE: • Length of str1, str2, str3 are 5. NULL character does NOT count as part of string's length.
Getting a string from the user • /* PROGRAM # 97 */ • /* USE OF SCANF( ) TO READ STRINGS FROM USER */ • #include<stdio.h> • main( ){ • /*Declare a character array to hold input */ • char str1[20]; • printf("Enter a string: "); • /*Read the string inputted*/ • scanf("%s", str1); • printf(“You just entered this string: %s”, str1); • }
Filling a string • We have already seen how to fill a string by initializing it in a declarative statement. Now how to do it in an executable statement. • To fill a string from standard input (scanf) or file (fscanf), we use a special placeholder for strings %s. • scanf ("%s", city); (Notice the absence of &. It is not necessary here since city is already an address, the same as &city[0], remember?)
Filling a string • There is one problem with the %s placeholder when used with scanf (or fscanf). It considers the space as a delimiter. Therefore, if for a city name you enter Los Angeles, you will get only Los stored in the string. • The solution is to use a function named gets (or fgets if you read from a file). That function only considers the new line character as the delimiter, not the space. Instead of scanf ("%s", city); you use gets (city); instead of fscanf (in, "%s", city); you use fgets(city, size, in);
Printing a string • The space problem does not occur with printf. If the city is "Los Angeles" then a printf ("%s", city); will print out the entire city name. • The puts function can also be used as an alternative to printf but its use is less necessary than the gets function.
Q? Ask the user to enter two different capital cities for two countries.
Q? • /* Reading a string with scanf */ • #include <stdio.h> • #include <string.h> • int • main (void) • { • char city[20], city2[20]; • printf ("What is the capital of Canada? "); • /* the string is read with the %s placeholder */ • /* do not use & or use &city[0] */ • scanf ("%s", city); • printf ("What is the capital of Russia? "); • scanf ("%s", city2); • /* here is the report */ • printf ("\nThe capital of Canada is: %s.", city); • printf ("\nThe capital of Russia is: %s.", city2); • return (0); • }
Note!!! • 1. Size of the string MUST be indicated since we only declare the string • 2.The absence of & in scanf should be noted • (The string name represents the Starting address of the string)
Getting Strings Using gets( ) Function - <stdio.h> • /* PROGRAM # 98*/ • /* USE OF SCANF( ) TO READ STRINGS FROM USER */ • #include<stdio.h> • main(){ • char str1[20]; • puts("Please enter this string\”West By NorthWest!\”: "); • scanf("%s", str1); • printf(“You just entered this string: %s”, str1); • }
Explanation: • scanf( ) sees the blank character between 3 words, only gets the first word. • Solution: • Use gets( ) function
/* USE OF GETS( ) TO READ STRINGS FROM USER */ • /* PROGRAM # 99 */ • #include<stdio.h> • main(){ • char str1[20]; • printf("Enter a string: "); • gets(str1); • printf(“You just entered this string: %s”, str1); • } • After execution: • Enter a string: North by NorthWest! • You just entered this string: North by NorthWest!
The gets controversy • Many experienced programmers will argue that gets is a dangerous function because you have to check manually that you don't run outside the array limits. For example, if you declare a string as char x[10];, use gets (x) and enter a sentence of 100 characters, it will accept it and write the extra characters into memory cells outside the array declaration paving the way for access violation and crashes. • A safer way would be to use fgets all the time (use stdin as the file variable for keyboard input). Ex: fgets (x, sizeof(x), stdin); or fgets (x,10,stdin); • Note that by using a size larger than the actual input string, a newline character will be part of the string. That does not happen with gets or scanf.
/* Reading a string from a file */ • #include <stdio.h> • #include <string.h> • int • main (void) • { • char sentence[200]; • FILE *input; • /* file is opened */ • input = fopen("phrase.txt", "r"); • /* the string is read from the file */ • fgets (sentence, sizeof(sentence), input); • /* sentence is echoed on the screen */ • /* \" to display a " (double quotes) */ • printf ("The sentence is:\n\"%s\"\n\n\n", sentence); • /* file is closed */ • fclose (input); • return (0); • }
Functions Dealing With Strings Defined in <string.h> header • Finding the length of a string [strlen] • Copying a string to another one [strcpy]
strcpy • strcpy: the function to transfer a string into a variable. Equivalent to the assignation operator. • With strings you cannot do city="Toronto"; in an executable statement. To do an assignment we use strcpy. • char city[10], city2[10]; • strcpy (city, "Toronto"); • /* places “Toronto” into city /* • strcpy (city2, city); • /* places “Toronto” into city2 /* city
Copying A String to Another One • Copying A String to Another One • Strcpy(String1, string2) • Copies String2 into String1 • /* PROGRAM # 106 */ • /* USE OF STRCPY - STRNCPY*/ • #include <stdio.h> • #include <string.h> • main( ){ • /* Declare character arrays */ • char S1[100], S2[100]; • char S3[100]=”These two strings will have to be the same!”; • /* Copy S3 into S1 */ • strcpy(S1, S3); • printf(“This is the 1st string \”%s\”.\n”, S1); • printf(“This is the 2nd string \”%s\”.\n”, S3); • puts(“”); • /* Copy the S3 into S2 */ • strcpy(S2, S3); • printf(“This is the 1st string \”%s\”.\n”, S2); • printf(“This is the 2nd string \”%s\”.\n”, S3); • }
Copying A String to Another One • /* OUR VERSION OF STRCPY */ • … • … • for(i=0; i<strlen(S2); i++) • S1[i]=S2[i]; • S1[i]=NULL; • … • … • OR • … • … • i=0; • while( S2[i] != ‘\0’) • S1[i]=S2[i]; • i++; • } • S1[i]=NULL; • … • …
Finding the Length of the String • The following are string functions • strlen(string) • returns an integer as the length of a string. • Note!!!: NULL character not counted. • strlen: the strlen function returns the length of the string not counting the null character. • char city[10]; • strcpy (city, “Toronto”); • /* places “Toronto” into city */ • printf (“%d”, strlen (city)); • /* displays 7 on the screen */
/* USE OF STRLEN */ • /* PROGRAM # 105 */ • /* USE OF STRLEN */ • #include <stdio.h> • #include <string.h> • main( ){ • char Str[ ] = "I wonder how strlen function works?!"; • int Slen; • /* Call the function strlen( ), to assign the length of the string */ • Slen=strlen(Str); • printf( "Your string is %s and it has %d characters.", Str ,Slen); • } • /* Our version of STRLEN */ • … • i=0; • while( Str[i] != ‘\0’) • i++; • …
String function: strcpy There are many useful functions to manipulate strings in the string library (need #include <string.h>). strcpy: the function to transfer a string into a variable. Equivalent to the assignation operator. With strings you cannot do city="Toronto"; in an executable statement. To do an assignment operation we must use strcpy. char city[10], city2[10]; strcpy (city, "Toronto"); /* places "Toronto" into city /* strcpy (city2, city); /* places "Toronto" into city2 /* 0 1 2 3 4 5 6 7 8 9 'T' 'o' 'r' 'o' 'n' 't' 'o' '\0' ? ? city2
String function: strlen • strlen: the strlen function returns the length of the string not counting the null character. char city[10]; strcpy (city, "Toronto"); /* places "Toronto" into city */ printf ("%d", strlen (city)); /* displays 7 on the screen */
Having an array as a “result” • An array can never be a result as it represents multiple values. As with function with multiple “results”, we will have to use pointers. void addarrays (constint a[], const int b[], int c[], int size) { int i; for (i=0; i<size; ++i) c[i] = a[i] + b[i]; } • The const option means that the specified array cannot be modified by the function.
Dynamic allocation of arrays • Arrays, as we know them now, can only be of a fixed size. • int x[100]; declares an array size 100, no less no more. • It is illegal to do the following. Do you know why? • printf ("Enter the size of the array: "); • scanf ("%d", &size); • int x[size];
C’s Dynamic allocation functions • Pointers provide necessary support for C’s dynamic allocation system. Dynamic allocation is the means by which a program can obtain memory while it is running. memory allocated by C’s dynamic allocation functions is obtained from the heap. the heap is free memory that is not used by your program, the operating system, or any other program running in the computer. The size of the heap cannot usually be known in advance, but it typically contains a fairly large amount of free memory.The core of C’s allocation system consist of the functions: • (Memory allocation) malloc () allocates memory • free() realease memory • (contiguous allocation) calloc() allocate memory
Heap memory • It is impossible to have arrays of varying sizes because that makes programming inefficient. C is very strict with arrays but it is also the most efficient of all the high-level languages. • There is a way to have dynamic allocation in C. The solution is to use “heap” memory instead of the usual memory we have been using so far. • Heap memory: slower, less-structured,dynamic memory. • The heap is a region of free memory that your program can use via C’s dynamic memory allocation functions.
DYNAMIC ARRAYS • IDEA: Create an array at run time • Declare a pointer by using either • calloc( ) [void *calloc( arg1, arg2)] • arg1: # of elements in an array, • arg2: bytes needed for one element • (both functions are part of <stdlib.h>)
Note!!! • The calloc() function returns a pointer to the first byte of the allocated region.
<stdlib.h> • void *calloc(size_var1, size_var2) • Returns a pointer that points to a top of the array whose number of elements is the first argument and the size of each element is the second argument. All elements are initialized to zero. • calloc() allocate memory the size of which is equal to num*size. allocate sufficient memory for an array of num objects of size. All bits in the allocated memory are initially set to zero. • Void free(void *var) • Free a memory block whose starting address is the argument. This block should have been previously allocated by calloc.
Using a dynamic array • int size; • /* 1. declare a pointer to the array */ • double *array; • printf (“Enter the size of the array: “); • scanf ("%d", &size); • /* 2. allocate the array in the heap */ • array = (double *) calloc (size, sizeof(double)); • /* 3. use the array normally */ • ... • /* 4. free the heap memory */ • free (array);
Dynamic allocation of arrays • Arrays, as we know them now, can only be of a fixed size. int x[100]; declares an array size 100, no less no more. • It is illegal to do the following. Do you know why? printf ("Enter the size of the array: "); scanf ("%d", &size); int x[size];
Dynamic Allocation of Arrays • It is impossible to have arrays of varying sizes because that makes programming inefficient. C is very strict with arrays but it is also the most efficient of all the high-level languages. • There is a way to have dynamic allocation in C. The solution is to use “heap” memory instead of the usual memory we have been using so far. • Heap memory: slower, less-structured, dynamic memory.
Using a dynamic array int size; /* 1. declare a pointer to the array */ double *array; printf ("Enter the size of the array: "); scanf ("%d", &size); /* 2. allocate the array in the heap */ array = (double *) calloc (size, sizeof(double)); /* 3. use the array normally */ ... /* 4. free the heap memory */ free (array); See the complete program at c.ihypress.ca/07.php (program #9)
USE OF CALLOC( ) • Same thing can be achieved using another standard memory function, i.e., calloc( ): • … • int *arr; • arr = (int *) calloc ( array_size, sizeof(int) ); • … • NOTE: • If the requested space is not available, it returns NULL.
/* A dynamically-allocated 1-D array */ • #include <stdio.h> • #include <stdlib.h> • int • main (void) • { • double *x; /* declare a pointer only */ • int i, size; • /* ask user for size of array */ • printf ("How large do you want your array? "); • scanf ("%d", &size); • /* allocate the array in the heap */ • x = (double *) calloc (size, sizeof(double)); • /* printing the array for verification • surprise! a dynamic array is • automatically initialized with zeros! */ • for (i = 0; i < size; ++i) • printf ("%.1f ", x[i]); • /* freeing the memory allocation */ • free (x); • return (0); • }
DYNAMIC MEMORY ALLOCATION – HOMEWORK!!! • WRITE A C PROGRAM THAT • ASK THE USER FOR THE SIZE OF AN INT ARRAY • DYNAMICALLY CREATE THE ARRAY • GET VALUES FOR THE ARRAY • CALCULATES THE MINIMUM, MAXIMUM • CALCULATES THE AVERAGE • PRINT THE RESULTS
Q?HOMEWORK!!! • Write a program to create an array of integers (LIST) dynamically. User provides the size of the array.
Passing Strings between Functions • Same way that we used arrays as function arguments • /* PROGRAM # 100 */ • /*GETS STRING FROM THE USER, RETURN THE STRING*/ • #include <stdio.h> • void GetName(char str[ ]); • void PrintName(char str[ ]); • main( ){ • /* declare a character array to hold input */ • char name[20]; • /*Call functions to input the character from • the user and display it */ • GetName(name); • PrintName(name); • } • /* To get the string */ • void GetName(char str[ ]){ • printf("What is your name (max 20): "); • gets(str); • } • /* To print string */ • void PrintName(char str[ ]){ • printf("Your name is %s.", str); • }
Passing a string to a function • Passing a string to a function is the same thing as passing an array of numerals. • We pass only the pointer to its first cell. • On the next slide is a function that takes in a string and counts the number of vowels (a,e,i,o,u) in it. • Notice that contrary to numerical arrays, we don't need to pass the size because for strings it is easy to determine its size from inside the function (which is not possible for arrays of numerals).
Passing a string to a function • int • count_vowels (char string[]) • { • int nv=0, i; • for (i=0; i<strlen(string); ++i) • if (string[i]=='a'||string[i]=='e'|| • string[i]=='i'||string[i]=='o'|| • string[i]=='u') • nv = nv + 1; • return (nv); • }
Passing a string to a function • The main program would look like this: • int main (void) • { • char s[100]; • int vowels; • printf ("Enter a sentence: "); • gets (s); • vowels = count_vowels (s); • printf ("The sentence contains %d vowels.\n", vowels); • return (0); • }
2D Array Applications • 1D arrays can be viewed as VECTORS. • Similarly, 2D arrays can be viewed as MATRICES. • As such, when we are dealing with 2D arrays we really trying to manipulate Matrices including: • Matrix addition • Matrix subtraction • Matrix multiplication • Matrix transposition • Matrix inversion • Solving for systems of linear equations • Linear transformations
Regualr Array – Example • Write a program that gets a vector from the user. Assume that the elements of the vector are float and the max size of the vector is 3.
/* PROGRAM # 900 */ • #include<stdio.h> • void GetVector(float A[3]); • void PrintVector(float A[3]); • main( ){ • float Vector[3]; • GetVector(Vector); • PrintVector(Vector); • } • /* To input a Vector with max size 3 from the user*/ • void GetVector(float A[3]){ • int i; • for(i=0; i<3; i++){ • printf("Please enter A[%d]", i); • scanf("%f", &A[i]); • } • } • /* To display the 3 Vector */ • void PrintVector(float A[3]){ • int i; • for(i=0; i<3; i++){ • printf("%5.2f", A[i]); • printf("\n"); • } • }