Parsing house number from street address represented as a char[] - c

Suppose I have a street address stored as a char[]. Examples of valid values:
1600 Pennsylvania Ave
1 Infinite Loop
221 Baker Street
As you can see, the house number can be of any length.
In C, what is an efficient way of separating the house number into its own int? I'm thinking I need to write a while loop to check for each char c if isdigit(c), but I don't know if I'm on the right track here in terms of implementation.

You can use strtok to break up the string into tokens and use isdigit() to figure out if that token is numeric.
#include <string.h>
#include <stdio.h>
int main()
{
const char str1[80] = "1600 Pennsylvania Ave";
int houseNumber = 0;
const char s[2] = " ";
char *token;
/* get the first token */
token = strtok(str, s);
/* walk through other tokens */
while( token != NULL ) {
printf( " %s\n", token );
if (isdigit(str1[0])) {
houseNumber = atoi (token);
}
token = strtok(NULL, s);
}
return(0);
}
Alternatively, you can use sscanf to read the entire string and automatically parse everything:
#include <string.h>
#include <stdio.h>
int main()
{
const char str1[80] = "1600 Pennsylvania Ave";
int houseNumber = 0;
char streetName[50];
char streetExt[20];
sscanf (str1,"%d %s %s", &houseNumber, streetName, streetExt);
return(0);
}
This last method depends on the format of the strings being exactly the same in all cases, meaning that it's always a number followed by 2 strings. The strtok method will be a little more fault tolerant if there's more other stuff.

Consider the following solution:
#include <stdio.h>
#include <string.h>
int main(void)
{
char address[255];
char * ptr;
int number;
char strnumber[100];
char strstreet[255];
// ask adress
printf("Please, enter the addres: ");
// put end of string replacing newline
fgets(address, 255, stdin);
ptr = strchr(address, '\n');
if(ptr)
{
*ptr = '\0';
}
else
{
address[254] = '\0';
}
// try to read whole number from the beggining of the string
if( 1 == sscanf(address, "%d", &number) )
{
// make number as a string (if it is needed)
sprintf(strnumber, "%d", number);
// take streat to separate string
ptr = strchr(address + strlen(strnumber), ' '); // find the firs space
if( ptr )
{
strcpy(strstreet, ptr + 1); // +1 just to skip the found space
}
}
else
{ // if no number at the beginning of address string
number = 0;
strnumber[0] = '\0';
strstreet[0] = '\0';
}
// show the results
printf("You have entered a string:\n%s\n", address);
printf("The found number is:\n%d\n", number);
printf("The found number as a string:\n%s\n", strnumber);
printf("The address without number is:\n%s\n", strstreet);
}

I would use strstr and atoi like this
char someAddress[80] = "1600 Pennsylvania Ave";
char* p = strstr(someAddress, " ");
if (p)
{
*p = 0; // Terminate string, i.e. cheat for a moment
int number = atoi(someAddress);
*p = " "; // Restore someAddress
}
else
{
// Handle illegal format in someAddress
}
This method shall only be used when you know it is safe to modify someAddress for a short period.

This is one situation with the numbers first, where it is much easier just to use a simple pointer and an if statement to parse the line:
#include <stdio.h>
#define ADDL 64
int main (void) {
char address[ADDL] = {0};
char street[16] = {0};
while (fgets (address, ADDL-1, stdin) != NULL)
{
char *ap = address;
char *sp = street;
while (*ap >= '0' && *ap <= '9') /* while the char is a number */
{
*sp = *ap++; /* copy to street number */
sp++;
}
*sp = 0; /* null-terminate */
printf (" Address: %s Number : %s\n\n", address, street);
}
return 0;
}
Output
$ ./bin/split_address < dat/houses.txt
Address: 1600 Pennsylvania Ave
Number : 1600
Address: 1 Infinite Loop
Number : 1
Address: 221 Baker Street
Number : 221
Note: the printf statement above makes use to the embedded newline at the end of address rather than stripping it as you would normally do. Also note that if you want the number as an integer, long, or unsigned, simply call atoi, strtol or strtoul on street.

Related

Can't dynamically allocate a string

I tried to dynamically allocate a string using a function I named ALLO, but when I execute I get an error, which is my function ALLO can't get the string using getc, it gets skipped.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void ALLO(char *str){
char c=0;
int i = 0, j = 1;
str = (char*)malloc(sizeof(char));
printf("Enter String : ");
while (c != '\n') {
// read the input from keyboard standard input
c = getc(stdin);
// re-allocate (resize) memory for character read to be stored
str = (char*)realloc(str, j * sizeof(char));
// store read character by making pointer point to c
str[i] = c;
i++;
j++;
}
str[i] = '\0'; // at the end append null character to mark end of string
printf("\nThe entered string is : %s", str);
free(str); // important step the pointer declared must be made free
}
int main(){
char *NomAF;
int NAF;
printf("Entrer le nombre des ateliers : ");
scanf("%d",&NAF);
ALLO(NomAF);
return 0 ;
}
The semantics are wrong.
You ask the user for the names of the athletes, and then you scan it into an integer. You should ask for the number of athletes first. Then, after that, you allocate memory to accommodate each name.
int num_names;
scanf("%d", &num_names);
After you know the number of names, you then allocate a buffer for each name, separately.
char **names;
names = malloc(num_names * sizeof(char **));
for(int i = 0; i < num_names; i++)
ALLOC(&names[i]);
Also, you shouldn't be using scanf for user input. Use fgets instead, which is a little better.
Then, you also should be using a pointer to pointers to get those strings.
A little modified version of your code (which you should review and fix, as needed):
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void ALLO(char **str){
/* use INT for getc() return */
int c=0, i = 0;
/* you are gettting 1 byte of memory */
*str = malloc(sizeof **str);
/* should use fprintf(stderr...) or fflush(stdout) to guarantee
* the sentence will be seen by user
*/
printf("Enter String : ");
while (c != '\n') {
// read the input from keyboard standard input
c = getc(stdin);
// re-allocate (resize) memory for character read to be stored
/* i = 0 in the first run,
*
* and you have 1 byte alloced in the first run.
*
* so you get 1 byte for actual getc() return
* 1 byte for next character + NULL byte
*
* NOTE: you are STORING the NULL byte in your string. You only
* check for it AFTER you do the assignment, so your strings
* contain a newline before the NULL byte.
*/
*str = (char*)realloc(*str, (i + 2) * sizeof **str);
// store read character by making pointer point to c
(*str)[i] = c;
// you can use only 'i' for this...
i++;
/* #i
*
* Using only 'i' requires that you understand what #i is doing
* during execution. #i will keep the current buffer position,
* and you know you need one more position for the next
* character and one more for the NULL byte.
*
* Therefore, in your realloc statemente, you need #(i + 2)
*/
}
(*str)[i] = '\0'; // at the end append null character to mark end of string
printf("\nThe entered string is : %s", *str);
// if you free here, you can't get the string at #main for printing.
// free is the last step
//free(str); // important step the pointer declared must be made free
}
int main(){
char **NomAF;
int NAF, i;
char buf[100];
printf("Number of athlets : ");
fgets(buf, sizeof(buf), stdin);
NAF = atoi(buf);
NomAF = malloc(NAF * sizeof *NomAF);
// check malloc errors
// get names
for(i = 0; i < NAF; i++) {
ALLO(&NomAF[i]);
printf("New name: %s\n", NomAF[i]);
}
// print names, then free() then
for(i = 0; i < NAF; i++) {
printf("Name: %s\n", NomAF[i]);
free(NomAF[i]);
}
// free the base pointer
free(NomAF);
return 0 ;
}
Add this
while((c=getchar()!='\n')&&c!=EOF);
before getc it skips white space.
Because after this scanf("%d",&NAF); take you are giving input 5(+enter) this goes 5'\n' 5 is got by scanf and '\n' is in buffer and this new line is got by your getc.
and change this str[i] = '\0'; to str[i-1] = '\0';, it replaces the newline with NULL and you allocated memory for i characters only.
You can return the string by return str; and change function return type as char* or if don't want that take a parameter that allocated by malloc.
See this:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void ALLO(char *str)
{
char c=0;
int i = 0;
printf("Enter String : ");
while (c != '\n')
{
while((c=getchar()!='\n')&&c!=EOF);
c = getc(stdin);
str = (char*)realloc(str, (i+1) * sizeof(char));
if(!str) exit(1);
str[i] = c;
i++;
}
str[i-1] = '\0';
}
int main()
{
char *NomAF;
int NAF;
NomAF=malloc(sizeof(char));
if(!NomAF) exit(1);
printf("Entrer le nombre des ateliers : ");
scanf("%d",&NAF);
ALLO(NomAF);
printf(NomAF);
free(NomAF);
return 0 ;
}
output:
Entrer le nombre des ateliers : 5
Enter String : a
s
d
f
g
----->newline to stop the loop
asdfg
Process returned 0 (0x0) execution time : 8.205 s
Press any key to continue.
I entered it as a string not character by character, its not practical to ask the user the enter letter by letter
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
char * inputword(char **);
int main()
{
char *word;
printf("Enter Word:");
word=inputword(NULL);
printf("Word Entered:%s",word);
free(word);
printf("\nEnter Word 2:");
inputword(&word);
printf("Word Entered:%s",word);
free(word);
return 0 ;
}
char *inputword(char **word)
{
char *str=NULL,ch,*memerr="Memory Error";
int i=0,flag=1;
do
{
str=realloc(str,((i+1)*sizeof(char)));
if(!str)
{
printf(memerr);
exit(1);
}
ch = getch();
switch(ch)
{
case 13:
str[i] = '\0';
putc('\n',stdout);
flag=0;
break;
case '\b':
if(i>0) i--;
str[i--]='\0';
printf("\b \b");
break;
default:
str[i] = ch;
putc(ch,stdout);
}
i++;
}while(flag);
if(word!=NULL)
*word=str;
return str;
}
output:
Enter Word:Hai, How are You?(1 String)
Word Entered:Hai, How are You?(1 String)
Enter Word 2:Hai, How are You?(2 string)
Word Entered:Hai, How are You?(2 string)
Process returned 0 (0x0) execution time : 58.883 s
Press any key to continue.

Function that concatenates two pointer strings together

I am having issues when it comes to concatenating these two pointer strings together, below is my concatenating function, I am supposed to take string 1 and add it to string 2. Also I cannot use any functions in the string library, that's the point of this is to help us understand what code is actually in the functions by writing it ourself.
char strconcat(char *user2p, char *user1p) {
while (*user2p) {
user2p++;
}
while (*user1p) {
*user2p = *user1p;
*user2p++;
*user1p++;
}
*user2p = '\0';
printf("test: %c", *user2p);
return *user2p;
}
And here is the part of my main that is relevant to the function.
int main() {
char userString1[21], userString2[21];
char *user1p, *user2p;
user1p = userString1;
user2p = userString2;
printf("Please enter the first string: ");
gets(userString1);
printf("Please enter the second string: ");
gets(userString2);
printf("String 1 after concatenation: ");
puts(userString1);
printf("String 2 after concatenation: %c\n", strconcat(user2p, user1p));
The terminal keeps giving me this, I didn't include the code for the length and alphabetical order. It gives me a null when I try to run the test printf in the function and it gives me nothing when I return the function. I'm at a loss and any help is much appreciated!
Please enter the first string: jackhammer
Please enter the second string: jacky
The length of string 1 is: 10
The length of string 2 is: 5
String 1 comes before string 2 alphabetically.
String 1 after concatenation: jackhammer
(null)
String 2 after concatenation:
Your concat algorithm is fine, but you have to return a pointer to the original [leftmost] value, so your function needs to save it before looping:
char *
strconcat(char *user2p, char *user1p)
{
char *orig2p = user2p;
while (*user2p) {
user2p++;
}
while (*user1p) {
*user2p = *user1p;
user2p++;
user1p++;
}
*user2p = '\0';
printf("test: %s\n", orig2p);
return orig2p;
}
UPDATE:
To come up with a completely bulletproof test program for the concat function, we can use [overly] large input buffers and clip the input length to a maximum of 1/2 of the target buffer.
gets strips the newline but fgets does not. So, I've created an xgets function that is similar to gets but uses fgets and strchr to get [nearly] the same effect.
Although I believe it's okay to use standard string functions as part of the test code, I've created a hand coded version of strchr [hope that's not your next assignment :-)].
Anyway, here's the full program:
#include <stdio.h>
char *
strconcat(char *user2p, char *user1p)
{
char *orig2p = user2p;
while (*user2p) {
user2p++;
}
while (*user1p) {
*user2p = *user1p;
*user2p++;
*user1p++;
}
*user2p = '\0';
printf("test: %s\n", orig2p);
return orig2p;
}
char *
xstrchr(char *buf,int chrwant)
{
int chrcur;
char *res = NULL;
for (chrcur = *buf++; chrcur != 0; chrcur = *buf++) {
if (chrcur == chrwant) {
res = buf - 1;
break;
}
}
return res;
}
char *
xgets(char *buf,int maxlen)
{
char *cp;
char *res;
res = fgets(buf,maxlen,stdin);
if (res != NULL) {
cp = xstrchr(buf,'\n');
if (cp != NULL)
*cp = 0;
}
return res;
}
#define MAXLEN 800
int
main(void)
{
char userString1[MAXLEN], userString2[MAXLEN + 1];
char *user1p, *user2p;
printf("Please enter the first string: ");
user1p = xgets(userString1,MAXLEN / 2);
printf("Please enter the second string: ");
user2p = xgets(userString2,MAXLEN / 2);
if ((user2p != NULL) && (user1p != NULL))
printf("String 2 after concatenation: %s\n",strconcat(user2p, user1p));
return 0;
}
There's a number of issues. First is this.
while (*user1p) {
*user2p = *user1p;
*user2p++;
*user1p++;
}
This is working by accident. If you have compiler warnings on you should get a warning...
test.c:13:9: warning: expression result unused [-Wunused-value]
*user2p++;
^~~~~
test.c:14:9: warning: expression result unused [-Wunused-value]
*user1p++;
^~~~~~~
The reason it's unused is because C is interpreting it like so:
*(user1p++)
Increment the pointer, then dereference it. You just want to increment the pointers, no dereferencing required.
while (*user1p) {
*user2p = *user1p;
user2p++;
user1p++;
}
Then down here.
printf("String 2 after concatenation: %c\n", strconcat(user2p, user1p));
%c prints an individual char. You want %s which prints a char *. This reveals you have the wrong signature. strconcat should return a char * (ie. what C uses for strings) and return user2p (a char *).
char *strconcat(char *orig_to, const char *from) {
...
return user2p;
}
And since you're not changing from it should be const char * to let the compiler know and warn you if its accidentally changed.
Finally, when you return *user2p it's already been moved to the end of the string.
while (*user1p) {
*user2p = *user1p;
user2p++;
user1p++;
}
*user2p = '\0';
printf("test: %c", *user2p);
// This points to the null byte just set above
return user2p;
So printing the result of strconcat will print nothing. To get around this, store the original pointer for user2p and return that.
char *strconcat(char *orig_to, const char *from) {
char *orig_user2p = user2p;
...
return orig_user2p;
}
And some tips. It's easier to follow the code with good variable names that describe what they're doing.
char *strconcat(char *orig_to, const char *from) {
char *to = orig_to;
...
}
char foo[NN] already makes foo a pointer. There's no need to declare separate char * variables and copy the pointer.
char from[21], to[21];
Never use gets. There's no limit to how much memory it can use and it can easily overflow your buffer. Use fgets which can limit how much can be read to available memory.
printf("Please enter the string to concat from: ");
fgets(from, sizeof(from), stdin);
Though it's annoying that it keeps the newline and there's no simple function to strip it. You can use scanf which will strip whitespace, but beware its many pitfalls.
printf("Please enter the string to concat from: ");
scanf("%20s", from);
printf("Please enter the string to concat to: ");
scanf("%20s", to);
Finally, be sure the string you're concatenating to can hold its own contents and the new contents.
char from[21], to[41];
printf("Please enter the string to concat to: ");
// Be sure to leave enough room in `to` to fit `from`.
fgets(to, sizeof(to) - sizeof(from), stdin);
I would have created a more dynamic memory model. This code is more generic and concatenates strings creating a new string containing both strings.. Free when done :-)...
char *strconcat(char *string1, char *string2) {
int lenStr1=0,lenStr2=0;
char *tmpStr1=string1,*tmpStr2=string2,*returnStr;
while (*tmpStr1++)lenStr1++;
while (*tmpStr2++)lenStr2++;
if((returnStr=(char *)malloc(lenStr1+lenStr2+1))){
memcpy(returnStr,string1,lenStr1);
memcpy(&returnStr[lenStr1],string2,lenStr2);
returnStr[lenStr1+lenStr2]=0;
return returnStr;
} else {
return 0;
}
}
int main() {
char *string1="String 1 ",*string2="String 2 ",*result;
if((result=strconcat(string1, string2))) {
printf("-> %s \n",result);
free(result);
} else {
printf("Out of memory");
return EXIT_FAILURE;
}
return EXIT_SUCCESS;
}

Parsing a string with scanf

I need to get integers from a string that an user enters into the console.
For exemple:
I have this string: [1, 2, 3, 4, 5] and I would like to get all of the integers from it. I already tried multiple scanf patterns, such as scanf("%*[^\[]%d,", &a), but nothing worked. I couldn't find anything relevant on Stack Overflow either.
The main problem is that he can enters between 1 and 50 integers into his string. I have no idea about how to stock only integers (removing ',' and '[' ']' ) into an array.
Some solutions have been found for removing special chars such as [ ] or ,
But now I still need to remove SPACE between comas and integers...
EDIT : problem solved using fgets. I was using scanf to get my string, but it were stopping to SPACES.
Fond out how to do that with scanf :
while(scanf(" %d",&i))
scanf/sscanf does not support regular expressions. You should try something like:
const char my_string[] = "[1,2,3,4,5]";
int a,b,c,d,e;
sscanf(my_string, "[%d,%d,%d,%d,%d]", &a, &b, &c, &d, &e);
Example: http://ideone.com/AOaD7x
It can also be good to check the return value of scanf/sscanf:
int retval = sscanf(my_string, "[%d,%d,%d,%d,%d]", &a, &b, &c, &d, &e);
if (retval != 5)
fprintf(stderr, "could not parse all integers\n");
Reference
Edit:
In your edited question you asks how to do this if there is a variable number of integers. You can use strchr to locate the next comma in the string and continue to iterate until no more comma is found. This assumes that the string ends with ].
const char my_string[] = "[1,2,3,4,5]";
/* start at first integer */
const char *curr = &my_string[1];
while (curr != NULL) {
/* scan and print the integer at curr */
int tmp;
sscanf(curr, "%d", &tmp);
printf("%d\n", tmp);
/* find next comma */
curr = strchr(curr, ',');
/* if a comma was found, go to next integer */
if (curr)
/* warning: this assumes that the string ends with ']' */
curr += 1;
}
Example: http://ideone.com/RZkjWN
Try this piece of code, by using strtok you can separate out all type of unwanted characters in your string. Add all your unwanted set of character to this s array and let strtok do the work.
char str[]="[1,2,3,4,5]";
const char s[4] = "[],"; // All unwanted characters to be filtered out
char *token;
token = strtok(str, s);
while( token != NULL )
{
printf( "%d\n", atoi(token));
token = strtok(NULL, s);
}
Since you have it in the integer format, you could store it in an array and go further with it.
Output :
1
2
3
4
5
Using scanf() for parsing strings is not recommended.
Similarly to others answers, you can use strtok to parse the numbers between "[],", and convert the found numbers using strtol. It would be dangerous to use something like atoi() for integer conversion, as their is no error checking with it. Some more error checking with strtol() can be found in the man page.
Here is some sample(can be improved) code which does this:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAXNUM 50
#define BASE 10
int main(void) {
char string[] = "[1,2,3,4,5]";
char *number, *endptr;
const char *delim = "[],";
int numbers[MAXNUM], current;
size_t i, count = 0;
number = strtok(string, delim);
while (number != NULL) {
current = strtol(number, &endptr, BASE);
/* checking if valid digit found */
/* more error checking can be added */
if (endptr != number) {
numbers[count++] = current;
}
number = strtok(NULL, delim);
}
for (i = 0; i < count; i++) {
printf("numbers[%zu] = %d\n", i, numbers[i]);
}
return 0;
}
Sample input 1:
string[] = "[1,2,3,4,5]";
Output 1:
numbers[0] = 1
numbers[1] = 2
numbers[2] = 3
numbers[3] = 4
numbers[4] = 5
Sample input 2:
string[] = "[1,a,3,c,5]";
Output 2:
numbers[0] = 1
numbers[1] = 3
numbers[2] = 5

I/O - Manipulation of C Strings

I'd like to iterate through a string (entered by the user), returning the inputted string with an added space after each character (i.e. "Hello" --> "H e l l o ".
If I preset the value for str (i.e. char str[] = "Hello";) then the desired result is printed ("H e l l o "), but not so with user input (i.e. If the user inputs "Hello" the output is "H"). How does one successfully extract and manipulate a C string based on user input?
#include <stdio.h>
#include <string.h>
int main()
{
char str[] = "";
printf("\nEnter a string: ");
scanf("%s", &str);
printf("\nYou typed: %s \n", str);
int i = 0;
char newstr[150] = "";
for (i = 0; i < strlen(str); i++)
{
newstr[2*i] = str[i];
newstr[2*i+1] = ' ';
}
newstr[2 * strlen(str)] = '\0';
printf("\nExpanded String: ");
printf("%s", newstr);
return 0;
}
Here:
char str[] = "";
the size of str is inferred from the initializer, which is in this case one byte large. Thus str cannot hold a string larger than one byte, and since the zero-terminator is one byte large, there is no more space for a payload. A fix is to specify a size:
char str[1024] = "";
Now str has enough space for a kilobyte of data, or 1023 characters in addition to the terminator. The size is deliberately chosen to be much larger than the input you expect.
In addition to this, it would be a good idea to prevent scanf from writing past the end of the buffer by including the size in the format string. That is
scanf("%1023s", str); // now scanf will not read more than 1023 bytes plus sentinel.
...and in turn, it would be a good idea to increase the size of newstr accordingly (to twice that of str), i.e.
char newstr[2047]; // 2 * 1023 + terminator
...or, you know, make str smaller, depending on how long a string you want to support.
Thanks to Cool Guy for catching the superfluous & and newstr size implications.
"How does one successfully extract and manipulate a C string based on user input?"
You can use getchar() instead.
For example, you can store the user input in an array first. Then the problem becomes the same as if you did your 'char str[] = "Hello":
int index = 0
while((temp1 = getchar())!= '\n'){
str[index++] = temp1;
}
the following code
-complies cleanly
-checks and handles errors
-does the job
-doesn't use unneeded memory
(well actually) the logic could be a loop
that reads one char, outputs char, outputs space
or something similar if a trailing space is a problem
then the input buffer could be a single character
#include <stdio.h>
#include <stdlib.h> // exit, EXIT_FAILURE
#include <string.h>
int main()
{
// char str[] = "";
// there actually has to be room for the string
char str[100] = {'\0'};
printf("\nEnter a string: ");
if( 1 != scanf("%s", str) ) // arrays degenerate to pointer so no extra '&' needed
{ // then scanf failed
perror( "scanf failed" );
exit( EXIT_FAILURE );
}
// implied else, scanf successful
printf("\nYou typed: %s \n", str);
// there is no need to keep the modified string in memory
// when all that will be done is print it
int i = 0; // loop counter
printf("\nExpanded String: ");
for (i = 0; i < strlen(str); i++)
{
printf("%c", str[i]);
if( i < (strlen(str)-1) )
{ // then another char will follow
printf( " " );
}
else
{
printf( "\n" );
} // end if
} // end for
return 0;
} // end function: main

c, delete words which contain digits from a string

I need to delete all words that contain digits from the string.
E.g. if input is abdgh 67fgh 32ghj hj dfg43 11 fg, output should be abdgh hj fg.
I thought of using while( text[i] != ' '), but I don't know how to continue it for the rest of the string (after the first whitespace).
I don't have any other idea, and couldn't find anything by googling. Please, help me!
Here, i gave it a try. Works just fine for me. I tried to explain the logic throughout the code via comments. Hope it helps.
#include <stdio.h>
#include <string.h>
int containsNum(char * str);
int main()
{
char str[] = "abdgh 67fgh 32ghj hj dfg43 11 fg"; // input string
char newstr[100] = ""; //new string to create with filtered data
char * pch; //temp string to use in strtok
printf("given string : %s\n",str );
pch = strtok (str," ");
while (pch != NULL)
{
if(!containsNum(pch))// creation of new string with strcat
{ // if the current word not contains any number
strcat(newstr,pch);
strcat(newstr," "); //adding a space between words for readability
}
pch = strtok (NULL, " ");
}
printf("modified string : %s\n", newstr );
return 0;
}
//function containsNum
//gets a string and checks if it has any numbers in it
//returns 1 if so , 0 otherwise
int containsNum(char * str)
{
int i,
size =strlen(str),
flag=0;
for(i=0; i<size ; ++i)
{
if((int)str[i] >=48 && (int)str[i] <=57 ){
flag =1;
break;
}
}
return flag;
}
Regards
Algorithm:
1-You will have to break your input string into smaller components which are also called as tokens. For example: for the string abdgh 67fgh 32ghj hj dfg43 11 fg the tokens could be abdgh, 67fgh, 32ghj, hj, dfg43, 11 and fg.
2- These smaller strings or tokens can be formed using the strtok function which is defined as
char * strtok ( char * str, const char * delimiters );. Thestr in the first argument is the input sting which in the code presented below is string1. The second argument called the delimiters is what actually defines when to divide the input string into smaller pieces(tokens).
For instance, a whitespace as a delimiter will divide the input string whenever a whitespace is encountered, which is how the string is being divided in the code.
3-Since, your program needs to delete those words in the input string which contain digits we can use the isdigit() function to check exactly that.
WORKING CODE:
#include <cstring>
#include <ctype.h>
#include<stdio.h>
int main ()
{
char output[100]="";
int counter;
int check=0; /* An integer variable which takes the value of "1" whenever a digit
is encountered in one of the smaller strings or tokens.
So, whenever check is 1 for any of the tokens that token is to be ignored, that is,
not shown in the output string.*/
char string1[] = "abdgh 67fgh 32ghj hj dfg43 11 fg";
char delimiters[] = " ";//A whitespace character functions as a delimiter in the program
char * token;//Tokens are the sub-strings or the smaller strings which are part of the input string.
token=strtok(string1,delimiters);/*The first strktok call forms the first token/substring which for the input
given would be abdgh*/
while(token!=NULL)/*For the last substring(token) the strtok function call will return a NULL pointer, which
also indicates the last of the tokens(substrings) that can be formed for a given input string.
The while loop finishes when the NULL pointer is encountered.*/
{
for(counter=0;counter<=strlen(token)-1;counter++)/*This for loop iterates through each token element.
Example: In case of abdgh, it will first check for 'a',
then 'b', then 'd' and so on..*/
{
if(isdigit((int)token[counter])>0)/*This is to check if a digit has been encountered inside a token(substring).
If a digit is encountered we make check equal to 1 and break our loop, as
then that token is to be ignored and there is no real need to iterate
through the rest of the elements of the token*/
{
check=1;
break;
}
}
if(check==1) /* Outside the for loop, if check is equal to one that means we have to ignore that token and
it is not to be made a part of the output string. So we just concatenate(join) an
empty string ( represented by " " )with the output string*/
{
strcat(output,"");
check=0;
}
else /*If a token does not contain any digit we simply make it a part of the output string
by concatenating(joining) it with the output string. We also add a space for clarity.*/
{
strcat(output,token);
strcat(output," ");
}
token = strtok( NULL, delimiters ); /*This line of code forms a new token(substring) every time it is executed
inside the while loop*/
}
printf( "Output string is:: %s\n", output ); //Prints the final result
return 0;
}
#include <stdio.h>
#include <ctype.h>
#include <stdbool.h>
char *filter(char *str){
char *p, *r;
p = r = str;
while(*r){
char *prefetch = r;
bool contain_digit = false;
while(!isspace(*prefetch) && *prefetch){
if(contain_digit)
++prefetch;
else if(isdigit(*prefetch++))
contain_digit = true;
}
if(contain_digit){
r = prefetch;
}else {
while(r < prefetch){
*p++ = *r++;
}
}
if(!*r)
break;
if(p[-1] == *r)
++r;
else
*p++ =*r++;
}
*p = '\0';
return str;
}
int main(void) {
char text[] = "abdgh 67fgh 32ghj hj dfg43 11 fg";
printf("%s\n", filter(text));//abdgh hj fg
return 0;
}

Resources