I have a string
{"status":true}
I want to replace " with ". I tried several string operations, but they're not working.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char *replace (char *this, char *withthat, char *inthis) {
char *where = inthis;
if(strlen(withthat)>strlen(this)) {
fprintf(stderr, "replace can only shrink\n");
exit(EXIT_FAILURE);
}
while ((where = strstr(where, this))) {
memcpy(where, withthat, strlen(withthat));
memmove(where+strlen(withthat),where+strlen(this), strlen(where+strlen(this))+1);
}
return inthis;
}
int main(void) {
char string[] = "{"status":true}";
printf("%s\n", replace(""", "\"", string));
return 0;
}
Output:
{"status":true}
Related
Outside of using a hash function, I'd like to write a basic mapping of a key/value lookup of a few movie-credits related items. Does the following macro seem like an acceptable way to do it?
#include <stdio.h>
#include <string.h>
#define TOMAP(input_str, output_buf, from, to) \
if (strcmp(input_str, from) == 0) \
strcpy(output_buf, to)
void map_imdb_position(const char* pos, char output[])
{
TOMAP(pos, output, "Director", "director");
TOMAP(pos, output, "Writer", "scribe");
}
int main(void) {
char position[20];
map_imdb_position("Director", position);
printf("Director->%s\n", position);
}
If not, what might be a better approach to doing a sort of switch statement on a string comparison?
As suggested in the comments a cleaner way to do this would be with a map of credits in a function, for example:
#include <stdio.h>
#include <string.h>
typedef struct map {
char from[20];
char to[20];
} Map;
void map_imdb_position(const char* credit, char output[])
{
static Map credits[] = {
{"Director", "director"},
{"Writer", "scribe"}
};
for (int i=0; i < sizeof(credits)/sizeof(*credits); i++) {
if (strcmp(credit,credits[i].from) == 0) {
strcpy(output, credits[i].to);
break;
}
}
printf("%s --> %s\n", credit, output);
}
int main(void) {
char position[20];
map_imdb_position("Director", position);
map_imdb_position("Writer", position);
}
Working example: https://onlinegdb.com/Sk_t76aQ_
Side note: I was working on this solution but Carl already came up with a similar one.
But, I prefer to use the ptr->field syntax and to have an end-of-table sentinel at the end (vs. the sizeof construct to get the count).
And, I think designated initializers when constructing the table make things more readable [especially if more fields need to be added to the struct].
So, here's my version:
#include <stdio.h>
#include <string.h>
typedef struct {
const char *from;
const char *to;
} mapimdb_t;
mapimdb_t mapimdb[] = {
{ .from = "Director", .to = "director" },
{ .from = "Writer", .to = "scribe" },
// ...
{ .from = NULL }
};
void
map_imdb_position(const char *pos, char *output)
{
for (const mapimdb_t *map = mapimdb; map->from != NULL; ++map) {
if (strcmp(pos,map->from) == 0) {
strcpy(output,map->to);
break;
}
}
}
void
dotest(const char *from,char *out)
{
map_imdb_position(from,out);
printf("dotest: %s->%s\n",from,out);
}
int
main(void)
{
char position[20];
dotest("Director", position);
dotest("Writer", position);
}
X macros can be used:
#include <stdio.h>
#include <string.h>
#define STR_LIST \
X("Director", "director") \
X("Writer", "scribe")
void map_imdb_position(const char* pos, char output[])
{
#define X(from, to) \
if (strcmp(pos, from) == 0) \
{ strcpy(output, to); return; } // "return" was missing?
STR_LIST
#undef X
}
int main(void) {
char position[20];
map_imdb_position("Director", position);
printf("Director->%s\n", position);
}
I'm making a code to remove the file name and type from a path. However, i'm receiving warnings concerning the line where i change the content from a character. How could i get rid of the warning?
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char *getPath(char *fullPath){
char *aux;
int a, b, c;
aux = malloc(50 * sizeof(char));
aux = fullPath;
a = strlen(aux);
for(b=0; b<a; b++){
if (aux[b] == '/'){
c = b;
}
}
for(c; c < a; c++){
///PROBLEM HERE
aux[c] = "";
}
///PROBLEM HERE
return aux;
}
int main(void) {
char C[50];
char *path, *filename;
scanf("%s", C);
path = getPath(C);
printf("%s", path);
}
aux[c] = ""; // here "" is a char *
aux is a char *, therefore aux[c] is a char (not a string "")
aux[c] = '\0';
As written in the comments, there still have other mistakes in the rest of the code: for example aux value is erased.
Tried fixing the entire code.
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
bool getPath(char *const strippedPath, const int strippedPath_buflen,const char *const fullPath){
int b=strlen(fullPath);
for(;;){
--b;
if(b<0)
return false;
if('/'==fullPath[b])
break;
}
if(strippedPath_buflen<b+1)
return false;
strncpy(strippedPath,fullPath,b);
strippedPath[b]='\0';
return true;
}
int main(void) {
for(;;){
char C[50]={};
printf("> ");
fflush(stdout);
scanf("%s",C);
if(0==strcmp("quit",C))
break;
char path[3+1]={'X','X','X','X'};
if(getPath(path,4,C))
printf("%s\n",path);
else
printf("err\n");
}
return 0;
}
> aaaa/b.txt
err
> aaa/b.txt
aaa
> a/c/b.txt
a/c
> aa/b.txt
aa
> a/b.txt
a
> a/
a
> /b.txt
> b.txt
err
> quit
Why it is not working... It should be working, right? gcc have problem with this line, but why?
render_history(history, 2);
Sorry for bothering. I am just a beginner.
#include <stdio.h>
void render_history(char** history, const int entry);
int main()
{
char* history[3][4];
history[0][0] = "1234";
history[1][0] = "5678";
history[2][0] = "9012";
render_history(history, 2); //??
return 0;
}
void render_history(char** history, const int entry)
{
// print "9012"
}
gcc have problem with this line, but why?
Because the type is wrong. char* history[3][4]; can't be passed as char**. They are incompatible types.
Try something like:
#include <stdio.h>
void render_history(char* (*history)[4] , const int entry)
{
printf("%s\n", history[entry][0]);
}
int main()
{
char* history[3][4];
history[0][0] = "1234";
history[1][0] = "5678";
history[2][0] = "9012";
render_history(history, 2);
return 0;
}
As mentioned above double pointer not equal to 2D array.
You can also use pointer to pointer of char. char **history. And with this you have several option:
1) Use compound literals
#include <stdio.h>
void render_history(const char **history, const int entry)
{
printf("%s\n", history[entry]);
}
int main(void)
{
const char **history = (const char *[]) { "1234", "5678", "9012", NULL};
render_history(history, 2);
return 0;
}
If you need change your data later
2) Use dynamic memory allocation with malloc
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
void render_history(char **history, const int entry)
{
printf("%s\n", history[entry]);
}
int main(void)
{
char **history = malloc(3 * sizeof(char *));
for (int i = 0; i < 3; ++i)
{
history[i] = malloc(4 * sizeof(char));
}
strcpy(history[0], "1234");
strcpy(history[1], "5678");
strcpy(history[2], "9012");
history[3] = NULL;
render_history(history, 2);
return 0;
}
If you use 2nd option dont forget free memory after use.
#include <stdio.h>
#include <stdlib.h>
int countArrayChars(char *strArray[]){
int i=0;
while (strArray[i] != '\0'){
i++;
}
printf("%d\n", i);
return i;
}
int main(int argc, const char * argv[]) {
char *dog[] = {"dog"};
countArrayChars(dog);
For some reason, it prints "5".
Shouldn't it print 3?
I even tried to put \0 after the "g".
You declare array of string and initialize it with dog.
char *dog[] = {"dog"};
Actually it represented as
dog[0] = "Dog"; //In your case only element index with 0.
...............
...............
dog[n] = "tiger"; //If there Have n+1 element
Hence your array size is 1. Which hold constant string dog. To access it you should use dog[0].
So without less modification you can use your code as:
int countArrayChars(char *strArray[])
{
int i=0;
while (strArray[0][i] != '\0')
{
i++;
}
printf("%d\n", i);
return i;
}
int main(int argc, const char * argv[])
{
char *dog[] = {"dog"};
countArrayChars(dog);
}
Or if you want to declare a string use
char *dog = "dog";
or
char dog[] = "dog";
Please try this
#include <stdio.h>
#include <stdlib.h>
int countArrayChars(char *strArray){
int i=0;
while (strArray[i] != '\0'){
i++;
}
printf("%d\n", i);
return i;
}
int main(int argc, const char * argv[]) {
char *dog[] = "dog";
countArrayChars(dog);
}
#include<stdio.h>
#include<conio.h>
#include<string.h>
char* strreverse(char*);
int main()
{
char *rev_string;
char *name="computer";
clrscr();
rev_string=strreverse(name);
printf("%s", rev_string);
getch();
return 0;
}
char* strreverse(char *name)
{
int length=strlen(name);
char *ptr;
char *rstr;
for(ptr=name+(length-1);ptr>=name;ptr--)
{
*rstr=*ptr;
printf("%c",rstr);
rstr++;
}
*(rstr)=NULL;
return rstr;
}
the above is my code. i tried to write a program for string reverse without using arrays. But i am not getting the output retupmoc. what is wrong in my code? how to insert null char in char*?
#include <stdio.h>
#include <conio.h>
#include <string.h>
#include <stdlib.h>
char* strreverse(const char*);
int main(){
char *rev_string;
char *name="computer";
clrscr();
rev_string=strreverse(name);
printf("%s\n", rev_string);
free(rev_string);
getch();
return 0;
}
char* strreverse(const char *name){
int length=strlen(name);
const char *ptr;
char *ret, *rstr = malloc(length + 1);
if(ret=rstr){
for(ptr=name+length;ptr != name;){
*rstr++ = *--ptr;
}
*rstr = '\0';
}
return ret;
}
You did not allocate memory to hold your reversed string. Try
char *rstr = calloc(1, length+1);
Also it should be
printf("%c", *rstr); // dereference
*(rstr)= '\0'; // instead of NULL
Here you find sweet and short solution for string reverse:
#include<stdio.h>
#include<string.h>
int strreverse(char* , char*);
int main()
{
char rev_string[10] = {0};
char name[10]="computer";
strreverse(name, rev_string);
printf("%s\n", rev_string);
return 0;
}
int strreverse(char *name, char *rStr)
{
int i = 0;
int length = strlen(name);
while(i < length)
{
rStr[i] = name[length-i-1];
i++;
}
return 0;
}
Try to run and have fun.