C: split string to string array with delimiter "&&" - c

I'm kinda new in C so i need help.
I need to split a string to string array with the delimiter "&&",
the thing is that i tried to use strtok, but when i use it, it looks like that the strtok can't handle correctly if the is '&' some where in the string.
I know that each part between the && is at max 256 chars and that there are at most 16 parts.
so i need to create an array arr[16][256] or an array of size 16*256.
in any case each time i try my code fail on the different between & and &&
example:
char arr[16][255];
char stringToSplit = "Hello World && How are u doing && more words & bla &";
output:
arr[0] = "Hello World ";
arr[1] = " How are u doing ";
arr[2] = " more words & bla &";
Thanks ahead!
This is what i tried:
int i;
char *p;
i = 0;
p = strtok (stringToSplit ,"&&");
while (p != NULL)
{
arr[i++] = p;
p = strtok (NULL, "&&");
}
for (i=0;i<16; ++i)
printf("%s\n", arr[i]);

strtok() splits the string on characters.
You need strstr() to find a string inside a string then copy the relevant characters to the destination. Keep doing this until the source string is exhausted.

A simple double nested loop will do. check for "&&" and watch out for long sub-strings and too many sub-strings.
void tubu13(void) {
#define NUM (16)
#define SIZ (255+1)
char arr[NUM][SIZ];
const char *stringToSplit = "Hello World && How are u doing && more words & bla &";
const char *p = stringToSplit;
int n, len;
for (n = 0; n < NUM; n++) {
for (len=0; len < SIZ-1; len++) {
if (p[0] == '\0') {
break;
}
if (p[0] == '&' && p[1] == '&') {
p += 2;
break;
}
arr[n][len] = *p;
p++;
}
arr[n][len] = '\0';
printf(" arr[%d] = \"%s\";\n", n, arr[n]);
}
}
arr[0] = "Hello World ";
arr[1] = " How are u doing ";
arr[2] = " more words & bla &";
arr[3] = "";
...
arr[15] = "";

#include <stdio.h>
#include <string.h>
char *strtokByWord_r(char *str, const char *word, char **store){
char *p, *ret;
if(str != NULL){
*store = str;
}
if(*store == NULL) return NULL;
p = strstr(ret=*store, word);
if(p){
*p='\0';
*store = p + strlen(word);
} else {
*store = NULL;
}
return ret;
}
char *strtokByWord(char *str, const char *word){
static char *store = NULL;
return strtokByWord_r(str, word, &store);
}
int main(){
char arr[16][255];
char stringToSplit[] = "Hello World && How are u doing && more words & bla &";
int i, n;
char *p;
i = 0;
p = strtokByWord(stringToSplit, "&&");
while (p != NULL){
strcpy(arr[i++], p);
p = strtokByWord(NULL, "&&");
}
n = i;
for (i=0;i<n; ++i)
printf("%s\n", arr[i]);
return 0;
}

Related

Removing char from string C

I'm learning C now
I need to make a program that remove char that I'll input from string. I've seen an algorithm and I write this code
#define MAX_LEN 200
int main()
{
char str[MAX_LEN];
char rem;
int i = 0;
printf("Enter the setence:");
gets(str);
printf("\nEnter the char to remove");
rem = getchar();
char* pDest = str;
char* pS= str;
printf("sent:\n%s", str);
while (str[i]!='\0'){
if (*pDest != rem) {
*pDest = *pS;
pDest++;
pS++;
}
else if (*pDest == rem) {
pS++;
}
i++;
}
*pDest = '\0';
while (str[i] != '\0') {
printf("number%d", i);
putchar(str[i]);
printf("\n");
i++;
}
}
But it returns nothing, like the value str gets, i think \0 and retuns nothing.
May you help me to find the problem?
Use functions!!
If dest is NULL then this function will modify the string str otherwise, it will place the string with removed ch in dest.
It returns reference to the string with removed character.
char *removeChar(char *dest, char *str, const char ch)
{
char *head = dest ? dest : str, *tail = str;
if(str)
{
while(*tail)
{
if(*tail == ch) tail++;
else *head++ = *tail++;
}
*head = 0;
}
return dest ? dest : str;
}
int main(void)
{
char str[] = "ssHeslsslsos sWossrlssd!ss";
printf("Removal of 's' : `%s`\n", removeChar(NULL, str, 's'));
}
It would be easier to use array style indexing to go through the string. For example use str[i] = str[i + 1] instead of *pstr = *other_pstr. I leave this incomplete method, since this looks like homework.
int main()
{
char str[] = "0123456789";
char ch = '3';
for (int i = 0, len = strlen(str); i < len; i++)
if (str[i] == ch)
{
for (int k = i; k < len; k++)
{
//Todo: shift the characters to left
//Hint, it's one line
}
len--;
}
printf("%s\n", str);
return 0;
}
I just added new char array char dest[MAX_LEN] that store string with deleted symbols:
#define MAX_LEN 200
int main()
{
char str[MAX_LEN];
char rem;
int i = 0;
printf("Enter the setence:");
gets(str);
printf("\nEnter the char to remove");
rem = getchar();
char dest[MAX_LEN] = "\0";
char* pDest = dest;
char* pS = str;
printf("sent:\n%s", str);
while (str[i]!='\0')
{
if (*pS != rem)
{
*pDest = *pS;
pDest++;
pS++;
}
else if (*pS == rem)
{
pS++;
}
i++;
}
i = 0;
printf("\nres:\n %s \n", dest);
while (dest[i] != '\0') {
printf("number%d", i);
putchar(dest[i]);
printf("\n");
i++;
}
}

Split a string to an array of strings, along with a flag

I'm trying to write a code in c that return 1 if there is "&" in the string and 0 otherwise.
In addition, the char* that I receive in the function I want to put it in an array of chars and NULL in the end.
My code is like this:
char** isBackslash(char* s1, int *isFlag) {
int count = 0;
isFlag = 0;
char **s2[100];
char *word = strtok(s1, " ");
while (word != NULL) {
s2[count] = word;
if (!strcmp(s2[count], "&")) {
isFlag = 1;
}
count++;
word = strtok(NULL, " ");
}
s2[count] = NULL;
return s2;
}
For example, if the original string (s1) is "Hello I am John &".
So I want s2 to be like:
s2[0] = Hello
s2[1] = I
s2[2] = am
s2[3] = John
s2[4] = &
s2[5] = NULL
And the function will return '1'. What is wrong with my code? I debugged it and unfortunately, I don't find the problem.
You were shadowing your own parameter. See a working example below:
#include <stdio.h>
#include <string.h>
#define BUFF_SIZE 256
int isBackslash(char* s1, char s2[][BUFF_SIZE]) {
int isFlag = 0;
int i = 0;
int j = 0;
int n = 0;
while (s1[i] != '\0') {
isFlag |= !('&' ^ s1[i]); // will set the flag if '&' is met
if (s1[i] == ' ') {
while (s1[i] == ' ')
i++;
s2[n++][j] = '\0';
j = 0;
}
else
s2[n][j++] = s1[i++];
}
return isFlag;
}
int main(void) {
char s2[BUFF_SIZE/2+1][BUFF_SIZE];
memset(s2, 0, sizeof(s2));
char s1[BUFF_SIZE] = "Hello I am John &";
int c = isBackslash(s1, s2);
printf("%d\n", c);
int i = 0;
while (s2[i][0] != '\0')
printf("%s\n", s2[i++]);
}

How to replace a character in a string with another string in C

Let's suppose i have this phrase:
Hello $, Welcome!
I have to replace the '$' with a name, the result should be:
Hello Name, Welcome!
For now i did this, but it copies only the name and the first part of the phrase:
char * InsertName(char * string, char * name)
{
char temp;
for(int i = 0; i < strlen(string); i++)
{
if(string[i] == '$')
{
for(int k = i, j = 0; j < strlen(name); j++, k++)
{
temp = string[k+2];
string[k] = name[j];
string[k+1] = temp;
}
return string;
}
}
return "";
}
How can i shift all the elements after the name, so i can have the full string to be returned?
You can use sprintf() to print the output on a C-string, emulating the work done by printf():
Edit: You will have to include these two headers for this function to work:
#include <stdlib.h>
#include <memory.h>
An implementation of what you are trying to implement:
char* InsertAt(unsigned start, const char* source, const char* target, const char* with,
unsigned * position_ret)
{
const char * pointer = strstr(source, target);
if (pointer == NULL)
{
if (position_ret != NULL)
*position_ret = UINT_MAX;
return _strdup(source);
}
if (position_ret != NULL)
*position_ret = (unsigned)(pointer - source);
char* result = calloc(strlen(source) + strlen(with) + strlen(pointer), sizeof(char));
sprintf_s(result, strlen(source) + strlen(with) + strlen(pointer), "%.*s%.*s%.*s",
(signed)(pointer - source), _strdup(source),
(signed)strlen(with) + 1, _strdup(with),
(signed)(strlen(pointer) - strlen(target)), _strdup(pointer + strlen(target)));
return result;
}
Example:
#define InsertAtCharacter(src, ch, with) InsertAt(0u, (src), \
(char[]){ (char)(ch), '\0' }, (with), NULL)
int main(void)
{
printf("%s", InsertAtCharacter("Hello $, Welcome!", '$', "Name"));
return 0;
}
Try this !!!
#include <stdio.h>
#include <string.h>
char* replace(char* str, char* a, char* b)
{
int len = strlen(str);
int lena = strlen(a), lenb = strlen(b);
for (char* p = str; p = strstr(p, a); ++p) {
if (lena != lenb) // shift end as needed
memmove(p+lenb, p+lena,
len - (p - str) + lenb);
memcpy(p, b, lenb);
}
return str;
}
int main()
{
char str[80] = "Hello $,Welcome!";
printf("%s\n", replace(str, "$", "name"));
return 0;
}

arrays and strings in c

I would like break up a string sequence by " " and stick it into an array. This is the code that I have but does not work:
int main(void) {
char s[] = "this is a string";
char* x = NULL;
unsigned int i = 0;
for (char *p = strtok(s," "); p != NULL; p = strtok(NULL, " ")) {
x[i] = *p;
puts(x[i]);
i++;
}
return 0;
}
It gives me the following error: error:
array initializer must be an initializer list
I am at a loss on how to accomplish this in C. So I would like x[0] = "this",
x[1] = "is" and so on. Any help would be appreciated, I have searched for the answer and read tutorials but still cant come up with the right answer. Any help would be greatly appreciated. Thanks!
There are two problems with your code:
You are trying to grow your array as you go. This is not possible in C without using dynamic allocation with realloc, or pre-allocating sufficient space, and using some of it.
You are trying to store the results of strtok for future use. In general, this is not safe, because tokens point to the original string. It is safer to copy each token into separate space.
Here is how your code would look with pre-allocated space for 100 tokens:
int main(void) {
char s[] = "this is a string";
char* x[100];
unsigned int i = 0;
for (char *p = strtok(s," "); i != 100 && p != NULL; p = strtok(NULL, " ")) {
x[i] = malloc(strlen(p)+1);
strcpy(x[i], p);
puts(x[i]);
i++;
}
// Now you need to free the strings
for (unsigned int j = 0 ; j != i ; j++) {
free(x[j]);
}
return 0;
}
Demo.
If you are certain that there would be no modifications done to s, you could store tokens directly, too:
int main(void) {
char s[] = "this is a string";
char* x[100];
unsigned int i = 0;
for (char *p = strtok(s," "); i != 100 && p != NULL; p = strtok(NULL, " ")) {
x[i] = p;
puts(x[i]);
i++;
}
return 0;
}

Split String into Tokens

*Can someone please help me with this function. I'm trying to separate the string input into tokens and also shift each token some by some specified amount. *
char *tokenize(char *f, int shift){
const char delim[] = " .;\n\t";
char *pa = f; //points to the beginning of *f
//size of *f
int i;
int stringSize = 0;
for(i = 0; f[i] != '\0'; i++)
{
stringSize++;
}
//put string in array to pass to strtok function
char newString[stringSize];
int j;
for(j = 0; j < stringSize; j++)
{
newString[j] = *f;
f++;
}
//break the words up into sub-strings without the delimiters
char *word = strtok(newString, delim);
while(word != NULL)
{
word = strtok(NULL, delim);
word = stringShift(word, shift);
//printf("After being shifted %d = %s\n", shift, word);
}
return pa;
}
/*Shift Function*/
char *stringShift(char *s, int k){
int i;
for(i = 0; s[i] != '\0'; i++)
{
s[i] += k;
}
return s;
}
I think this should serve the purpose ok, as far as I understand it
char* addWordToArr(char *arr,char *word)
{
int i;
for(i =0;i<strlen(word);i++)
{
*arr++ = word[i];
}
*arr++ = ' ';
return arr;
}
char *tokenize(char *f, int shift){
const char delim[] = " .;\n\t";
int stringSize = strlen(f);
//put string in array to pass to strtok function
char newString[stringSize+1];
int j;
for(j = 0; j < stringSize; j++)
{
newString[j] = *f;
f++;
}
newString[stringSize] = '\0'; //null terminate
char *rVal = malloc(sizeof(char) * (stringSize +1)); //The total length of the tokenized string must be <= the original string
char *writePtr = rVal;
//break the words up into sub-strings without the delimiters
char *word = strtok(newString, delim);
word = stringShift(word, shift);
writePtr = addWordToArr(writePtr,word);
while(word != NULL)
{
word = strtok(NULL, delim);
if(word)
{
word = stringShift(word, shift);
writePtr = addWordToArr(writePtr,word);
}
}
writePtr = '\0';
return rVal;
}
which produces:
string before shift bish;bash;bosh hyena trout llama exquisite underwater dinosaur
string after shift dkuj dcuj dquj j{gpc vtqwv nncoc gzswkukvg wpfgtycvgt fkpqucwt
The stringShift function is unchanged

Resources