String manuplation in C - c

I hava a string, say ../bin/test.c, so how can i get its substring test?
I tried strtok api, but it seems not good.
char a[] = "../bin/a.cc";
char *temp;
if(strstr(a,"/") != NULL){
temp = strtok(a, "/");
while(temp !=NULL){
temp = strtok(NULL, "/");
}
}

Try this:
char a[] = "../bin/a.cc";
char *tmp = strrstr(a, "/");
if (tmp != NULL) {
tmp ++;
printf("%s", tmp); // you should get a.cc
}

#include <stdio.h>
#include <string.h>
int main(void){
char a[] = "../bin/a.cc";
char name[16];
char *ps, *pe;
ps = strrchr(a, '/');
pe = strrchr(a, '.');
if(!ps) ps = a;
else ps += 1;
if(pe && ps < pe) *pe = '\0';
strcpy(name, ps);
printf("%s\n", name);
return 0;
}

The ugly one solution:
char a[] = "../bin/a.cc";
int len = strlen(a);
char buffer[100];
int i = 0;
/* reading symbols from the end to the slash */
while (a[len - i - 1] != '/') {
buffer[i] = a[len - i - 1];
i++;
}
/* reversing string */
for(int j = 0; j < i/2; j++){
char tmp = buffer[i - j - 1];
buffer[i - j - 1] = buffer[j];
buffer[j] = tmp;
}

Related

using double pointer for char - what's the problem in the code?

char* scanString()
{
char* str = NULL;
char* temp = NULL;
int numOfChars = 0;
char c = '0';
while (c != '\n')
{
scanf("%c", &c);
str = (char*)realloc(str, sizeof(char) * (numOfChars + 1));
temp = str;
if (str == NULL)
{
str = temp;
return str;
}
str[numOfChars] = c;
if (c == '\n')
{
str[numOfChars] = '\0';
}
numOfChars++;
}
return str;
}
int main()
{
char** doublePointer = NULL;
char* m = scanString();
char* token = strtok(m, ",");
int i = 0;
while (token != NULL)
{
doublePointer = (char**)realloc(doublePointer, sizeof(char*) * (i+1));
if (doublePointer)
doublePointer[i] = (char*)realloc(doublePointer[i], strlen(token) + 1);
strcpy(doublePointer[i], token);
token = strtok(NULL, ",");
i++;
}
for (int k = 0; k <= i; k++)
{
printf("%d: %s\n", k + 1, doublePointer[k]);
}
return 0;
}
im trying to get a string like "option1,oprion2,option3" into array of strings and then put each option in its place at the array.
at the end i wanna print wach option in the order they were put.
what am I doing wrong?
Thanks for helping.
The problem was fixed by replacing
doublePointer[i] = (char*)realloc(doublePointer[i], strlen(token) + 1);
with a malloc. Credits to kaylum!

Converting a string into 2d array in c

hi i have been trying to convert a string map to an 2d array but the more i change the more i get confused. now it does not compile and complains its = NUL (edited i added malloc and seems that and gives segmentation fault).
#include <unistd.h>
#include <stdlib.h>
char **stoa(char *str)
{
int i;
int j;
int k;
char **map;
//int len = ft_strlen_line(str);
//int row = ft_strlen(str);
i = 0;
j = 0;
k = 0;
//arow = row/len;
//map = malloc(j * k sizeof(char*));
map = malloc(j * sizeof(k));
while(str[i])
{
if (str[i] == '\n')
{
k = 0;
j++;
}
map[j][k] = str[i];
k++;
i++;
}
free(map);
return (map);
if (!(map = malloc(j * k * sizeof(char))))
return NULL;
}
int main(void)
{
char row12[] = "ABABABABAB\nABABABABAB\nABABABABAB\n\0";
char **map;
map = stoa(row12);
return (0);
}
Not tested.
char **stoa(char *str)
size_t nlines = 0;
size_t pos = 0;
char **array = NULL;
char **tmp;
while(*str)
{
while(*str && str[pos++] != '\n');
nlines++;
tmp = realloc(array, (nlines + 1) * sizeof(*array));
if(tmp) array = tmp;
else break;
array[nlines] = NULL;
if(array[nlines - 1] = malloc(pos + 2));
if(array[nlines - 1])
{
memcpy(array[nlines - 1], str, pos);
array[nlines - 1][pos] = 0;
str = str + pos;
if(str == '\n') str++;
pos = 0;
}
else break;
}
return array;
}

Deleting substring in a string with delimiters in C [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 2 years ago.
Improve this question
I need a help with a program (without using strtok() function) that should be doing this:
If the input is
car;dog;pet;elephant
and if the argument is 2, the ouput should be:
car;pet;elephant
if the argument is 4, the output should be:
car;dog;pet
and so on.
I've tried a lot of different solutions but nothing seems to work. So if anybody could help me, I would be really glad.
Thank you.
I think this solution always works with valid input.
#include <stdlib.h>
#include <stdio.h>
int main(int argc, char *argv[])
{
if (argc != 3)
return 1;
int x = atoi(argv[2]);
char *s = argv[1], *d = argv[1];
while (*s)
{
if (x == 0)
{
--x;
while (*s && *s != ';')
++s;
if (*s)
++s;
else
break;
}
if (*s == ';')
--x;
*d++ = *s++;
}
if (*(d - 1) == ';')
*(d - 1) = '\0';
else
*d = '\0';
puts(argv[1]);
return 0;
}
Here is a function to construct a new csv line with the field number pos (1-based) removed:
#include <stdlib.h>
#include <string.h>
char *removeField(const char *str, char delim, int pos)
{
char *out;
const char *p, *q;
size_t len1, len2;
int i, nsep = 0;
if (str == NULL)
return NULL;
/* skip the fields before the target field */
for (p = str, i = 1; *p && i < pos; i++) {
while (*p && *p != delim)
p++;
if (*p == delim) {
p++;
nsep++;
}
}
/* skip the field to remove */
for (q = p; *q && *q != delim; q++)
continue;
if (*q == delim) {
/* if there are more fields, skip the delimiter */
q++;
} else {
/* otherwise remove the trailing delimiter if the removed field was
the last one but not the first one */
if (pos > 1 && nsep == pos - 1)
p--;
}
/* allocate the exact amount of bytes */
len1 = p - str;
len2 = strlen(q);
out = malloc(len1 + len2 + 1);
if (out != NULL) {
/* copy the left and right parts */
memcpy(out, str, len1);
memcpy(out + len1, q, len2 + 1);
}
/* return the new CSV line or NULL if allocation failure */
return out;
}
Here is the function removing the substring from the "csv style" line. It takes info the account empty strings and (probably most as I did not properly test it) border cases.
It is not using "heavy" string functions like strtok or strdup as I believe this exercise is to write it using arrays or pointers.
char *dupAndDelete(const char *str, char delim, int pos)
{
char *out = NULL;
int cpos = 1;
if(str)
{
out = malloc(strlen(str) + 1);
char *wrk = out;
if(out)
{
while(*str)
{
if(cpos == pos)
{
while(*str && *str != delim)
str++;
}
else
{
*wrk++ = *str;
}
if(*str == delim)
{cpos++;}
if(*str) str++;
}
if(wrk > out)
if(*(wrk - 1) == delim && cpos == pos)
wrk--;
*wrk = 0;
}
}
return out;
}
int main(void)
{
char *str = ";;car;;dog;pet;elephant;;";
char *output;
for(int pos = 0; pos < 12; pos++)
{
output = dupAndDelete(str, ';', pos);
if(output) printf("pos = %2d str = \"%s\"\n", pos, output);
fflush(stdout);
free(output);
}
return 0;
}
You can search a ; with strchr()
This code searches the index you want to remove (1-based indexes)
int main(void)
{
for (size_t i = 0; i < 6; i++)
{
// This is you argument
int arg2 = i;
printf("%ld: ", i);
char *s = strdup(";car;dog;pet;elephant");
char *curr = s;
for (int i = 0; curr && i < arg2; i++)
curr = strchr(curr + 1, ';');
if (!curr)
{
printf("%s\n", s);
free(s);
continue;
}
char *next = strchr(curr + 1, ';');
if (!next)
{
*curr = 0;
}
else
{
size_t offset = next - curr;
size_t len = strlen(s);
for (size_t i = curr - s; i < len; i++)
s[i] = (i + offset < len ? s[i + offset + (curr == s)] : 0);
}
printf("%s\n", s);
free(s);
}
return 0;
}
Without any control/argument inspection, I think this is what you're looking for:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main(int argc, char ** argv) {
if (argc < 3) {
printf("Argument missing!\n");
return 1;
}
char * output = calloc(sizeof(char), strlen(argv[1]));
int cnt = 1;
int memb = atoi(argv[2]);
int outputp = 0;
char* token = strtok(argv[1], ";");
while (token != NULL) {
if (cnt != memb) {
strcat(output+outputp, token);
outputp += strlen(token);
strcat(output+outputp, ";");
outputp++;
}
token = strtok(NULL, ";");
cnt++;
}
output[outputp-1] = '\0';
printf("%s\n", output);
free(output);
return 0;
}
use:
$ ./a.out "car;dog;pet;elephant" 2
car;pet;elephant
$ ./a.out "car;dog;pet;elephant" 4
car;dog;pet
Edit: you can use strsep() instead of strtok(), then if your substring is empty, that will counts too:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main(int argc, char ** argv) {
if (argc < 3) {
printf("Argument missing!\n");
return 1;
}
char * output = calloc(sizeof(char), strlen(argv[1])+1);
int cnt = 1;
int memb = atoi(argv[2]);
int outputp = 0;
char * token;
while ((token = strsep(&argv[1], ";")) != NULL) {
printf("'%s'\n", token);
if (cnt != memb) {
strcat(output+outputp, token);
outputp += strlen(token);
strcat(output+outputp, ";");
outputp++;
}
cnt++;
}
output[outputp-1] = '\0';
printf("%s\n", output);
free(output);
return 0;
}

reversing word. (null terminated c string char array). why isn't it working

am trying to reverse a char array and print it using %s. but its not working. am not getting anything printed. why is that? my code is pretty simple/
char* reverse(char* word){
int i = 0;
int length=0;
while (word[i] != '\0'){
i++;
}
length = i;
char* temp_word = malloc(length* sizeof(char));
for (i = 0; i < length; i++){
temp_word[i] = word[length - i];
word[i] = temp_word[i];
}
return word ;
}
temp_word[i] = word[length - i];
should probably be
temp_word[i] = word[length - i - 1];
If word[] is 3 characters long, word[3] is actually the null terminator.
This works ... you did not allocate space for Null terminator ... and you are overwriting by doing this 'word[i] = temp_word[i]' ...
#include <stdio.h>
#include <stdlib.h>
char *reverse(char *);
int main()
{
char sWord[10] = "PHONE";
char *temp = NULL;
printf("Before reverse() => %s\n", sWord);
temp = reverse(sWord);
printf("After reverse() => %s\n", temp);
return 0;
}
char *reverse(char *word)
{
int i = 0;
int length = 0;
while(word[i] != '\0')
{
i++;
}
length = i;
char *temp_word = malloc(length * (sizeof(char)+1)); // +1 here.
for (i = 0; i < length; i++)
{
temp_word[i] = word[length - (i+1)];
//word[i] = temp_word[i]; <== Do not need this.
}
temp_word[length] = '\0';
return temp_word ;
}

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