Strings in C

C doesn’t have a string data type per se; instead, C uses an array of char elements to store a string.

A string constant is a set of characters placed between a pair of double quotes. Anything between double quotes is taken by the compiler to be a string.

#include <stdio.h>

int main(void){
    
    printf("This is a string. ");
    //newline character
    printf("As is this. \nBut this is on the second line.");
    //tab character
    printf("\nAnd this is \t on the \t third.");
    
    return 0;
    
}

Strings stored in memory end with the null character, . As strings in C are always terminated by a null character, the length of a string is always the number of characters, plus one. Strings are stored in arrays of type char.

Remember,the size of the char array must be large enough to hold the string of characters, plus one. We can also leave the array’s brackets empty and initialize the char array with the desired string, to have the size automatically set.

 #include <stdio.h>

int main(void){
    
    int i = 0;
    char strA[] = "I propose to move immediately upon your works.";
    
    while(true){
        //check if we have reached the null
        //termination characater
        if(strA[i] == ''){
            break;
        } else {
            //output the character
            //and increment the counter
            printf("%c ", strA[i++]);
        }
    }
    
    return 0;
    
}

The %s specification is used to output a null-terminated string. At wherever the %s appears in the format string argument, an output function will output successive characters from the char array until it hits the character.

#include <stdio.h>

int main(void){
    
    char str01[28] = "Nice boat!";
    char str02[128] = "It is better to die for the Emperor than live for yourself!";
    char str03[] = "My lab members are my allies, and the World is my enemy!";
    
    printf("String #1: %s\n", str01);
    printf("String #2: %s\n", str02);
    printf("String #3: %s\n", str03);
    
    
    return 0;
    
}

The main drawback to using mutable char arrays to hold a variety of strings is that you must make the char array long enough to hold the longest string that is expected. As arrays are, by definition, fixed length, we will probably end up wasting storage space much of the time.

Joining one string to the end of another is a often required; this is called appending a string.

#include <stdio.h>

int main(void){
    
    char strA[] = "Shaka, when the walls fell.";
    char strB[] = "Mirab, with sails unfurled.";
    int i, j;
    int length = sizeof(strA) + sizeof(strB);
    
    char strC[length];
      
    //copy first string
    i = 0;
    while(strA[i]!=''){
        strC[i] = strA[i];
        i++;
    }
    
    //insert a space 
    //to go between the two strings.
    strC[i] = ' '; 
    //copy second string
    j = i + 1;
    i = 0;
    while(strB[i]!=''){
      strC[j++] = strB[i++];
    }
    
    strC[j] = '';
    
    printf("strA = %s\n", strA);
    printf("strB = %s\n", strB);
    printf("strC = %s\n", strC);
    
    return 0;
    
}

The sizeof() operator returns the number of bytes in the string, including the byte allocated to store the character. This gives us some padding – we can replace the character in the first string to a blank space character before we append the second string to it within the new string.

In the real world, however, we would want to use the strlen() function rather than sizeof(). Unlike sizeof(), the strlen() function does not count the null termination character in the string.

Why should we use strlen(), then? Well, for one reason, we ought to recall here that a string in C is nothing more than a char array, and when we pass an array to a function, it is passed by reference, which in the C context means that the called function has a copy of a pointer to the array, and not the array itself. This means that if we use the sizeof() operator on a string parameter, we will get back the size of a pointer on our system, and not the number of bytes stored in the string!

#include <stdio.h>
#include <string.h>
#include <malloc.h>

//function returns a pointer to a char
//array
char * appendStr(char *strA, char *strB){
    int i, j;
    
    //sizeof wouldn't work here
    printf("Size of stringA[] in function: %d\n", sizeof(strA));
    printf("whereas strlen(stringA) gives us: %d\n", strlen(strA));
    
    //---let's us pointer arithmetic for fun
    char * returnChar = (char *)malloc(strlen(strA) + strlen(strB) + 2);

    i = 0;
    
    while(*(strA + i) != ''){
        *(returnChar + i) = *(strA + i);
        i++;
    }
    //put a space between the two
    *(returnChar + i) = ' ';
    
    //now  let's copy over the second string
    //we can used array index notation as well
    j = ++i;
    i = 0;
    
    while(strB[i]!=''){
        returnChar[j++] = strB[i++];
    }
    
    returnChar[j] = '';
   
    //since we are returning a value 
    //allocated on the heap
    //we will have to call free() in the calling function
    return returnChar;
    
} // end function --------------------


int main(void){
    
    char stringA[] = "Hi.";
    char stringB[] = "Nice boat!";
    char *buffer;
    
    printf("sizeof(stringA) = %d\n", sizeof(stringA));
    printf("strlen(stringA) = %d\n", strlen(stringA));
    
    //don't forget that an array name devolves to a pointer
    //when passed as an argument to a function
    buffer = appendStr(stringA, stringB);
    
    printf("\n%s\n", buffer);
    
    //don't forget to clean up!
    free(buffer);
    
    return 0;
    
}

Note that the strlen() function is declared in the string.h header file.

We can use a two-dimensional array of type char to store strings, where each row is used to hold a separate string. Thus, in a char array stringsArray[i][j], at any given point the i index will indicate which string we are using, and the j index will indicate which character in that string we are at.

#include <stdio.h>
#include <string.h>

int main(void){
    
 
    char stringArray[3][56] = {
                    "Valar morghulis",
                    "Don't Panic",
                    "Photons be free!"};
    
    char stringArrayTwo[][128] = {
                    "Nilbog is Goblin Spelled Backwards!",
                    "The morning sun has vanquished the horrible night.",
                    "You are technically correct -- the best kind of correct."
    };
    
    printf("%s ", stringArray[0]);
    printf("...starts with: %c\n", stringArray[0][0]);
    
    printf("%s ", stringArrayTwo[1]);
    printf("...starts with: %c\n", stringArrayTwo[1][0]);
    
    return 0;
    
}

Note that when initializing an array of strings, we can omit the first value when initializing the string array, so that the compiler deduces for us the number of strings we are declaring.

I wrote a book on C, check it out: http://www.amazon.com/Big-Als-C-Standard-ebook/dp/B00A4JGE0M/

Sorting and Processing Strings in C

An array of strings is stored in memory as a two dimensional array of characters. For our first program, we will create a two dimensional array of five words with each word containing up to ten characters.

#include <stdio.h>
#include <string.h>

int main(void){

    int i, j;

    char swapstring[10];

    char strings[5][10] = {
            {'T','e','l','e','b','i','t'},
            {'A','t','a','r','i'},
            {'M','e','m','o','t','e','c','h'},
            {'V','i','s','i','c','o','r','p'},
            {'B','o','m','i','s'},
        }; // end strings[][]   


    printf("The original list is: \n");
    for(i = 0; i < 5; i++){
        printf("%s\n", strings[i]);
    }
    printf("\n");

    //use bubble sort
    for(j = 0; j < 4; j++){
        for(i = j + 1; i < 5; i++){
            //strcmp() returns a number greater than zero
            //if the second string is less than the first
            if(strcmp(strings[j], strings[i]) > 0){
                strcpy(swapstring, strings[j]);
                strcpy(strings[j], strings[i]);
                strcpy(strings[i], swapstring);
            }
        }
    }

    printf("The sorted list is: \n");
    for(i = 0; i < 5; i++){
        printf("%s\n", strings[i]);
    }

    return 0;


}

In our first program we used bubble sort to sort the list of strings. A bubble sort is a nested loop that performs n-1 passes over a list of n number of items, swapping an item with the next item in the list if it is greater than the next item. Bubble sort is very simple, and also very inefficient.

In our next program, we will use selection sort to sort the strings. Selection sort’s main value over bubble sort is that it should in general perform less swaps; although, it is still not a very efficient sorting routine. Selection sort, like bubble sort, has an inner and outer loop. The outer loop moves from the start of the array to the penultimate element. At each increment of the outer loop, the inner loop sets the potential minimum value to whatever the current index is in the outer loop. The inner loop then compares this theoretical minimum value with every element after it; if the loop finds a value that is less than the theoretical minimum, it resets the the theoretical minimum to the index of that element. Finally, when the inner loop has been completed, it then and only then swaps out the current element in the outer loop with the element that the inner loop found to be the smallest.

 

#include <stdio.h>
#include <string.h>


int main(void){

    char swapstring[10];

    int j,k, minimum;

    char strings[5][10]= {
        "Malthus",
        "Smith",
        "Volaire",
        "Hobbes",
        "Hume"
    };

    printf("The original list is: \n");
    for(j = 0; j < 5; j++){
        printf("%s\n", strings[j]);
    }


    for(j = 0; j < 4; j++){
        //set index of smallest element
        minimum = j;
        for(k = j + 1;  k < 5; k++){
            //if result is negative
            //strings[k] is less than strings[minimum]
            if(strcmp(strings[k], strings[minimum]) < 0){
                //elemet at index k is new minimum
                minimum = k;
            }

        } //end innner for loop
       
        //swap
        strcpy(swapstring, strings[j]);
        strcpy(strings[j], strings[minimum]);
        strcpy(strings[minimum], swapstring);

    } // end outer for loop

    printf("The sorted list is: \n");
    for(j = 0; j < 5; j++){
        printf("%s\n", strings[j]);
    }

    return 0;
}

Our next program counts the number of vowels in a string using a simple switch statement.

#include <stdio.h>

#define LENGTH 50


int GetVowelCount(char *s);

int main(void)
{

    char string1[LENGTH] = "WelcoMe to ThE jUnGLe, we'VE got fuN aNd GAmes.";
    char string2[LENGTH] = "hE's THE One thEy call dR. FeELgoOd.";

    int i = 0;
   

    printf("Vowel count for %s: ", string1);
    printf("%d\n", GetVowelCount(string1));

    printf("Vowel count for %s: ", string2);
    printf("%d\n", GetVowelCount(string2));

    return 0;
}

int GetVowelCount(char *s){
    int i = 0, j = 0;

    while(*(s+i)!=''){
        switch(*(s+i)){
            case 'A':
            case 'a':
                j++;
                break;
            case 'E':
            case 'e':
                j++;
                break;
            case 'I':
            case 'i':
                j++;
                break;
            case 'O':
            case 'o':
                j++;
                break;
            case 'U':
            case 'u':
                j++;
                break;   
        }
        i++;
    }

    return j;
}

Our final program is a simple one as well; it is the classic palindrome checker. A palindrome is a word that reads the same forwards and backwards.

#include <stdio.h>
#include <string.h>

int CheckForPalindrome(char *s);

int main(void){

    char *s[5] =
    {
        “radar”,
        “robot”,
        “kayak”,
        “jazz”,
        “civic”,
    };

    for(int i = 0; i < 5; i++){
        printf(“%s\t”, *(s+i));
        if(CheckForPalindrome(*(s+i))>0){
            printf(“is a palindrome.\n”);
        } else {
            printf(“is not a palindrome.\n”);
        }
    }

    return 0;
}

//returns -1 if it finds two characters that do not match
//returns 1 otherwise
int CheckForPalindrome(char *s)
{
    int L = 0;
    //remember, index starts at 0
    //hence, minus 1
    int R = strlen(s) – 1;

    while(L < R){
        if(*(s+L)!=*(s+R)){
            return -1;
        }
        L++;
        R–;
    }

    return 1;
}

If you would like to learn more about C, take a look at my book at http://www.amazon.com/Big-Als-C-Standard-ebook/dp/B00A4JGE0M/

 

 

 

 

 

String Functions in

The strcat() function joins two strings together by overwriting the null character in the first string parameter with the second string, which retains its null terminating character. One conclusion we can draw from this operation is that we must be sure that the first string has a large enough space in memory to contain both strings, as there is no bound checking.

#include <stdio.h>
#include <string.h>

int main(void){
    
    char string1[200] = "Making assumptions is part of any investigation.";
    char *string2 = " If we're wrong, all it'll cost is an apology.";
    
    //strcat returns the first string
    printf("%s", strcat(string1, string2));
            
    //first string remains changed
    printf("\n%s\n", string1);
    
    return 0;
    
}

Our next program will append the second string read from stdin to the first, and then output the string to stdout.

#include <stdio.h>
#include <string.h>

#define BUFFER_SIZE 200

int main(void){
    
    char string1[BUFFER_SIZE];
    char string2[BUFFER_SIZE];
    
    printf("Please enter a string:\t");
    
    //standard input (stdin)
    //is treated as a file
    fgets(string1, BUFFER_SIZE, stdin);
    
    printf("Please enter another string:\t");
    
    fgets(string2, BUFFER_SIZE, stdin);

    //note how fgets includes the trailing newline
    //in the strings
    printf("\n%s\n", strcat(string1, string2));
    
    
    return 0;
    
}

The strchr() function returns a pointer to the first occurrence of a byte in a string provided to it. If no match is found, a null pointer is returned.

#include <stdio.h>
#include <string.h>

int main(void){
    
    char *string1 = "The morning sun has vanquished the horrible night";
    char string2[100] = "What a terrible night for a curse.";
    
    char *string3 = strchr(string1, 'v');
    char *string4 = strchr(string2, ' ');
    
    printf("\n%s\n", string3);
    printf("\n%s\n", string4);
    
    return 0;
    
}

The strcmp() function compares two strings and returns an integer based on the outcome. A value less than zero is returned if the first string parameter is less than the second string parameter. A value of zero is returned if the two strings are equal to each other. Finally, a value of greater than zero is returned if the first string is greater than the second string.

#include <stdio.h>
#include <string.h>

#define BUFFER_SIZE 200

int main(void){
    
    char string1[BUFFER_SIZE] = "Three pounds of flax";
    char string2[BUFFER_SIZE] = "Three pounds of flax";
    char string3[BUFFER_SIZE] = "three pounds of flax";
    
    if(strcmp(string1, string3)){
        printf("<%s> and <%s> are not the same\n", string1, string3);
    }
    
    if((strcmp(string1, string2))==0){
        printf("<%s> and <%s> are the same\n", string1, string2);
    }
    
    //result might seem counterintuitive
    if((strcmp(string1, string3))<0){
        printf("<%s> is less than <%s>\n", string1, string3);
    } else if((strcmp(string1, string3))>0){
        printf("<%s> is greater than <%s>\n", string1, string3);
    } else {
        printf("<%s> and <%s> are equal\n", string1, string3);
    }
    
    return 0;
    
}

The strcpy() function copies the contents of the second string parameter into the first.

It bears mentioning here than in certain situations that call for a pointer, an array name devolves to a pointer to its first element. Remember, a string is a char array with a standardized sentinel, in this case the null character, defining its boundary.

#include <stdio.h>
#include <string.h>

#define BUFFER_SIZE 200

int main(void){
    
    char string1[BUFFER_SIZE];
    char string2[BUFFER_SIZE] = "Han shot first.";
    char string3[BUFFER_SIZE] = "No one knows what he can do till he tries.";
    
    strcpy(string1, string2);
    
    printf("\n%s\n", string1);
    
    printf("\n%s\n", strcpy(string2, string3));
    
    char *string4 = strcpy(string3, string1);
    
    printf("\n%s\n", string4);
    
    return 0;
    
}

Don’t forget that there are no standard operators for assigning and comparing strings. To assign a string value to another string, we must use strcpy(). To compare a string, we must use strcmp().

The strlen() function returns the length as an unsigned long integer of the null-terminated string pointed to by the function’s sole parameter. Note that the null terminator itself is not counted.

#include <stdio.h>
#include <string.h>

#define BUFFER_SIZE 200

int main(void){
    
    char *str1 = "Don't Panic";
    
    printf("The length of the string: %lu\n", strlen("You rush a Miracle Man, you get rotten miracles"));
    
    printf("The length of %s is %lu", str1, strlen(str1));
    
    return 0;
}

The strncat() function joins a two strings together, with the second string parameter being limited in length by a certain number of characters specified in the third and final function parameter, which is an integer number.

#include <stdio.h>
#include <string.h>

#define BUFFER_SIZE 30
#define LARGER_BUFFER_SIZE 60

int main(void){
    
    char string1[BUFFER_SIZE]="";
    char string2[LARGER_BUFFER_SIZE] = "As Thucydides has said, ";
    char *string3 = "The secret of happiness is freedom. The secret of freedom is courage.";
    
    strncat(string1, string3, BUFFER_SIZE);
    
    printf("\n%s\n", string1);
    
    //remember, strncat and strcat append second string
    //to the end of the first
    strncat(string2, string3, LARGER_BUFFER_SIZE - strlen(string2));
    
    printf("\n%s\n", string2);
    
    return 0;
}

If you’re interested in learning more about the C language, please buy a copy of my book at http://www.amazon.com/Big-Als-C-Standard-ebook/dp/B00A4JGE0M

 

 

Arrays and Strings in C

An array is an indexed list of variables of the same type that are referred to by a shared name. A specific variable in the array is accessed via its index number. In C, all arrays consist of contiguous memory locations, which means that we can also access array elements via pointer arithmetic. The lowest address stores the first array element, and the highest address stores the last element. Suffice to say, arrays and pointers are closely related.

One common type of array is the string, which is a char array terminated by the null character.

As with other variables, arrays must be declared so that the compiler can allocate space for them in memory.

#include <stdio.h>

int main(void){
    
    
    //declare double type array
    double bubble[10];
    
    //declare int type array
    int intArray[50];
    
    bubble[0] = 7.976;
    bubble[1] = 2.352;
    
    printf("bubble[0] = %f\n", bubble[0]);
    printf("bubble[1] = %f\n", bubble[1]);
    
    return 0;
    
}

As we have seen, an element is accessed by indexing the array name, which is done by placing the number of the element’s location in the array within square brackets after the name of the array. Note that in C, all arrays have 0 as the index of their first element.

#include <stdio.h>

int main(void){
    
    int ints[50];
    
    int i;
    
    //assign values to
    //every element in ints array
    for(i = 0; i < 50; i++){
        ints[i]=i+1;
    }
    
    //display contents of array
    for(i=0; i < 50; i++){
        printf("%d\t", ints[i]);
    }
    
    putchar('\n');
    
    return 0;
    
}

Note that C has no bounds checking on arrays.

The amount of memory required to hold an array is directly related to its type and size. For a single-dimension array, the total size in bytes is the length of the array multiplied by the size of the base type of the array.

We can create a pointer to the first element in an array by specifying the array name without any sort of index.

#include <stdio.h>

int main(void){
    
    int i = 0;
    int *ptr;
    int sample[25];
    
    ptr = sample;
    
    sample[0] = 1;
    for(i = 1; i < 25; i++){
        sample[i] = i + sample[i-1];
    }
    
    i = 0;
    
    //use pointer arithmetic
    //to access array elements
    while(i++ < 25){
        printf("%d\n", *ptr++);
    }
    
    return 0;
}

We cannot pass an entire array as an argument to a function. We can, however, pass a pointer to an array by specifying the array’s name without an index. We can declare the array as a function parameter in three different ways: as a pointer, as a  sized array, or as an unsized array.

#include <stdio.h>
#define SIZE 50

//two void functions
//one to assign values
//one to print values
void assignValues(double array[SIZE]);
void printValues(double *arrayPtr);

//one void function to modify values
void modifyValues(double array[]);

int main(void){
    
    double trouble[SIZE];
          
    assignValues(trouble);
    
    printValues(trouble);
    
    printf("\nafter modifying values in array...\n");
                
    modifyValues(trouble);
    
    printValues(trouble);
    
    return 0;
    
}

void assignValues(double array[SIZE]){
    
    int i;
    double var = 0.0;
    
    for(i = 0; i < SIZE; i++){
            var = i / 1000.0;
            array[i] = (i-(SIZE/2)) + var;
        }
}

void printValues(double *arrayPtr){
    int i = 0;
    while(i < SIZE){
        printf("%.8f\n", *(arrayPtr + i));
        i++;
    }
}

void modifyValues(double array[]){
    int i;
    for(i = 0; i < SIZE; i++){
        array[i] = array[i] / (i+1) + i;
    }
}

One dimensional arrays are often used as strings. A string is a null-terminated character array. Note that when declaring a character array that will hold a string, we must declare it to be one character longer than the largest string that it will hold.

#include <stdio.h>


int main(void){
    
    int i;
    char lowerCase[27];
    char upperCase[27];
    
    lowerCase[0] = 'a';
    upperCase[0] = 'A';
    
    for(i = 1; i < 26; i++){
        lowerCase[i] =  lowerCase[0] + i;
        upperCase[i] = upperCase[i-1] + 1;
    }
    
    //assign null terminator
    //to ends of the string
    lowerCase[26] = '';
    upperCase[26] = '';
    
    //print strings using
    // %s conversion specifier
    printf("Lower Case Letters: %s\n", lowerCase);
    printf("Upper Case Letters: %s\n", upperCase);
    
    
    return 0;
}

We can use the fgets() function to acquire a string from standard input. The fgets() function takes three arguments: the char array, the size of the char array, and where to get the input from. Since we will be taking the input from the user, we will specify stdin as the source of input.

#include <stdio.h>

int main(void){
    
    const int buffer = 256;
    
    char string1[buffer];
    char string2[buffer];
    
    printf("Enter a string: ");
    
    fgets(string1, buffer, stdin);
    
    printf("Enter another string: ");
    
    fgets(string2, buffer, stdin);
    
    printf("%s", string1);
    
    printf("%s", string2);

    return 0;
    
}

Interested in learning more?

Take a look at this book on C: http://www.amazon.com/Big-Als-C-Standard-ebook/dp/B00A4JGE0M/

Char Functions in C

The C Standard Library has a useful set of functions for handling characters and strings. The string functions require the header <string.h> and the character functions require the header <ctype.h>.

Character functions automatically convert their arguments to the unsigned char type.

The isalnum() function returns nonzero if its argument is either a letter of the alphabet or a digit.

#include <ctype.h>
#include <stdio.h>

int main(void){
    
    char ch;
    
    while(1){
        printf("Enter a character or enter ! to quit:\t");
        ch = getchar();
        if(ch=='!'){
            break;
        }
        
        //use isalnum() function
        if(isalnum(ch)){
            printf("%c is alphanumeric\n", ch);
        } else {
            printf("%c is not alphanumeric\n", ch);
        }
        
        //flush standard input
        while((ch = getchar())!='\n'){}
    }
    
    return 0;
    
}

The isalpha() function returns nonzero if the char value is a letter of the alphabet; otherwise zero is returned.

#include <ctype.h>
#include <stdio.h>

int main(void){
    
    char ch;
    
    while(1){
        printf("Enter a character (Enter ! to exit):\t");
        ch = getchar();
        if(ch!='!'){
            if(isalpha(ch)){
                printf("%c is a letter of the alphabet\n", ch);
            } else {
                printf("%c is not a letter of the alphabet\n", ch);
            }
            
        } else {
            break;
        }
        
        /*
         * slightly more optimal method
         * of clearing input buffer
         */
        while(getchar()!='\n'){}
        
    }
    
    return 0;
    
}

The isblank() function returns nonzero if the value is a whitespace character.

#include <stdio.h>
#include <ctype.h>

int main(void){
    
    char ch;
    
    while(1){
        
        printf("Enter a character (enter ! to exit): ");
        
        if((ch=getchar())=='!'){
            break;
        }
        
        if(isblank(ch)){
            printf("%c is a whitespace character\n", ch);
        } else {
            printf("%c is not a whitespace character\n", ch);
        }
        
        //clear stdin
        while(getchar()!='\n'){}
        
    }
    
    return 0;
    
}

The isupper() function returns nonzero if the value is an uppercase letter; the islower() function returns nonzero if the value is a lowercase letter.

#include <stdio.h>
#include <ctype.h>

int main(void){
    
    char ch;
    
    while(1){
        printf("Enter a character (! to exit):\t");
        ch=getchar();
        
        if(ch=='!'){
            break;
        }
        
        //test char value using
        //isupper() and islower()
        if(isupper(ch)){
            printf("%c is an uppercase letter.\n", ch);
        } else if (islower(ch)){
            printf("%c is a lowercase letter.\n", ch);
        } else {
            printf("%c is not a letter.\n", ch);
        }
        
        //clears stdin
        while(getchar()!='\n'){}
        
    }
    
    return 0;
    
}

Please visit my author page on Amazon.com: http://www.amazon.com/Al-Jensen/e/B008MN382O/