Force Readings of Strings at an Angle

In the previous lesson, Pointer arithmetic in the C linguistic communication, we focused on pointer arithmetic. In today'southward C programming tutorial we're going to focus on strings and structures once more. Except for what we showed in the outset lessons of the C basics class, we tin can work with them dynamically.

Dynamic strings

When we wanted to store a string, nosotros stored it as an array of characters (charsouth). For this array, we had to specify its exact size, as C arrays require. And specified the size either explicitly:

          char          text[half-dozen] =          "howdy";

Note the size is larger past i due to the zero character '\0'.

Or nosotros left it upwardly to C:

          char          text[] =          "hi";

However, if we want to store text that we don't know all the same (for example, user names entered at runtime), we have 2 options:

  1. Utilize a fixed-size array of characters to store the texts (of size 21, for example). For users with names shorter than twenty characters we'd be wasting retention. E.chiliad. John Doe uses 8 characters only so 12 of them would remain unused. On the other paw, nosotros'd take to truncate user names longer than 20 characters. Bernd Ottovordemgen­tschenfelde is therefore unlucky.
  2. Utilize char pointers to store the texts. Since arrays and pointers are like, nosotros can piece of work with such dynamic strings as we've been used to, even using standard functions. Unfortunately, we'd accept to take care of the strings ourselves so the functions malloc() and free() would go our friends. Also, nosotros'd need to use a buffer (encounter further) to retrieve the strings using standard functions, which complicates the situation. We'd avoid the limit of the option one, but for us, programmers, the awarding would exist much harder to create.

In practice, both approaches are used for storing strings, each having its advantages and disadvantages. Let's try them:

1. Creating static strings

Creating a static cord with the proper noun the user enters would look similar this:

          char          name[21]; printf("Enter your proper noun: "); scanf(" %20[^\due north]", name); printf("Your name is %due south", proper name);

The upshot:

                      c_strings            Enter your proper name: John Smith Your name is John Smith        

2. Creating dynamic strings

Let'due south show how creating a string that is exactly as long equally the user has entered information technology would expect similar. Since we're going to use the scanf() function to read from the console, we need to create an auxiliary static string anyhow. The scanf() function will store the text into it. This auxiliary assortment is often called a buffer. Let'south testify lawmaking and explain information technology:

          char          buffer[101]; printf("Enter your name: ");  scanf(" %100[^\n]", buffer);           char* name = (char          *) malloc(strlen(buffer) +          one);  strcpy(name, buffer);  printf("Your proper noun is %south", proper noun);  costless(name);

We store the cord from the user into the auxiliary assortment. The assortment should be long enough to carry the whole text. Depending on the length of the entered cord, nosotros then create a new dynamic string, by allocating a char array in memory. It probably won't surprise yous that it's 1 character longer than we need, due to the cipher graphic symbol. We set the value from the buffer to the string using the strcpy() part. Now the dynamic string is ready and nosotros can use it as we are used to. Only when we won't need it anymore, it needs to exist freed.

You might be wondering what is the reward of a dynamic string, since memory is wasted by the buffer we need for reading anyway. If we read and stored a million names, nosotros'd still need a unmarried buffer for it and only in the reading phase (then nosotros tin can destroy it). Storing and then many names dynamically would save lots of retention that would be occupied by unused characters otherwise. The price for that is longer code and the need to keep in mind to free strings created like this. Therefore, this solution can't be stated as universal, although I personally prefer it over static strings.

Passing structures by reference

Now permit's move to the promised structures. Nosotros passed them by value until at present. That ways that whenever we stored it into a variable, the construction was copied into it. Let'due south test it on an case.

          #include <stdio.h>          #include <stdlib.h>          #include <cord.h>          typedef          struct          {          char          name[51];          int          age;          char          street[51]; } USER;          int          principal(int          argc,          char** argv) {     USER carl;     strcpy(carl.name,          "Carl Smith");     strcpy(carl.street,          "Evergreen Terrace 5");     carl.age =          27;      USER user2 = carl;     carl.age =          15;     printf("Name: %s\nStreet: %due south\nAge: %d", user2.proper name, user2.street, user2.age);          return          (EXIT_SUCCESS); }

The code to a higher place creates a user in the carl variable and initializes its values. And so it creates another user structure named user2 and stores Carl in it. Since the structure created like this is a value type, we tin can assign it simply as this and re-create it. Irresolute the age of Carl and so doesn't affect user2 in any way. Finally, nosotros impress user2, having the same values as Carl had, fifty-fifty the original historic period:

                      c_structures2            Name: Carl Smith Street: Evergreen Terrace 5 Historic period: 27        

It's worth mentioning that copying the whole variable at once will not piece of work with arrays, as it's, dissimilar construction, made by a arrow.

Passing by value is quite impractical, especially when nosotros desire to change some structure. Let's add together a function to the programme above that accepts a USER structure every bit a parameter and adds 1 to its age.

          void          increaseAge(USER user) {     user.historic period++; }

At present let's make Carl older and print him:

USER carl; strcpy(carl.name,          "Carl Smith"); strcpy(carl.street,          "Evergreen Terrace 5"); carl.age =          27; increaseAge(carl); printf("Proper noun: %s\nStreet: %due south\nAge: %d", carl.proper name, carl.street, carl.age);

Nix will happen:

                      c_structures2            Name: Carl Smith Street: Evergreen Terrace 5 Historic period: 27        

Of course, this is because Carl was copied into the part parameter and this re-create is what was changed, nil happened to the original Carl. 1 solution would be to render the modified Carl and overwrite the previous i with information technology. All the same, realize that C has to re-create each property of the construction, the processor unnecessarily performs a large amount of instructions. Also, we often use malloc() to create structures in our applications anyhow if we want to piece of work with them outside the function in which they were created. (One time a function terminates, C frees the retentiveness used by local variables created in the function, therefore, they don't last and can non be returned).

Let's rewrite the program and so information technology uses pointers:

          void          increaseAge(USER* user) {     user->historic period++; }          int          main(int          argc,          char** argv) {     USER* p_carl = malloc(sizeof(USER));     strcpy(p_carl->name,          "Carl Smith");     strcpy(p_carl->street,          "Evergreen Terrace 5");     p_carl->historic period =          27;      USER* p_user2 = p_carl;     p_carl->historic period =          fifteen;     increaseAge(p_user2);     printf("Name: %s\nStreet: %s\nAge: %d", p_user2->name, p_user2->street, p_user2->age);      free(p_carl);          return          (EXIT_SUCCESS); }

Detect that if nosotros want to get the data from a arrow to a structure, instead of writing the dereference operator (asterisk) before it, nosotros change the dot for the arrow operator (->).

The plan output is equally follows:

                      c_structures2            Proper noun: Carl Smith Street: Evergreen Terrace 5 Age: 16        

At first, the application allocates memory for a structure of the USER type and stores its address into the p_carl variable. Information technology sets the user's values and then creates ane more arrow to Carl, p_user2. Then it changes Carl'south age to 15 and increases the age of the user p_user2 pointer points to past 1 yr. Carl will be 16, since his age was set to 15 before. Nosotros can encounter that both pointers point to the aforementioned user. And then nosotros print Carl using the p_user2 arrow. We won't forget to free the retentivity.

Maybe information technology seems to y'all every bit an unnecessary playing with pointers, but it's very important to empathise how passing works on these small examples, and then that we won't then be lost in larger applications.

The source projects for today's lesson can exist downloaded beneath. Side by side time, in the lesson Dynamic arrays (vectors) in the C language, we'll learn to create a data structure with unlimited size so nosotros could add new and new items to it. It'll be a dynamic assortment that is sometimes called a vector. Look forward to information technology :)


Did you take a trouble with annihilation? Download the sample application below and compare it with your projection, y'all will find the mistake easily.

holmesthail1981.blogspot.com

Source: https://www.ictdemy.com/c-language/dynamic-memory-allocation/dynamic-strings-and-structures-in-the-c-language

0 Response to "Force Readings of Strings at an Angle"

Post a Comment

Iklan Atas Artikel

Iklan Tengah Artikel 1

Iklan Tengah Artikel 2

Iklan Bawah Artikel