How do I separate a string into different chars - c

Also after I want to add a key to each letter like 'a' + 1 = 'b'. So I want to take a string for instance "Hello" then do
char 1 = H + 1;
char 2 = E + 1;
etc.
printf("%c" + "%c" + "%c" + "%c" + "%c", 1 , 2 , 3 , 4 , 5);
also I would love for this to be automated because IDK how long the string might be and what key theyre are going to use.

You can do something like this:
#include<stdio.h>
#include<string.h>
int main()
{
char text[] = "Hello";
int i=0;
int size= strlen(text);
for(i=0;i<size;i++)
{
//something here
}
return 0;
}

Assuming the string is mutable, you can update it in place:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
void update(char *s, int delta)
{
while(*s)
*s++ += delta;
}
int main(int argc, char **argv)
{
char str[] = "Hello";
update(str, 1);
printf("Encoded: \"%s\"\n", str);
update(str, -1);
printf("Decoded: \"%s\"\n", str);
return 0;
}
If the string is immutable, you will need to make a copy of it, and update the copy.
int main(int argc, char **argv)
{
const char str[] = "Hello";
char *copy = strdup(str);
update(copy, 1);
printf("Encoded: \"%s\"\n", copy);
update(copy, -1);
printf("Decoded: \"%s\"\n", copy);
free(copy);
return 0;
}

You should read about dynamic arrays in C.
#include <stdio.h>
#include <string.h>
char* code(const char* message)
{
int i = 0;
char* coded;
for (i = 0; i < strlen(message); i++)
{
coded[i] = message[i] - 3;
}
return coded;
}
char* decode(const char* message)
{
int i = 0;
char* coded;
for (i = 0; i < strlen(message); i++)
{
coded[i] = message[i] + 3;
}
return coded;
}
int main()
{
// This is dynamic allocated chars array
char* message = "Hello World!";
message = code(message);
printf("%s\n", message);
message = decode(message);
printf("%s\n", message);
}

Related

Read raw bytes in argv[]

I was wondering if there was a way to read bytes (like this: \x00\x01\x02) from the command line in C.
For example:
#include <stdio.h>
int main(int argc, char *argv[]) {
printf("%s", argv[1]);
return 0;
}
user#UbuntuServer: ~/Code# gcc Program.c -o Program
user#UbuntuServer: ~/Code# ./Program "\x48\x69"
Hiuser#UbuntuServer: ~/Code# ./Program "\x48\x69\x0a"
Hi
user#UbuntuServer: ~/Code#
Thanks!
Unless you use a library to parse regex strings like that, you'll need to parse the hex manually. Check out this answer (which has slightly different syntax but a similar function):
Hexadecimal string to byte array in C
I would go for something like this:
int main(int argc, char **argv)
{
char *buf = malloc(strlen(argv[1]) / 4 + 1);
size_t i = 0;
for (char *tok = strtok(argv[1], "\\x"); tok; tok = strtok(NULL, "\\x"))
{
sscanf(tok, "%02hhx", buf + i);
i++;
}
buf[i] = '\0';
printf("%s", buf);
free(buf);
return 0;
}
I found the HEX to ASCII conversion functions on this thread, and modified it to suit my situation.
#include <stdio.h>
#include <string.h>
int hexToInt(char c) {
int first = c / 16 - 3;
int second = c % 16;
int result = first * 10 + second;
if(result > 9) {
result--;
}
return result;
}
int hexToASCII(char c, char d) {
int high = hexToInt(c) * 16;
int low = hexToInt(d);
return high + low;
}
int main(int argc, char *argv[]) {
char* hexString = argv[1];
char buf = 0;
for(int i = 0; i < strlen(hexString); i++) {
if(i % 2 != 0) {
printf("%c", hexToASCII(buf, hexString[i]));
} else {
buf = hexString[i];
}
}
return 0;
}

How to add a character in a string by checking the delimiter?

I have a string in my program where in which it need to be altered with another string value before a "/".
Source String : qos-tree/output_rate
Target String : qos-tree-2/output_rate
#include <stdio.h>
#include <string.h>
void append(char* s, char c)
{
int len = strlen(s);
s[len] = c;
s[len+1] = '\0';
}
int main(void)
{
char str[256] = "qos-tree/output_rate";
char c = "a";
append(str, c);
printf("%s\n", str);
return 0;
}
This is what i have done so far,I think the logic is wrong here.Can anyone guide me to correct it?
Once the execution is completed the source string should have a "-2" before the "/"
void insert_before_ch(char *s, const char *ins, char c){
char *p = strchr(s, c);
if(p){
size_t len = strlen(ins);
memmove(p + len, p, strlen(p)+1);
memcpy(p, ins, len);
}
}
int main(void){
char str[256] = "qos-tree/output_rate";
insert_before_ch(str, "-2", '/');
printf("%s\n", str);
return 0;
}
In your attempt, you don't look for a slash and I do not see any "-2" anywhere.
Try this instead:
#include <stdio.h>
#include <string.h>
void append(char* s, char del, char* substring) {
char origin[256];
strcpy(origin, s);
int i = 0, j = 0, z = 0;
for(; origin[i]; ++i) {
if(origin[i] != del) {
s[j++] = origin[i];
} else {
for(; substring[z]; ++z) {
s[j++] = substring[z];
}
s[j++] = origin[i];
}
}
s[j] = '\0';
}
int main(void) {
char str[256] = "qos-tree/output_rate";
char del = '/';
char* substring = "-2";
append(str, del, substring);
printf("%s\n", str);
return 0;
}
The logic is that inside the function we use origin array to remember the actual contents of the array and then we copy from origin to s (which is the actual array of main()). If we find our delimiter del, then we copy the substring in that position and continuing with copying.
Note that the length of the array should be enough to store the resulted string. In this case, it is.
I think you should make your function work with dynamic allocation, because inserting characters into the string will make the resulting string larger, so this is my suggestion
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
void insert(char **str, char chr, unsigned int position)
{
int length;
char *ptr;
if (str == NULL)
return;
length = strlen(*str);
if (position >= length)
return;
ptr = realloc(*str, 2 + length);
if (ptr == NULL)
return;
*str = ptr;
memmove(ptr + position + 1, ptr + position, length - position + 1);
ptr[position] = chr;
}
int main(void)
{
const char *source = "qos-tree/output_rate";
size_t length = strlen(source);
char *str = malloc(1 + length);
if (str == NULL)
return -1;
strcpy(str, source);
insert(&str, '-', 8);
insert(&str, '2', 9);
printf("%s\n", str);
free(str);
return 0;
}
first of all thist char c = "a" should be replace with this char c = 'a'; because c is a character not a string
as for your problem I didn't realy see the relation between what your code is doing with what you said you wanted to do , but here a piece of code to achieve what , I think , you want to do :
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
void append(char* str , char c)
{
char firststr[60];
char therest[30];
strcpy(firststr , strtok(str , "/"));
strcpy(therest , strtok(NULL , "/"));
strcat(firststr , &c);
strcat(firststr , "/");
strcat(firststr , therest);
strcpy(str , firststr);
}
int main(void)
{
char str[60] = "qos-tree/output_rate";
char c = '2';
append(str , c);
printf("%s\n" , str);
}
there you go I think this is what you wanted to do you can modify the array sizes to fit your needs

How can I split a char* into substrings in C?

I have a text like this:
char* str="Hi all.\nMy name is Matteo.\n\nHow are you?"
and I want to split the string by "\n\n" in to an array like this:
char* array[3];
array[0]="Hi all.\nMy name is Matteo."
array[1]="How are you?"
array[2]=NULL
I've tried the strtok function but it does not split the string correctly.
#include <stdio.h>
#include <string.h>
int main(){
char *str="Hi all.\nMy name is Matteo.\n\nHow are you?";
char *array[3];
char *ptop, *pend;
char wk[1024];//char *wk=malloc(sizeof(char)*(strlen(str)+3));
int i, size = sizeof(array)/sizeof(char*);
/*
array[0]="Hi all.\nMy name is Matteo."
array[1]="How are you?"
array[2]=NULL
*/
strcpy(wk, str);
strcat(wk, "\n\n");
for(i=0, ptop=wk;i<size;++i){
if(NULL!=(pend=strstr(ptop, "\n\n"))){
*pend='\0';
array[i]=strdup(ptop);
ptop=pend+2;
} else {
array[i]=NULL;
break;
}
}
for(i = 0;i<size;++i)
printf("array[%d]=\"%s\"\n", i, array[i]);
return 0;
}
The strtok() function works on a set of single character delimiters. Your goal is to split by a two character delimiter, so strtok() isn't a good fit.
You could scan your input string via a loop that used strchr to find newlines and then checked to see if the next char was also a newline.
A more generic method based on strstr function:
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
int main(void) {
char* str="Hi all.\nMy name is Matteo.\n\nHow are you?\n\nThanks";
char **result = NULL;
unsigned int index = 0;
unsigned int i = 0;
size_t size = 0;
char *ptr, *pstr;
ptr = NULL;
pstr = str;
while(pstr) {
ptr = strstr(pstr, "\n\n");
result = realloc(result, (index + 1) * sizeof(char *));
size = strlen(pstr) - ((ptr)?strlen(ptr):0);
result[index] = malloc(size * sizeof(char));
strncpy(result[index], pstr, size);
index++;
if(ptr) {
pstr = ptr + 2;
} else {
pstr = NULL;
}
} ;
for(i = 0; i < index; i++) {
printf("Array[%d] : >%s<\n", i, result[i]);
}
return 0;
}

Remove '|' from a string

I wrote the below code which replaces '|' characters from the string.
#include <stdio.h>
#include <stdlib.h>
void remove_pipes(char*);
main (int argc, char **argv)
{
char string1[] = "|||||||||||||";
remove_pipes(string1);
printf("String1 = %s", string1);
char string2[] = "h|e|l|l|o";
remove_pipes(string2);
printf("String2 = %s", string2);
}
void remove_pipes(char* input)
{
for(; *input; input++)
{
if(*input == '|')
{
*input = ' ';
}
}
}
Now I need to modify this method to remove the '|' character from the string. I am not sure how to do that. Hope someone can give me some hint.
Use a char pointer to travel the input and modify it:
#include <stdio.h>
#include <stdlib.h>
void remove_pipes(char*);
main (int argc, char **argv)
{
char string1[] = "|||||||||||||";
printf("String1 = %s\n", string1);
remove_pipes(string1);
printf("String1 = %s\n", string1);
char string2[] = "h|e|l|l|o";
printf("String2 = %s\n", string2);
remove_pipes(string2);
printf("String2 = %s\n", string2);
}
void remove_pipes(char* input)
{
unsigned idx = 0;
char* aux = input;
for(; *input; input++)
{
if (*input != '|')
{
*(aux + idx++) = *input;
}
}
*(aux + idx) = '\0';
}

Using strtok in c

I need to use strtok to read in a first and last name and seperate it. How can I store the names where I can use them idependently in two seperate char arrays?
#include <stdio.h>
#include <string.h>
int main ()
{
char str[] ="test string.";
char * test;
test = strtok (str," ");
while (test != NULL)
{
printf ("%s\n",test);
test= strtok (NULL, " ");
}
return 0;
}
Here is my take at a reasonably simple tokenize helper that
stores results in a dynamically growing array
null-terminating the array
keeps the input string safe (strtok modifies the input string, which is undefined behaviour on a literal char[], at least I think in C99)
To make the code re-entrant, use the non-standard strtok_r
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
char** tokenize(const char* input)
{
char* str = strdup(input);
int count = 0;
int capacity = 10;
char** result = malloc(capacity*sizeof(*result));
char* tok=strtok(str," ");
while(1)
{
if (count >= capacity)
result = realloc(result, (capacity*=2)*sizeof(*result));
result[count++] = tok? strdup(tok) : tok;
if (!tok) break;
tok=strtok(NULL," ");
}
free(str);
return result;
}
int main ()
{
char** tokens = tokenize("test string.");
char** it;
for(it=tokens; it && *it; ++it)
{
printf("%s\n", *it);
free(*it);
}
free(tokens);
return 0;
}
Here is a strtok-free reimplementation of that (uses strpbrk instead):
char** tokenize(const char* str)
{
int count = 0;
int capacity = 10;
char** result = malloc(capacity*sizeof(*result));
const char* e=str;
if (e) do
{
const char* s=e;
e=strpbrk(s," ");
if (count >= capacity)
result = realloc(result, (capacity*=2)*sizeof(*result));
result[count++] = e? strndup(s, e-s) : strdup(s);
} while (e && *(++e));
if (count >= capacity)
result = realloc(result, (capacity+=1)*sizeof(*result));
result[count++] = 0;
return result;
}
Do you need to store them separately? Two pointers into a modified char array will yield two separate perfectly usable strings.
That is we transform this:
char str[] ="test string.";
Into this:
char str[] ="test\0string.";
^ ^
| |
char *s1 ----- |
char *s2 -----------
.
#include <stdio.h>
#include <string.h>
int main ()
{
char str[] ="test string.";
char *firstname = strtok(str, " ");
char *lastname = strtok(NULL, " ");
if (!lastname)
lastname = "";
printf("%s, %s\n", lastname, firstname);
return 0;
}
What about using strcpy:
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#define MAX_NAMES 2
int main ()
{
char str[] ="test string.";
char *names[MAX_NAMES] = { 0 };
char *test;
int i = 0;
test = strtok (str," ");
while (test != NULL && i < MAX_NAMES)
{
names[i] = malloc(strlen(test)+1);
strcpy(names[i++], test);
test = strtok (NULL, " ");
}
for(i=0; i<MAX_NAMES; ++i)
{
if(names[i])
{
puts(names[i]);
free(names[i]);
names[i] = 0;
}
}
return 0;
}
It contains much clutter to maintain a complete program and clean its resources, but the main point is to use strcpy to copy each token into its own string.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
char** split(const char *str, const char *delimiter, size_t *len){
char *text, *p, *first, **array;
int c;
char** ret;
*len = 0;
text=strdup(str);
if(text==NULL) return NULL;
for(c=0,p=text;NULL!=(p=strtok(p, delimiter));p=NULL, c++)//count item
if(c==0) first=p; //first token top
ret=(char**)malloc(sizeof(char*)*c+1);//+1 for NULL
if(ret==NULL){
free(text);
return NULL;
}
strcpy(text, str+(first-text));//skip until top token
array=ret;
for(p=text;NULL!=(p=strtok(p, delimiter));p=NULL){
*array++=p;
}
*array=NULL;
*len=c;
return ret;
}
void free4split(char** sa){
char **array=sa;
if(sa!=NULL){
free(array[0]);//for text
free(sa); //for array
}
}
int main(void){
char str[] ="test string.";
char **words;
size_t len=0;
int i;
words = split(str, " \t\r\n,.", &len);
/*
for(char **wk = words; *wk ;wk++){
printf("%s\n", *wk);
}
*/
for(i = 0;i<len;++i){
printf("%s\n", words[i]);
}
free4split(words);
return 0;
}
/* result:
test
string
*/
Copy the results from strtok to a new buffer using a function such as
/*
* Returns a copy of s in freshly allocated memory.
* Exits the process if memory allocation fails.
*/
char *xstrdup(char const *s)
{
char *p = malloc(strlen(s) + 1);
if (p == NULL) {
perror("memory allocation failed");
exit(1);
}
strcpy(p, s);
return p;
}
Don't forget to free the return values when you're done with them.
IMO, you don't need (and probably don't want) to use strtok at all (as in, "for this, or much of anything else"). I think I'd use code something like this:
#include <string.h>
#include <stdlib.h>
static char *make_str(char const *begin, char const *end) {
size_t len = end-begin;
char *ret = malloc(len+1);
if (ret != NULL) {
memcpy(ret, begin, len);
ret[len]='\0';
}
return ret;
}
size_t tokenize(char *tokens[], size_t max, char const *input, char const *delims) {
int i;
char const *start=input, *end=start;
for (i=0; *start && i<max; i++) {
for ( ;NULL!=strchr(delims, *start); ++start)
;
for (end=start; *end && NULL==strchr(delims, *end); ++end)
;
tokens[i] = make_str(start, end);
start = end+1;
}
return i;
}
#ifdef TEST
#define MAX_TOKENS 10
int main() {
char *tokens[MAX_TOKENS];
int i;
size_t num = tokenize(tokens, MAX_TOKENS, "This is a longer input string ", " ");
for (i=0; i<num; i++) {
printf("|%s|\n", tokens[i]);
free(tokens[i]);
}
return 0;
}
#endif
U can do something like this too.
int main ()
{
char str[] ="test string.";
char * temp1;
char * temp2;
temp1 = strtok (str," ");
temp2 = strchr(str, ' ');
if (temp2 != NULL)
temp2++;
printf ("Splitted string :%s, %s\n" , temp1 , temp2);
return
}

Resources