How to use strtok to get a word - c

I'm having some problem with my code. I need to use strtok() in c to output the words "Sing" and "Toy" (which are both in between the words "Due" and "De") in the string "Date WEEk Dae Due Toy De Dae i Date Due Sing De". I tried to use the if statement found in the code to explicitly output the words "Sing" and "Toy" but my code would not produce any output and it had no warnings during compilation. I'm only a beginner at C so please be patient with me. I heard that other functions such as strstr() might be able to do the same job as strtok() so if those other functions are much more convenient to use, do not hesitate to use those functions instead. Thank you.
Summary: I'm trying to get the words in between "Due" and "De" in the string above using strtok() and is it possible to do so or should I use another function?
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(){
char string[]="Date WEEk Dae Due Toy De Dae i Date Due Sing De";
char*pch;
pch=strtok(string,"De");
while(pch!=NULL){
if((*(pch-1)=='a')&&(*(pch-2)=='u'))
printf("%s\n",pch);
pch=strtok(NULL,"De");
}
return 0;
}

Keep in mind that the second parameter of strtok() is a delimeter list:
C string containing the delimiter characters.
These can be different from one call to another.
They way it's now in your code, the token will be taken after each capital D and lower case e.
For the case mentioned in your description, it's more suitable to workaround the problem using strstr().

you should pass " " as second argument to strtok
If you want to print Sing, check if pch is not null and strcmp(pch,"Sing") == 0 then print Sing

Find "Due" followed by a space
char *due = strstr(string, "Due ");
Find "De" preceded by a space
char *de = strstr(string, " De");
Check for errors
if (!due || !de) exit(EXIT_FAILURE);
Print what is between
printf("%.*s\n", (int)(de - due - 4), due + 4);

Use strstr like this
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
int main(void){
char string[]="Date WEEk Dae Due Toy De Dae i Date Due Sing De";
char *pre_word = "Due", *post_word = "De";
size_t pre_word_len = strlen(pre_word), post_word_len = strlen(post_word);
char *p = string, *pre, *post;
while(pre = strstr(p, pre_word)){//find pre word
if((pre == string || isspace((unsigned char)pre[-1])) &&
isspace((unsigned char)pre[pre_word_len])){//word check
if(post = strstr(pre + pre_word_len, post_word)){//find post word
if(isspace((unsigned char)post[-1]) &&
(isspace((unsigned char)post[post_word_len]) || !post[post_word_len])){//word check
*post = 0;//The original string is changed
char word[32], dummy[2];
if(1==sscanf(pre + pre_word_len, "%31s %1s", word, dummy)){//There is one word between words
printf("'%s'\n", word);
}
}
p = post + post_word_len;//set next search position
} else {
break;//Since post_word does not exist, it ends loop.
}
}
}
return 0;
}

Related

Is there a way to extract a comment out of a C string?

I'm trying to write a function that extracts the comment out of a string. For example, given:
"this is a test //bread is great"
it returns:
"bread is great"
I've tried to count the characters until the first '//' appears and then trim the unwanted part of the string.
while(s[i] != '/' && s[i+1] != '/') {
newbase++;
i++;
}
It worked for the first example but I'm having issues if I'm given a string like this:
"int test = 2/3"
It should return "" (an empty string) but it doesn't. I don't understand it.
This is very basic string handling. Simply use strstr and if successful, use the result. Optionally copy it to a second string.
#include <stdio.h>
#include <string.h>
int main (void)
{
const char* str = "this is a test //bread is great";
const char* result = strstr(str,"//");
if(result != NULL)
{
result += 2; // skip the // characters
puts(result); // print the string
// optionally make a hardcopy
char some_other_str[128];
strcpy(some_other_str, result);
puts(some_other_str);
}
}
If you just want to extract naively the remaining string after the first occurence of "//" you probably need something like this:
#include <stdio.h>
#include <string.h>
int main()
{
const char *text = "this is a test //bread is great";
const char* commentstart = strstr(text, "//");
char comment[100] = { 0 }; // naively assume comments are shorter then 99 chars
if (commentstart != NULL)
{
strcpy(comment, commentstart + 2);
}
printf("Comment = \"%s\"", comment);
}
Disclaimers:
This is untested simple code that shows a possible approach. There is no error checking whatsoever, especially if the comment is longer than 99 chars, there will be a buffer overflow.
This code is absolutely not suitable for extracting comments from real life C code.

copying an substring to string

i'm trying to get a 2 strings from the user and the second one will be the "needle" to copy to the first string
for example:
string 1 (user input): eight height freight
string 2 (user input): eight
output: EIGHT hEIGHT frEIGHT
for example i want to print: toDAY is a good DAY
having trouble copying multiple needles in stack
i have tried using while (*str) {rest of the function with str++}
i would love some explanation
#define _CRT_SECURE_NO_WARNINGS
#define N 101
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <conio.h>
void replaceSubstring(char* str, char* substr);
void main() {
int flag = 1;
char str[N], substr[N];
//char* str_ptr = &str, * substr_ptr = &substr; //creating pointer for the sake of while
while (flag) {
printf("\nEnter main text: ");
gets_s(str,N);
if (!str)
flag = 0;
printf("\nEnter sub-text: ");
gets_s(substr,N);
if (!str)
flag = 0;
replaceSubstring(str, substr);
printf("%s",str);
}
printf("\nExited. (press any key to exit)");
}
void replaceSubstring(char* str, char* substr) {
int lensbstr;
str = strstr(str, substr);
_strupr(substr); //cnvrt to UPPERCASE
lensbstr = strlen(substr); //length of the mutual string
if (str)
strncpy(str, substr, lensbstr);
}
This looks like a programming exercise, so I’m not going to just give you the answer. However, I’ll give you a few hints.
Two big problems:
You don’t have a loop that would replace the second and later instances.
You are upper-casing the substring... not a copy of the substring. A second pass through replaceSubstring would only match the upper-case version of the substring.
A couple of small problems / style comments:
str is an array, so its value is always non-zero, so “if(!str)” is never true.
strncpy is almost never the right answer. It will work here, but you shouldn’t get in the habit of using it. Its behavior is subtle and is rarely what you want. Here it would be faster and more obvious to use memcpy.
You are upper-casing the substring and measuring its length even if you didn’t find it and so won’t need those results.
Although using int for flags works and is the traditional way, newer versions of the language have stdbool.h, the “bool” type, and the “true” and “false” constants. Using those is almost always better.
You appear to intend to stop when the user enters an empty string for the first string. So why do you ask for the second string in that case? It seems like you want an infinite loop and a “break” in the middle.

String manipulation in C (replace & insert characters)

I am very new in C, I have little idea about sprintf but I can't fulfill my requirement.
I have a char * variable which contains string like below :
date=2013-12-09 time=07:31:10 d_id=device1 logid=01 user=user1 lip=1.1.1.1 mac=00:11:22:33:44:55 cip=2.2.2.2 dip=3.3.3.3 proto=AA sport=22 dport=11 in_1=eth1 out_1=
I want an output as
2013-12-09#07:31:10#device1#01#user1#1.1.1.1#00:11:22:33:44:55#2.2.2.2#3.3.3.3#AA#22#11#eth1##
if some value is null after = it should print ## in sequence.
I am not going to give you exact code but I will give you some links that will help you.
strchr :: You can use this find the position of '=' in the string.
Now, copy the string after the position of '=' till you find a 'space'.
Whenever you will find a 'space', write a '#' in the buffer.
Keep doing this, till you encounter a '\0'. Write '##' to buffer when you have encountered '\0'
Append that with a '\0'.
Ex:: C function strchr - How to calculate the position of the character?
example by use strtok, strchr, sprintf
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(){
const char *data = "date=2013-12-09 time=07:31:10 d_id=device1 logid=01 user=user1 lip=1.1.1.1 mac=00:11:22:33:44:55 cip=2.2.2.2 dip=3.3.3.3 proto=AA sport=22 dport=11 in_1=eth1 out_1=";
char *work = strdup(data);//make copy for work
char *output = strdup(data);//allocate for output
char *assignment; //tokenize to aaa=vvv
size_t o_count = 0;//output number of character count
for(assignment=strtok(work, " "); assignment ;assignment=strtok(NULL, " ")){
o_count += sprintf(output + o_count, "%s#", strchr(assignment, '=')+1);
}
printf("%s", output);
free(work);
free(output);
return 0;
}

How can i filter a string so only alphanumeric characters are allowed through

I am currently working on a log parsing script for a server, and to prevent users from inputting malicious commands, I need to filter out all characters except for alphanumeric characters (while allowing underscores) from the inputted string, although unfortunately I do not know how to do this, so I was just wondering if someone could tell/show me what to do in order to achieve this, thanks! also as an example, say someone inputs the following: stack##_over%flow, the program would then filter out the non-alphanumeric characters (except for underscores) in order to produce just stack_overflow, the equivalent of this in bash would be
tr -dc [:alnum:]'_'
also forgot to mention that I have tried the following, but still encounter some issues (for instance if a "!" is included in the string, i get "-bash: !": event not found"
#include <stdio.h>
#include <string.h>
#include <ctype.h>
int main(int argc, char ** argv) {
int i;
char *p;
if (argc > 1) {
for (p = argv[1]; *p != '\0'; p++) {
if (islower(*p) || isdigit(*p) || *p == '_') {
putchar (*p);
}
}
putchar ('\n');
}
return 0;
}
Find the length of the string you are processing, allocate a new string of that length, iterate over every character of the input string and if it is alpha numeric (using isalnum() from ctype.h) put the character in the resulting string, else just skip it. Null terminate and copy the resulting string to the input string, free the allocated string and return the result.
regular expressions(regex) are a great way to do this.
Here is an example to show this.

Tips on how to read last 'word' in a character array in C

Just looking to be pointed in the right direction:
Have standard input to a C program, I've taken each line in at a time and storing in a char[].
Now that I have the char[], how do I take the last word (just assuming separated by a space) and then convert to lowercase?
I've tried this but it just hangs the program:
while (sscanf(line, "%s", word) == 1)
printf("%s\n", word);
Taken what was suggested and came up with this, is there a more efficient way of doing this?
char* last = strrchr(line, ' ')+1;
while (*last != '\0'){
*last = tolower(*last);
putchar((int)*last);
last++;
}
If I had to do this, I'd probably start with strrchr. That should get you the beginning of the last word. From there it's a simple matter of walking through characters and converting to lower case. Oh, there is the minor detail that you'd have to delete any trailing space characters first.
The issue with your code is that it will repeatedly read the first word of the sentence into word. It will not move to the next word each time you call it. So if you have this as your code:
char * line = "this is a line of text";
Then every single time sscanf is called, it will load "this" into word. And since it read 1 word each time, sscanf will always return 1.
This will help:
char dest[10], source [] = "blah blah blah!" ;
int sum = 0 , index =0 ;
while(sscanf(source+(sum+=index),"%s%n",dest,&index)!=-1);
printf("%s\n",dest) ;
'strtok' will split the input string based on certain delimitors, in your case the delimitor would be a space, thus it will return an array of "words" and you would simply take the last one.
http://www.cplusplus.com/reference/clibrary/cstring/strtok/
One could illustrate many different methods of performing this operation and then determine which one contained the best performance and useability characteristics, or the advantages and disadvantages of each, I simply wanted to illustrate what I mentioned above with a code snippet.
#include <stdio.h>
#include <ctype.h>
#include <stdlib.h>
#include <string.h>
#include <conio.h>
int main()
{
char line[] = "This is a sentence with a last WoRd ";
char *lastWord = NULL;
char *token = strtok(line, " ");
while (token != NULL)
{
lastWord = token;
token = strtok(NULL, " ");
}
while (*lastWord)
{
printf("%c", tolower(*lastWord++));
}
_getch();
}

Resources