converting from string to int using strtol() : \0' or '\n'? - c

I have a doubt with conversion from string to int.
I got a string through function fgets then I used strtol function to convert it to int.
This is the code :
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <limits.h>
int main(void)
{
char buf[BUFSIZ];
char *p = NULL;
long int val;
int numero;
int temp;
do
{
temp=0;
printf ("Enter a number: ");
if (fgets(buf, sizeof(buf), stdin) != NULL)
{
val = strtol(buf, &p, 10);
if(buf==p)
{
printf(" no digits \n");
temp=1;
}
if ((errno == ERANGE && (val == LONG_MAX || val == LONG_MIN)) || (errno != 0 && val == 0))
{
perror("strtol");
temp=1;
}
if (*p != '\0')
{
printf("you have insert any char character \n");
temp=1;
}
}
else
{
printf("Error\n");
temp=1;
}
}
while(temp == 1);
/* If we got here, strtol() successfully parsed a number */
numero=(int)val;
printf("***** The number is : %d ******* \n",numero);
return 0;
}
and this code doen't work, but it work if I replace this control
if (*p != '\0')
{
printf("you have insert any char character \n");
temp=1;
}
with this one :
if (*p != '\n')
{
printf("you have insert any char character \n");
temp=1;
}
Do you know why ? :)
EDIT :
This is the code of my final function version :) Thanks to all :) Now it seem that all correctly works :
int readIN(int *numero)
{
long int val;
char buf[BUFSIZ];
char *p = NULL;
if (fgets(buf, sizeof(buf), stdin) != NULL)
{
val = strtol(buf, &p, 10);
if(buf==p)
{
return 1;
}
if ( (val > INT_MAX || val < 0) || (errno != 0 && val == 0))
{
return 1;
}
if (*p != '\n' && *p != '\r' && *p != '\0')
{
return 1;
}
}
else
{
return 1;
}
*numero=(int)val;
return 0;
}

Your code works perfectly. It has correctly identified that there are trailing characters after the number. As Matt says, gets returns a whole line, including the trailing line feed character (aside: why do people insist on posting the actual answer as a comment?).
Given that your string will almost always have this line feed, your simple fix is probably the right thing to do.
There are two exceptions though:
end of file
operating systems that use carriage returns at the end of line.
A more thorough solution would be this:
if (*p != '\n' && *p != '\r' && *p != '\0')
{
printf("error: unexpected trailing characters in input\n");
temp=1;
}

Related

How to use fgets() function so that it only reads 12 characters per line?

I have a file that contains the following words:
Theendsherethiswillnotjaksdjlasdfjkl;asdjfklasdjfkl;asdfjl;
these
are
the
Below is my code :
int i = 0;
bool duplicateFound = false;
while(fgets(line,12,fp)){
for (int j = 0; j < i; j++){
if (strcmp(wordList[j], line) == 0){
duplicateFound = true;
printf("Duplicate Found on Line %d : %s\n", j, wordList[j]);
}
}
if (duplicateFound == false){
strcpy(wordList[i], line);
printf("%s", wordList[i]);
}
i++;*/
printf("%s", line);
}
I am using line to save each word so that I can later check it for duplicates in the array.
I want it so that the function only reads up to 12 characters on each line but it outputs the following output.
ACTUAL OUTPUT :
Theendsherethiswillnotjaksdjlasdfjkl;asdjfklasdjfkl;asdfjl;
these
are
the
EXPECTED OUTPUT:
Theendsheret
these
are
the
You really should just call fgets and then do line[12] = '\0', but that doesn't cleanly deal with input that has long lines. One option is to simply abort if fgets ever returns a partial line (eg, if strchr(line, '\n') returns NULL).
If you want to handle long lines, you can just discard data with getchar until you see a newline. Assuming that you don't want to consider the newline to be one of the 12 characters, you could do something like:
#include <stdio.h>
#include <string.h>
int
main(void)
{
char line[13];
while( fgets(line, 13, stdin) ) {
char *c = strchr(line, '\n');
int ch;
if( c == NULL ) while( (ch = getchar()) != EOF ) {
if( ch == '\n' ) {
break;
}
} else {
*c = '\0';
}
if( printf("%s\n", line) < 0 ) {
break;
}
}
return ferror(stdout) || ferror(stdin) || fclose(stdout) || fclose(stdin);
}

tempWord[0]='\0' Does not reset String somehow

I wrote a program in C, The expected result should be:
$ cat poem.txt
Said Hamlet to Ophelia,
I'll draw a sketch of thee,
What kind of pencil shall I use?
2B or not 2B?
$ ./censor Ophelia < poem.txt
Said Hamlet to CENSORED,
I'll draw a sketch of thee,
What kind of pencil shall I use?
2B or not 2B?
But I got this:
$ ./censor Ophelia < poem.txt
Said Hamlet tomlet CENSORED,
I'lllia drawlia arawlia sketcha ofetcha theecha,
Whatcha kindcha ofndcha pencila shallla Ihallla usellla?
2Bsellla orellla notllla 2Botllla?
I use tempWord to store every word and compare it with the word that needs to be censored. Then I use tempWord[0]='\0' to reset the temp String, so that I can do another comparison. But it seems not working. Can anyone help?
# include <stdio.h>
# include <string.h>
int compareWord(char *list1, char *list2);
int printWord(char *list);
int main(int argc, char *argv[]) {
int character = 0;
char tempWord[128];
int count = 0;
while (character != EOF) {
character = getchar();
if ((character <= 'z' && character >= 'a') ||
(character <= 'Z' && character >= 'A') ||
character == 39) {
tempWord[count] = character;
count++;
} else {
if (count != 0 && compareWord(tempWord, argv[1])) {
printf("CENSORED");
count = 0;
tempWord[0] = '\0';
}
if (count != 0 && !compareWord(tempWord, argv[1])) {
printWord(tempWord);
count = 0;
tempWord[0] = '\0';
}
if (count == 0) {
printf("%c", character);
}
}
}
return 0;
}
int printWord(char *list) {
// print function
}
int compareWord(char *list1, char *list2) {
// compareWord function
}
There are multiple issues in your code:
You do not test for end of file at the right spot: if getc() returns EOF, you should exit the loop immediately instead of processing EOF and exiting at the next iteration. The classic C idiom to do this is:
while ((character = getchar()) != EOF) {
...
For portability and readability, you should use isalpha() from <ctype.h> to check if the byte is a letter and avoid hardcoding the value of the value of the apostrophe as 39, use '\'' instead.
You have a potential buffer overflow when storing the bytes into the tempWord array. You should compare the offset with the buffer size.
You do not null terminate tempWord, hence the compareWord() function cannot determine the length of the first string. The behavior is undefined.
You do not check if a command line argument was provided.
The second test is redundant: you could just use an else clause.
You have undefined behavior when printing the contents of tempWord[] because of the lack of null termination. This explains the unexpected behavior, but you might have much worse consequences.
printWord just prints a C string, use fputs().
The compWord function is essentially the same as strcmp(a, b) == 0.
Here is a simplified and corrected version:
#include <ctype.h>
#include <stdio.h>
#include <string.h>
int main(int argc, char *argv[]) {
char tempWord[128];
size_t count = 0;
int c;
while ((c = getchar()) != EOF) {
if (isalpha(c) || c == '\'') {
if (count < sizeof(tempWord) - 1) {
tempWord[count++] = c;
}
} else {
tempWord[count] = '\0';
if (argc > 1 && strcmp(tempWord, argv[1]) == 0) {
printf("CENSORED");
} else {
fputs(tempWord, stdout);
}
count = 0;
putchar(c);
}
}
return 0;
}
EDIT: chux rightfully commented that the above code does not handle 2 special cases:
words that are too long are truncated in the output.
the last word is omitted if it falls exactly at the end of file.
I also realized the program does not handle the case of long words passed on the command line.
Here is a different approach without a buffer that fixes these shortcomings:
#include <ctype.h>
#include <stdio.h>
int main(int argc, char *argv[]) {
const char *word = (argc > 1) ? argv[1] : "";
int count = 0;
int c;
for (;;) {
c = getchar();
if (isalpha(c) || c == '\'') {
if (count >= 0 && (unsigned char)word[count] == c) {
count++;
} else {
if (count > 0) {
printf("%.*s", count, word);
}
count = -1;
putchar(c);
}
} else {
if (count > 0) {
if (word[count] == '\0') {
printf("CENSORED");
} else {
printf("%.*s", count, word);
}
}
if (c == EOF)
break;
count = 0;
putchar(c);
}
}
return 0;
}
tempWord[0] = '\0';
It will not reset the variable to null. It just assign the '\0' to the first position. But The values which are assigned are still in memory only. Only the first position is assigned to '\0'. So, to reset the character array try the below.
memset(tempWord, 0, 128);
Add the above line instead of your tempWord[0] = '\0'.
And also this will solves you don't need to add the '\0' at end of each word. This itself will work. But for the first time your have to reset the character array using the same memset function. Before entering to the loop you have to set the tempWord to null using the memset function.
Using tempWord[0]='\0' will not reset the whole array, just the first element. Looking at your code, there are 2 ways you could go forward, either reset the whole array by using memset:
memset(tempWord, 0, sizeof tempWord);
or
memset(tempWord, 0, 128);
(or you can only clear it by the size of last word, also it needs string.h which you have already included),
Or you could just set the element after the length of 'current word' to be '\0' (ex, if current word is the then set tempWord[3]='\0', since strlen checks the string till null char only) which can be placed before those 2 ifs checking if the strings are equal or not, your new while loop will look like this:
{
character = getchar();
if((character<='z' && character>='a')||(character<='Z' && character>='A')||character == 39)
{
tempWord[count]=character;
count++;
}else {
tempWord[count]='\0';
if(count!=0 && compareWord(tempWord, argv[1]))
{
printf("CENSORED");
count=0;
}
if(count!=0 && !compareWord(tempWord, argv[1]))
{
printWord(tempWord);
count=0;
}
if (count==0)
{
printf("%c", character);
}
}
}
(it works, tested)

What's wrong with strtol?

I have this code, which should run fine, but for some reason, the loop would cycle through when I free the string before the conditional check of the loop. And the only way to get out from the loop is by giving integer with more than 3 digits (input > 99 || input < -99).
I'm using gcc to compile this code with code::blocks as IDE.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char* createString(void);
int main() {
int temp = 0;
char* string = 0;
char* error = 0;
do {
printf("\n Integer: ");
string = createString();
temp = strtol(string, &error, 10);
if (*error != '\n' && *error != '\0') printf("\n Input is not an integer");
free(string);
string = 0;
} while (*error != '\n' && *error != '\0');
free(error);
error = 0;
return 0;
}
char* createString() {
char* string = 0;
size_t size = 0;
size_t index = 0;
int ch = EOF;
do {
ch = getc(stdin);
if (ch == EOF || ch == '\n') ch = 0;
if (size <= index) string = (char*) realloc(string, size += 5);
if (!string) {
perror("realloc");
exit(EXIT_FAILURE);
}
string[index++] = ch;
} while(ch);
return string;
}
I did a work-around it by moving the free-ing process to the beginning of the loop cycle and after the loop.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char* createString(void);
int main() {
int temp = 0;
char* string = 0;
char* error = 0;
do {
free(string);
string = 0;
printf("\n Integer: ");
string = createString();
temp = strtol(string, &error, 10);
if (*error != '\n' && *error != '\0') printf("\n Input is not an integer");
} while (*error != '\n' && *error != '\0');
free(string);
string = 0;
free(error);
error = 0;
return 0;
}
char* createString() {
char* string = 0;
size_t size = 0;
size_t index = 0;
int ch = EOF;
do {
ch = getc(stdin);
if (ch == EOF || ch == '\n') ch = 0;
if (size <= index) string = (char*) realloc(string, size += 5);
if (!string) {
perror("realloc");
exit(EXIT_FAILURE);
}
string[index++] = ch;
} while(ch);
return string;
}
The code works fine now, but I'm wondering what is strtol doing.
free(error);
Remove it. error is not allocated in strtol or anywhere else. It is a pointer that points to the middle of string. Freeing it is UB.
You say:
for some reason, the loop would cycle through when I free the string before the conditional check of the loop
Keep in mind that with the call strtol(string, &error, 10); the pointer error will point into the string string. So if you free string before doing this:
if (*error != '\n' && *error != '\0') printf("\n Input is not an integer");
or this:
while (*error != '\n' && *error != '\0')
You'll invoke undefined behavior because error will be pointing to freed memory.

How to fill array of character pointers with arguments taken from scanf?

I'm trying to write a VERY basic shell program in C. The problem I am facing is trying to fill my argv array of character pointers with the words taken from input. When I attempt to print out the contents of the argv array after attempting to fill it using the parse() function below I get a segmentation fault. I know this means that I am probably trying to access part of the argv array that is out of bounds. However, even when supplying only one argument to fill the array, I still get the segfault. The printf call used to print argc returns the correct value for argc based on input, but the second printf call with *argv[0] is the one causing the segfault. I am wondering if my error is in the way I am attempting to print the contents of argv, or if the error is because I am attempting to fill argv incorrectly.
EDIT: I should add that the getword() function takes in a line of text and returns the first word delimited by spaces, and a number of other delimiters. I can post all the delimiters it breaks the words up by if necessary, but I do not think the problem is because of getword().
EDIT 2: Added in the header file and included the #include statement in main.
EDIT 3: Added the getword function under main(), and getword.h below p2.h
Here is p2.h, the header file included in main:
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include "getword.h"
#include <signal.h>
#define MAXITEM 100
getword.h:
#include <stdio.h>
#include <string.h>
#include <strings.h>
#define STORAGE 255
int getword(char *w);
int parse(char *, char *[]);
Here is the main function :
#include "p2.h"
int main() {
pid_t pid, child_pid;
int argc, inputRedirect;
char *devNull;
devNull = (char *) malloc(10);
strcpy(devNull, "/dev/null");
char *argv[MAXITEM];
char commandLine[STORAGE];
for (;;) {
printf("p2: ");
scanf("%s", commandLine);
argc = parse(commandLine, argv);
printf("argc = %d\n", argc);
if(argc == 0)
continue;
printf("*argv = %s\n", *argv[0]);
child_pid = fork();
if (child_pid < 0) {
printf("Cannot fork! Terminating...");
exit(1);
} else if (child_pid == 0) {
inputRedirect = open(devNull, O_RDONLY);
dup2(inputRedirect, STDIN_FILENO);
close(inputRedirect);
execvp(*argv, argv);
}
else {
for(;;) {
pid = wait(NULL);
if(pid == child_pid)
break;
}
printf("Child's pid is %d\n", child_pid);
}
}
killpg(getpid(), SIGTERM);
printf("p2 Terminated.\n");
exit(0);
}
int parse(char *commandLine, char *argv[]) {
int i, argc = 0;
char *commandPointer = commandLine;
while (*commandPointer != '\0') {
*argv = commandPointer;
argc++;
getword(commandPointer);
}
*commandPointer = '\0';
*argv = '\0';
return argc;
}
getword.c:
#include "getword.h"
#include <stdlib.h>
/*Function Prototypes*/
int tilde(char *p, int i);
int BSFollowedByMetaCharacter(int c, char *w);
int getword(char *w) {
int c;
int index = 0;
/*This while loop removes all leading blanks and whitespace characters
* The if statement then tests if the first character is a new line or
* semicolon metacharacter*/
while ((c = getchar()) == ' ' || c == '\t' || c == '\n' || c == ';') {
if (c == '\n' || c == ';') {
w[index] = '\0';
return 0;
}
}
/*This if statement calls ungetc() to push whatever character was taken
* from the input stream in the previous while loop back to the input
* stream. If EOF was taken from the input stream, ungetc() will return EOF,
* which will then cause getword() to return -1, signalling that it reached
* the End Of File. */
if (ungetc(c, stdin) == EOF)
return -1;
/*This if statement deals with some of the "non-special" metacharacters.
* If one of these metacharacters is pulled from the input stream by getchar(),
* it is stored in w and null-terminated. getword() then returns the length of
* the current string stored in w. If getchar() pulls anything besides one of the
* specified metacharacters from the input stream, it is then returned using ungetc() after
* the if statement.*/
if ((c = getchar()) == '<' || c == '>' || c == '|' || c == '&') {
w[index++] = c;
int d = getchar();
if (c == '>' && d == '>')
w[index++] = d;
else {
ungetc(d, stdin);
}
w[index] = '\0';
return index;
}
ungetc(c, stdin);
/*This while statement handles plain text from the input stream, as well as a few 'special'
* metacharacters. It also ensures that the word scanned is shorter than STORAGE-1 bytes.*/
while ((c = getchar()) != ' ' && c != '<' && c != '>' && c != '|'
&& c != ';' && c != '&' && c != '\t' && c != '\n' && c != '\0'
&& index <= STORAGE - 1) {
if (c == '~') {
int *ip = &index;
index = tilde(&w[index], *ip);
continue;
}/*END IF*/
else if (c == '\\') {
int d = c;
c = getchar();
if (BSFollowedByMetaCharacter(c, w)) {
w[index++] = c;
continue;
} else {
w[index++] = d;
}
}/*END ELSE IF*/
w[index] = c;
index++;
}/*END WHILE*/
ungetc(c, stdin);/*This final ungetc() call is used to push any meta characters*/
w[index] = '\0'; /*used as delimiters back to the input stream, to be retrieved*/
return index; /*at the next call of getword(). */
}/*END getword()*/
int tilde(char *cp, int i) {
int *ip;
ip = &i;
char *p = cp;
char *o;
o = (strcpy(p, getenv("HOME")));
int offset = strlen(o);
*ip = *ip + offset;
return i;
}
int BSFollowedByMetaCharacter(int c, char *w) {
if (c == '~' || c == '<' || c == '>' || c == '|' || c == ';' || c == '&'
|| c == ' ' || c == '\t' || c == '\\') {
return 1;
} else {
return 0;
}
}
The functions in getword.c seems correct. Your problem is in function parse.
To use execvp, contents of argv should be following (input:"hello world"):
argv[0] -> "hello"
argv[1] -> "world"
argv[2] -> NULL
Here, argv is an array of character pointers. But, in parse function, you are treating argv like simple character pointers in here:
*argv = commandPointer;
and here:
*argv = '\0';
Change your parse function into something like this:
int parse(char *commandLine, char *argv[]) {
int argc = 0;
char *commandPointer;
argv[argc++] = commandLine;
do{
commandPointer = (char*)malloc(sizeof(char) * STORAGE);
argv[argc++] = commandPointer;
getword(commandPointer);
}while(*commandPointer != '\0');
argv[argc] = NULL;
return argc;
}
Now, you should free allocated memory after if-else tree like:
for(int i = 0; i < argc; i++) free(argv[i]);

String Search and format in C

Just a quick one: in C I have a buffer full of data like below:
char buffer[255]="CODE=12345-MODE-12453-CODE1-12355"
My question is how to search through this. For example for the CODE=12345, section bear in mind that the numbers change, so I would like to search like this CODE=***** using wildcard or preset amount of spaces after the CODE= part.
This method wont compile last one left to try
#include <stdio.h>
#include <string.h>
#include <windows.h>
int main ()
{
char buf[255]="CODE=12345-MODE-12453-CODE1-12355";
#define TRIMSPACES(p) while(*p != '\0' && isspace((unsigned char)*p) != 0) ++p
#define NSTRIP(p, n) p += n
#define STRIP(p) ++p
char* getcode(const char *input)
{
char *p = (char*) input, *buf, *pbuf;
if((buf = malloc(256)) == NULL)
return NULL;
pbuf = buf;
while(*p != '\0') {
if(strncmp(p, "CODE", 3) == 0) {
NSTRIP(p, 4); //remove 'code'
TRIMSPACES(p);//trim white-space after 'code'
if(*p != '=')
return NULL;
STRIP(p); // remove '='
TRIMSPACES(p); //trim white-spaces after '='
/* copy the value until found a '-'
note: you must be control the size of it,
for avoid overflow. we allocated size, that's 256
or do subsequent calls to realloc()
*/
while(*p != '\0' && *p != '-')
*pbuf ++ = *p++;
// break;
}
p ++;
}
//put 0-terminator.
*pbuf ++ = '\0';
return buf;
}
//
}
You could use the sscanf() function:
int number;
sscanf(buffer, "CODE = %i", &number);
for that to work well your buffer has to be null terminated.
Another way to do it instead of sscanf():
char *input, *code;
input = strstr(buf, "CODE");
if(input == NULL) {
printf("Not found CODE=\n");
return -1;
}
code = strtok(strdup(input), "=");
if(code != NULL) {
code = strtok(NULL, "-");
printf("%s\n", code); // code = atoi(code);
} else {
//not found '='
}
Or more robust way.. a bit more complex:
#define TRIMSPACES(p) while(*p != '\0' && isspace((unsigned char)*p) != 0) ++p
#define NSTRIP(p, n) p += n
#define STRIP(p) ++p
char* getcode(const char *input, size_t limit)
{
char *p = (char*) input, *buf, *pbuf;
size_t i = 0;
while(*p != '\0') {
if(strncmp(p, "CODE", 3) == 0) {
NSTRIP(p, 4); //remove 'code'
TRIMSPACES(p);//trim all white-spaces after 'code'
/* check we have a '=' after CODE (without spaces).
if there is not, returns NULL
*/
if(*p != '=')
return NULL;
/* ok. We have.. now we don't need of it
just remove it from we output string.
*/
STRIP(p);
/* remove again all white-spaces after '=' */
TRIMSPACES(p);
/* the rest of string is not valid,
because are white-spaces values.
*/
if(*p == '\0')
return NULL;
/* allocate space for store the value
between code= and -.
this limit is set into second parameter.
*/
if((buf = malloc(limit)) == NULL)
return NULL;
/* copy the value until found a '-'
note: you must be control the size of it,
for don't overflow. we allocated 256 bytes.
if the string is greater it, do implementation with
subjecents call to realloc()
*/
pbuf = buf;
while(*p != '\0' && *p != '-' && i < limit) {
*pbuf ++ = *p++;
i ++;
}
*pbuf ++ = '\0';
return buf;
}
p ++;
}
return NULL;
}
And then:
char buf[255] = "foo baa CODE = 12345-MODE-12453-CODE-12355";
char *code = getcode(buf,256);
if(code != NULL) {
printf("code = %s\n", code);
free(code);
} else {
printf("Not found code.\n");
}
output:
code = 12345
Check out this online.
if you want to don't differentiate case, you can use the strncasecmp() that's POSIX function.
Assuming the CODE= part always comes at the beginning of the string, it's pretty easy:
sscanf(buffer, "CODE = %d", &number);
...but you want buffer to be char[255], not unsigned long.
Edit: If the CODE= part isn't necessarily at the beginning of the string, you can use strstr to find CODE in the buffer, do your sscanf starting from that point, then look immediately following that:
int codes[256];
char *pos = buffer;
size_t current = 0;
while ((pos=strstr(pos, "CODE")) != NULL) {
if (sscanf(pos, "CODE = %d", codes+current))
++current;
pos += 4;
}
Edit2:
For example, you'd use this something like this:
#include <stdio.h>
#include <string.h>
#include <windows.h>
int main ()
{
// This is full of other junk as well
char buffer[255]="CODE=12345 MODE-12453 CODE=12355" ;
int i;
int codes[256];
char *pos = buffer;
size_t current = 0;
while ((pos=strstr(pos, "CODE")) != NULL) {
if (sscanf(pos, "CODE = %d", codes+current))
++current;
pos += 4;
}
for (i=0; i<current; i++)
printf("%d\n", codes[i]);
return 0;
}
For me, this produces the following output:
12345
12355
...correctly reading the two "CODE=xxx" sections, but skipings over the "MODE=yyy" section.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char *getcode(const char *str, const char *pattern){
//pattern: char is match, space is skip, * is collect
static const char *p=NULL;
char *retbuf, *pat;
int i, match, skip, patlen;
if(str != NULL) p=str;
if(p==NULL || *p=='\0') return NULL;
if(NULL==(retbuf=(char*)malloc((strlen(p)+1)*sizeof(char))))
return NULL;
pat = (char*)pattern;
patlen = strlen(pat);
i = match = skip = 0;
while(*p){
if(isspace(*p)){
++p;
++skip;
continue;
}
if(*pat){
if(*p == *pat){
++match;
++p;
++pat;
} else if(*pat == '*'){
++match;
retbuf[i++]=*p++;
++pat;
} else {
if(match){//reset
pat=(char*)pattern;
p -= match + skip -1;
i = match = skip = 0;
} else //next
++p;
}
} else {
break;
}
}
if(i){//has match
retbuf[i++]='\0';
retbuf=realloc(retbuf, i);
return retbuf;
} else {
free(retbuf);
return NULL;
}
}
int main (){
char *code;
code=getcode("CODE=12345-MODE-12453-CODE1-12355", "CODE=*****");
printf("\"%s\"\n",code);//"12345"
free(code);
code=getcode(" CODE = 12345-MODE-12453-CODE1-12355", "CODE=*****");
printf("\"%s\"\n",code);//"12345"
free(code);
code=getcode("CODE-12345-MODE-12453-CODE1-12355", "CODE=*****");
if(code==NULL)printf("not match\n");//not match
code=getcode("CODE=12345-MODE-12453-CODE=12355", "CODE=*****");
printf("\"%s\"\n",code);//"12345"
free(code);
code=getcode(NULL, "CODE=*****");
printf("\"%s\"\n",code);//"12355"
free(code);
code=getcode("CODE=12345-MODE-12453-CODE1-12355", "CODE=*****");
printf("\"%s\"\n",code);//"12345"
free(code);
code=getcode(NULL, "CODE1-*****");
printf("\"%s\"\n",code);//"12355"
free(code);
return 0;
}

Resources