How do I split a string in function in C? [duplicate] - c

This question already has answers here:
C's strtok() and read only string literals
(5 answers)
Closed 3 years ago.
I need a function that split a string in c, i write the code and I checked it, I didn't get any errors or warnings, the code is :
int main()
{
cutString("any#any#any5") ;
return 0;
}
void cutString(char query[2000]) {
char * cut ;
cut = strtok(query , "#") ;
printf("%s" , cut);
}
But when I compile the program the compiler get stuck, without showing any output.
This is a picture for run screen.

Pay attention to the usage of strtok(). According to the Linux Man Page, on the first invocation of the function, you should specify the string to parse as first argument, while in each subsequent call you should specify NULL.
In fact, a sequence of calls on the same string maintains a pointer to the next character to process. If you want to check if no more tokens are found, just look at the return value (it'd be NULL in that case).

First of all you should read about the usage of strtok()
Please keep in mind you can't use strtok() on a string literal, since it will attempt to modify it which will cause undefined behavior.
#include <stdio.h>
#include <string.h>
int main()
{
char toCut[100] = "to#cut#this";
cutString(toCut);
return 0;
}
void cutString(char* query) {
char* cut ;
cut = strtok(query, "#"); // this first call returns a pointer to the first substring
while(cut != NULL)
{
printf("%s\n", cut);
cut = strtok(NULL, "#"); // each call to strtok returns a pointer to the next substring
}
}

Related

Character Pointer Arithmetic in Main vs In Other Functions [duplicate]

This question already has answers here:
How do I modify a pointer that has been passed into a function in C?
(7 answers)
C - modify the address of a pointer passed to a function
(6 answers)
Closed 5 years ago.
I am working on a practice problem that asks me to remove the first character in a string. Ex. char *string = "Rudolph", after calling removeFirst(string), string now equals "udolph".
I noticed, if I do it all in my main, I get the output "udolph". Here is my code:
int main() {
char *string = "Rudolph";
printf("%s\n", string);
//removeFirst(string);
string++;
printf("%s\n", string);
return 0;
}
However, if I were to call another function, my output is Rudolph. Here again is my code:
void removeFirst(char *string) {
if (string == "" | string == NULL)
return;
string++;
}
int main() {
char *string = "Rudolph";
printf("%s\n", string);
removeFirst(string);
//string++;
printf("%s\n", string);
return 0;
}
Given that I'm working with pointers, I thought that the changes I make in removeFirst should also make it to main. Why doesn't it work that way?
You are changing to the local variable. C is pass by value. A char* with same value as that of string is there in the called function removeFirst(). You make changes to it and then you expect the changes made on the copy to be reflected in the original variable. That's not going to happen here. That's why you don't get the same result as before case.
string == "" comparing two addresses not the content as you may have expected.
You can make changes like this
removeFirst(&string);
void removeFirst(char **string) {
if (*string == NULL)
exit(1);
(*string)++;
}
Then in main()
printf("%s\n", string); outputs udolph.
In this is case you pass the address of the pointer variable. You are now changing to the original variable by accessing the memory contained in the called function's local variable string. That is what retain the changes in main().

String Token strtok function logic

I am learning string manipulation with C Standard Functions. When I am learning this stuff, I am facing with strtok function and the following code.
#include <string.h>
#include <stdio.h>
int main()
{
char str[80] = "This is - www.tutorialspoint.com - website";
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 );
token = strtok(NULL, s);
}
return(0);
}
I don't understand why in while loop, strtok used with null? Why null used here? Because in strtok function definition comes something like (this function breaks first paramter string into a series of tokens using the second paramter of itself.)
Because it uses an internal static pointer to the string you are working with, so if you want it to operate on the same string, you just need to call it with NULL as the first argument and let it use it's internal pointer. If you call it with non-null first argument then it will overwrite the pointer with the new pointer.
This means in turn, that strtok() is not reentrant. So you normally just use it in simple situations, more complex situations where reentrance is important (like multithreaded programs, or working on multiple strings) require different approaches.
One way is on POSIX systems where you can use strtok_r() which takes one extra argument to use as it's "internal" pointer.
Check this manual to learn about it more.
strtok uses an internal (static) state to tokenize a string. When called with NULL, it goes to the next token in the string that was passed in the first call.
It is worth mentioning, that this property (internal state) makes it unsafe to use in multi-threaded environment. A safer version is strtok_r, which return the state as an output parameter.
The first call you use a char array which has the elements you want parsed.
The second time you call it you pass it NULL as the first parameter to tell function to resume from the last spot in the string. Once the first call is made your char array receives the parsed string. If you don't put NULL you would lose your place and effectively the last part of your string.
char * c_Ptr = NULL; //temp hold indivisual sections
char c_Ptr1[1000] = {NULL};
fgets(c_Ptr1, 1000, f_ptr); //Grabs a line from an open file
strtok(c_Ptr1, ","); //first one starts at the beginning
c_Ptr = strtok(NULL, ",");

C Unexpected string returned from function behaviour [duplicate]

This question already has answers here:
returning a local variable from function in C [duplicate]
(4 answers)
Closed 7 years ago.
I am quite new to C and I am playing with some string operations. I have encountered quite a strange problem for me while returning a string from a function. My simple program is as follows:
int main(int argc, char* argv[])
{
char text[] = "abAB";
char* out = testString(text);
printf("Result Text: %s", out);
printf("\n");
}
char* testString(char* input) {
char* text = copyString(input);
return text;
}
The copyString function defines a simple operation to copy one string to another. It is as follows:
char* copyString(char* input) {
char output[100];
int index = 0;
while (input[index] != '\0') {
output[index] = input[index];
index++;
}
output[index] = '\0';
return output;
}
The problem is that while I am debugging the application, the string I am returning from a function seems to be OK (Visual Studio visualises it well enough) and when the printf line occurs, the string outputted on the stdout is something completely strange and unfamiliar - a smily face. Sadly, I can't post images yet in order to show you what I see in my console as output.
I am using Visual C++ Express 2010 as an IDE if this could be helpful.
You are returning a variable declared within a function, which will cease to exist outside the scope in which it is declared. Use a dynamically allocated char array and then return a pointer to it.
char* output = malloc(100 * sizeof(char));
...
return output ;
Note : You are assuming that input string is less than 100 characters. Instead of that, try passing the length of string as a parameter or use strlen. Your program will crash if input string has more than 99 characters.
Also as noted in comments, free the memory allocated when you are done using it.

C String parsing errors with strtok(),strcasecmp()

So I'm new to C and the whole string manipulation thing, but I can't seem to get strtok() to work. It seems everywhere everyone has the same template for strtok being:
char* tok = strtok(source,delim);
do
{
{code}
tok=strtok(NULL,delim);
}while(tok!=NULL);
So I try to do this with the delimiter being the space key, and it seems that strtok() no only reads NULL after the first run (the first entry into the while/do-while) no matter how big the string, but it also seems to wreck the source, turning the source string into the same thing as tok.
Here is a snippet of my code:
char* str;
scanf("%ms",&str);
char* copy = malloc(sizeof(str));
strcpy(copy,str);
char* tok = strtok(copy," ");
if(strcasecmp(tok,"insert"))
{
printf(str);
printf(copy);
printf(tok);
}
Then, here is some output for the input "insert a b c d e f g"
aaabbbcccdddeeefffggg
"Insert" seems to disappear completely, which I think is the fault of strcasecmp(). Also, I would like to note that I realize strcasecmp() seems to all-lower-case my source string, and I do not mind. Anyhoo, input "insert insert insert" yields absolutely nothing in output. It's as if those functions just eat up the word "insert" no matter how many times it is present. I may* end up just using some of the C functions that read the string char by char but I would like to avoid this if possible. Thanks a million guys, i appreciate the help.
With the second snippet of code you have five problems: The first is that your format for the scanf function is non-standard, what's the 'm' supposed to do? (See e.g. here for a good reference of the standard function.)
The second problem is that you use the address-of operator on a pointer, which means that you pass a pointer to a pointer to a char (e.g. char**) to the scanf function. As you know, the scanf function want its arguments as pointers, but since strings (either in pointer to character form, or array form) already are pointer you don't have to use the address-of operator for string arguments.
The third problem, once you fix the previous problem, is that the pointer str is uninitialized. You have to remember that uninitialized local variables are truly uninitialized, and their values are indeterminate. In reality, it means that their values will be seemingly random. So str will point to some "random" memory.
The fourth problem is with the malloc call, where you use the sizeof operator on a pointer. This will return the size of the pointer and not what it points to.
The fifth problem, is that when you do strtok on the pointer copy the contents of the memory pointed to by copy is uninitialized. You allocate memory for it (typically 4 or 8 bytes depending on you're on a 32 or 64 bit platform, see the fourth problem) but you never initialize it.
So, five problems in only four lines of code. That's pretty good! ;)
It looks like you're trying to print space delimited tokens following the word "insert" 3 times. Does this do what you want?
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main(int argc, char **argv)
{
char str[BUFSIZ] = {0};
char *copy;
char *tok;
int i;
// safely read a string and chop off any trailing newline
if(fgets(str, sizeof(str), stdin)) {
int n = strlen(str);
if(n && str[n-1] == '\n')
str[n-1] = '\0';
}
// copy the string so we can trash it with strtok
copy = strdup(str);
// look for the first space-delimited token
tok = strtok(copy, " ");
// check that we found a token and that it is equal to "insert"
if(tok && strcasecmp(tok, "insert") == 0) {
// iterate over all remaining space-delimited tokens
while((tok = strtok(NULL, " "))) {
// print the token 3 times
for(i = 0; i < 3; i++) {
fputs(tok, stdout);
}
}
putchar('\n');
}
free(copy);
return 0;
}

conditions after using strtok()

I'm new to C and i would like to learn something that is troubling me.
I have a code where i used strtok and basically it gets a string with the _#_ and seperates it from the string leaving the rest into chars and ints(i used atoi for that)
The program runs fine when i enter something like that: hello_#_2001_#_name_#_HARRY it gives me back hello,2001,name and HARRY. But when I input only hello_#_ it continues to run though stops doing anything. I think i need to assign a certain pointer to the first NULL but not sure if what i think is correct could you please help?
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char *split(char words[99])
{
int i;
char *word=strtok(words, "_#_");
char *year=strtok(NULL, "_#_");; // assigning NULL for previousely where it left off
char *definition=strtok(NULL,"_#_");
char *synonyms=strtok(NULL,"_#_");
i=atoi(year);
printf("%s\n", word);
printf("%i\n",i);
printf("%s\n", definition);
printf("%s\n", synonyms);
return 0;
}
int main()
{
char words[100];
printf("Enter a string\n");
scanf("%s", words);
split(words);
}
When I run your program and enter the string hello_#_, it throws a segfault when atoi is called. This is expected since year, definition, and synonyms will all be NULL. So you should check year for a NULL value before calling atoi.
From the man page:
The strtok() and strtok_r() functions return a pointer to the beginning of each subsequent token in the string, after replacing the token itself with a NUL character. When no more tokens remain, a null pointer is returned.
Try checking if the return value of strtok() is NULL before continuing.
You need to do some error checking. If you run out of tokens, strtok returns NULL, and then if you try to actually do something with that non-existing string (like pass it to atoi or try to print it) Bad Things will happen. It's up to you to decide what your function should do in that case (abort? Print what it can?) but you'll have to do something.

Resources