- The suffix "_r" is historical, where the 'r' stood for "reentrant".
- A computer program or subroutine is called reentrant.
- if it can be interrupted in the middle of its execution and then safely be called again ("re-entered") before its previous invocations complete execution.
- Using global variable inside the function, ISR(interuppt call) may try to access our temporary changed global value in outside.
- Solution:
- Use the local variable instead of global variable will clear this issue
- _r reason:
- Using _r to make sure global variables are not affected.
- _r function will be thread safe.
- EG: strtok vs strtok_r
- strtok_r() is thread-safe.
- The strtok_r() function is a reentrant version of strtok().
- Strtok_r uses the 3arg as the local variable instead of global variable to record the progress through s1.
Return:The strtok() and strtok_r() functions return a pointer to the next token, or NULL if there are no more tokens.
Attributes:For an explanation of the terms used in this section, see attributes(7). ┌───────────┬───────────────┬───────────────────────┐ │Interface │ Attribute │ Value │ ├───────────┼───────────────┼───────────────────────┤ │strtok() │ Thread safety │ MT-Unsafe race:strtok │ ├───────────┼───────────────┼───────────────────────┤ │strtok_r() │ Thread safety │ MT-Safe │ └───────────┴───────────────┴───────────────────────┘
Program:
/* strtok vs strtok_r by Velraj.K
Check : http://velrajcoding.blogspot.in
*/
Check : http://velrajcoding.blogspot.in
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, char *argv[])
{
char *str1, *str2, *token, *subtoken;
char *saveptr1, *saveptr2;
char str_second[256] = {'\0'};
int j;
{
char *str1, *str2, *token, *subtoken;
char *saveptr1, *saveptr2;
char str_second[256] = {'\0'};
int j;
if (argc != 4) {
fprintf(stderr, "Usage: %s string delim subdelim\n",
argv[0]);
exit(EXIT_FAILURE);
}
fprintf(stderr, "Usage: %s string delim subdelim\n",
argv[0]);
exit(EXIT_FAILURE);
}
strncpy(str_second, argv[1], sizeof(str_second));
printf("\n\n\t\t Do the token using strtok_r \n");
/* use strtok_r */
for (j = 1, str1 = argv[1]; ; j++, str1 = NULL) {
token = strtok_r(str1, argv[2], &saveptr1);
if (token == NULL)
break;
printf("%d: %s\n", j, token);
for (j = 1, str1 = argv[1]; ; j++, str1 = NULL) {
token = strtok_r(str1, argv[2], &saveptr1);
if (token == NULL)
break;
printf("%d: %s\n", j, token);
for (str2 = token; ; str2 = NULL) {
subtoken = strtok_r(str2, argv[3], &saveptr2);
if (subtoken == NULL)
break;
printf(" --> %s\n", subtoken);
}
}
printf("Original value = %s \n", argv[1]);
subtoken = strtok_r(str2, argv[3], &saveptr2);
if (subtoken == NULL)
break;
printf(" --> %s\n", subtoken);
}
}
printf("Original value = %s \n", argv[1]);
printf("\n\n\t\tDo the token using strtok str_second = %s \n", str_second);
/* Initialize the variable to NULL to start token again with strtok */
str1 = NULL;
str2 = NULL;
token = NULL;
subtoken = NULL;
saveptr1 = NULL;
saveptr2 = NULL;
/* Initialize the variable to NULL to start token again with strtok */
str1 = NULL;
str2 = NULL;
token = NULL;
subtoken = NULL;
saveptr1 = NULL;
saveptr2 = NULL;
/* use strtok */
for (j = 1, str1 = str_second; ; j++, str1 = NULL) {
token = strtok(str1, argv[2]);
if (token == NULL)
break;
printf("%d: %s\n", j, token);
#if 0 // Could not use the 2nd strtok with different delim because it uses the global pointer
for (str2 = token; ; str2 = NULL) {
subtoken = strtok(str2, argv[3]);
if (subtoken == NULL)
break;
printf(" --> %s\n", subtoken);
}
#endif
}
for (j = 1, str1 = str_second; ; j++, str1 = NULL) {
token = strtok(str1, argv[2]);
if (token == NULL)
break;
printf("%d: %s\n", j, token);
#if 0 // Could not use the 2nd strtok with different delim because it uses the global pointer
for (str2 = token; ; str2 = NULL) {
subtoken = strtok(str2, argv[3]);
if (subtoken == NULL)
break;
printf(" --> %s\n", subtoken);
}
#endif
}
exit(EXIT_SUCCESS);
}
}
Output:
learn$ ./a.out this,isvelraj,check,strok,new , .
Do the token using strtok_r
1: this
--> this
2: isvelraj
--> isvelraj
3: check
--> check
4: strok
--> strok
5: new
--> new
Original value = this
Do the token using strtok str_second = this,isvelraj,check,strok,new
1: this
2: isvelraj
3: check
4: strok
5: new
No comments:
Post a Comment