break a string into 'first' and 'second' - c

I have read through countless strtok posts, even copied some directly in their entirety into a new int main, but I can't figure out how to create the functions get_first and get_second.
get_first("This is a sentence."); //returns "This"
get_rest("This is a sentence."); //returns "is"
This is what I have so far, I have had nothing but trouble with strtok, but I don't know what else to use.
#include <stdio.h>
#include <string.h>
char * get_first(char * string) {
string = strtok(string, " ");
return string;
}
char * get_second(char * string) {
string = strtok(string, " ");
string = strtok(NULL, " ");
return string;
}
int main(int argc, char * argv[]) {
char * test_string = "This is a sentence.";
char * first = get_first(test_string);
char * second = get_second(test_string);
printf("%s\n", first);
printf("%s\n", second);
}
Getting no faults compiling with gcc -g -Wall, but it always seg faults. I think I have tried every permutation of char c[] and char * c there is.

strtok changes the string. (but String literals are not allowed to change.)
So create a copy.
Do the following:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
char * get_first(const char *string){
char *clone = strdup(string);//create copy, strdup is non standard. malloc and copy.
char *token = strtok(clone, " ");
if(token)
token = strdup(token);
free(clone);
return token;
}
char * get_second(const char *string) {
char *clone = strdup(string);
char *token = strtok(clone, " ");
if(token && (token = strtok(NULL, " ")))
token = strdup(token);
free(clone);
return token;
}
int main(void) {
char * test_string = "This is a sentence.";
char * first = get_first(test_string);
char * second = get_second(test_string);
printf("%s\n", first);
printf("%s\n", second);
free(first);
free(second);
}

Related

Segmentation error when convert string to array of strings in c

I want to convert a string to an array of strings and I get an error
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main(int argc, char **argv)
{
int count = 0;
char *str = argv[1];
char *token, *last;
char **arr_str = calloc(9999, sizeof(char*));
token = strtok_r(str, " ,", &last);
arr_str[count] = strcpy(calloc(strlen(token), sizeof(char)), token);
while (token != NULL) {
count++;
token = strtok_r(NULL, " ", &last);
arr_str[count] = strcpy(calloc(strlen(token), sizeof(char)), token);
printf("%s", arr_str[count - 1]);
}
printf("------------");
while(arr_str[count])
printf("%s", arr_str[count--]);
exit (0);
}
how to allocate memory for a string and make a pointer to it from an array?
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main(int argc, char **argv)
{
/* always check argument count */
if(argc < 2) {
printf("Not enough arguments given\n");
return 1;
}
int count = 0;
char *str = malloc(strlen(argv[1] + 5));
memcpy(str, argv[1], strlen(argv[1]));
char *token, *last;
char **arr_str = calloc(9999, sizeof(char*));
token = strtok_r(str, " ,", &last);
while ((token = strtok_r(NULL, " ", &last)) != NULL) {
count++;
/* sizeof(char) is always 1 and is redundant unless you are on
a obscure platform that it returns other than 1
which shouldnt exist in modern world
*/
arr_str[count] = malloc(strlen(token) + 1);
strcpy(arr_str[count], token);
}
printf("------------");
while(arr_str[count])
printf("%s", arr_str[count--]);
exit (0);
}
strtok is destructive meaning it edits strings it encounters, it tried to edit argv which resulted in a segmentation error.
I also edited code to follow better practices and edited formatting.
You need memory for elements of the arr_str.
calloc(9999) while not great if this not going to end up in a serious application it's not a issue.
sizeof(char) should always return 1 on a normal modern system unless you are on extremely obscure system
Use puts(char* s) if you don't need string formatting.
You should do input validation.

"incompatible type for argument 1 of ‘strcpy’" error in C

I am writing a program where I must define my own versions of the following functions:
int AtoI ( const char * str );
int StrCmp ( const char * str1, const char * str2 );
char * StrCpy ( char * destination, const char * source );
char * StrCat ( char * destination, const char * source );
char * StrChr ( char * str, int character );
Inside the main function, I am required to declare an array called wordlist of type myWord of size 20. Then, using the strtok() library function, extract each word from the string MyString and store it in wordlist. However, I keep getting the error message:
incompatible type for argument 1 of ‘strcpy’
for the line:
strcpy(wordlist[i], token);
How do I fix this problem? So far, this is what I have:
#include <stdio.h>
#include <string.h>
struct myWord{
char word[21];
int length;
};
int main(void){
typedef struct myWord myword;
int i = 0;
myword wordlist[20];
char *myString = "the cat in the hat jumped over the lazy fox";
char *token;
token = strtok(myString, " ");
while(myString != NULL){
strcpy(wordlist[i], token);
token = strtok(NULL, " ");
printf("%s\n", wordlist[i]);
i++;
}
}
The corrected code is
#include <stdio.h>
#include <string.h>
typedef struct myWord{
char word[21];
int length;
}myword;
int main(void){
int i = 0;
myword wordlist[20];
char myString[] = "the cat in the hat jumped over the lazy fox";
char *token;
token = strtok(myString, " ");
while(token != NULL){
strcpy(wordlist[i].word, token);
token = strtok(NULL, " ");
printf("%s\n", wordlist[i].word);
i++;
}
}
C-string member of your struct is word, so you must pass that member to strcpy and printf
Your loop must check token returned by strtok to check if the end of string was reached
strtok modify your string to do the job, so the string must be modifiable, you cannot use a pointer to a string literal.

issue to extract token from sub token using strtok() function in c

Have written following code in c
#include "stdio.h"
#include "string.h"
int main()
{
char str[] = "gatway=10.253.1.0,netmask=255.255.0.0,subnet=10.253.0.0,dns=10.253.0.203";
char name[100],value[100];
char *token1,*token2;
char *commasp = ", ";
char *equ="=";
token1 = strtok(str,commasp);
while(token1 != NULL)
{
token2 = strtok(token1,equ);
sprintf(name,"%s",token2);
token2 = strtok(NULL,commasp);
sprintf(value,"%s",token2);
printf("Name:%s Value:%s\n",name,value);
token1 = strtok(NULL,commasp);
}
return 0;
}
My problem is i got only one printf like Name:gatway Value:10.253.1.0. i know last strtok() in while loop followed by previous strok() which turns to null so token1 get null value and break the loop. Have think solution for it to not use strtok() in while loop for sub token (getting name and value) and use other method to extract name and value but it seems to lengthy code(using for or while loop for character match).So any one have batter solution to packup code in single loop.
You could use strtok_r instead of strtok.
char *key_value;
char *key_value_s;
key_value = strtok_r(str, ",", &key_value_s);
while (key_value) {
char *key, *value, *s;
key = strtok_r(key_value, "=", &s);
value = strtok_r(NULL, "=", &s);
printf("%s equals %s\n", key, value);
key_value = strtok_r(NULL, ",", &key_value_s);
}
gatway equals 10.253.1.0
netmask equals 255.255.0.0
subnet equals 10.253.0.0
dns equals 10.253.0.203
Frankly though I think it would be easier to just look for , and when you find one look for = backwards.
You can do this in two steps, first parse the main string:
#include <stdio.h>
#include <string.h>
int main()
{
char str[] = "gatway=10.253.1.0,netmask=255.255.0.0,subnet=10.253.0.0,dns=10.253.0.203";
char name[100],value[100];
char *commasp = ", ";
char *ptr[256], **t = ptr, *s = str;
*t = strtok(str, commasp);
while (*t) {
t++;
*t = strtok(0, commasp);
}
for (t = ptr; *t; t++) {
printf("%s\n", *t);
// now do strtok for '=' ...
}
return 0;
}
Then parse individual pairs as before.
The above results in:
gatway=10.253.1.0
netmask=255.255.0.0
subnet=10.253.0.0
dns=10.253.0.203

Taking apart strings in C

I have a string that includes two names and a comma how can i take them apart nd write them to seperate strings.
Example
char *line="John Smith,Jane Smith";
I am thinking of using sscanf function.
sscanf(line,"%s,%s",str1,str2);
What should i do?
note: I can change comma to space character.
I am thinking of using sscanf function.
Don't even think about it.
char line[] = "John Smith,Jane Smith";
char *comma = strchr(line, ',');
*comma = 0;
char *firstName = line;
char *secondName = comma + 1;
Here's how you could do it using strtok:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
// Your string.
char *line = "John Smith,10,Jane Smith";
// Let's work with a copy of your string.
char *line_copy = malloc(1 + strlen(line));
strcpy(line_copy, line);
// Get the first person.
char *pointer = strtok(line_copy, ",");
char *first = malloc(1 + strlen(pointer));
strcpy(first, pointer);
// Skip the number.
strtok(NULL, ",");
// Get the second person.
pointer = strtok(NULL, ",");
char *second = malloc(1 + strlen(pointer));
strcpy(second, pointer);
// Print.
printf("%s\n%s", first, second);
return 0;
}

insert strtok results into char* (increased dynamic)

I'm loosing my mind.
I want to split string (char* text) with spaces and insert the string results into array and return this array.
I have the following method in C
char *read_command(char *text)
{
int index=0;
char *res=NULL;
char *command= (char*)malloc(strlen(text)+1);
strcpy(command, text);
char *tok = strtok(command, " ");
while(tok!=NULL && index ==0)
{
res = (char*)realloc(res, sizeof(char)*(index+1));
char *dup = (char*)malloc(strlen(tok)+1);
strcpy(dup, tok);
res[index++] = dup; //Error here
tok = strtok(NULL, " ");
}
res[index++]='\0';
return res;
}
from main method
char *input="read A B C";
char *command = read_command(input);
Thank you
You are using a wrong type to calculate the size in this call:
res = realloc(res, sizeof(char)*(index+1));
You need to use char*, not char, with sizeof, like this:
res = realloc(res, sizeof(char*)*(index+1));
Since your code returns a pointer to C strings (represented as char*) the return type should be char**.
You need to remove the index == 0 condition from the while loop, otherwise it wouldn't go past the initial iteration.
This assignment
res[index++]='\0';
should be
res[index++]=NULL;
You also need to call free(command) before returning the results to the caller. Finally, you should not cast results of malloc in C.
Here is your code after the fixes above:
char **read_command(char *text) {
int index=0;
char **res=NULL;
char *command= malloc(strlen(text)+1);
strcpy(command, text);
char *tok = strtok(command, " ");
while(tok!=NULL) {
res = realloc(res, sizeof(char*)*(index+1));
char *dup = malloc(strlen(tok)+1);
strcpy(dup, tok);
res[index++] = dup;
tok = strtok(NULL, " ");
}
// Need space to store the "terminating" NULL
// Thanks, BLUEPIXY, for pointing this out.
res = realloc(res, sizeof(char*)*(index+1));
res[index]=NULL;
free(command);
return res;
}
Demo on ideone.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char **read_command(const char *text){
int index=0;
char **res=NULL;
char *command= malloc(strlen(text)+1);
strcpy(command, text+strspn(text, " \t\n"));//strspn for skip space from top
char *tok = strtok(command, " ");
res = realloc(res, sizeof(char*)*(index+1));
while(tok!=NULL){
res[index++] = tok;
res = realloc(res, sizeof(char*)*(index+1));
tok = strtok(NULL, " ");
}
res[index++]=NULL;
return res;
}
int main(void){
char *input="read A B C";
char **command = read_command(input);
int i;
for(i=0;command[i]!=NULL;++i){
printf("s[%d]=%s\n", i, command[i]);
}
free(command[0]);//for free command of read_command
free(command);//for free res of read_command,,
return 0;
}

Resources