Passing string variable by reference - c

I've this piece of code :
#include <stdio.h>
#include <string.h>
void b(char *in, char ** out);
int main()
{
char a[] = {'w','o','r','l','d','\0'};
char *d = nullptr;
b(a, &d);
printf("hello %s\n", d);
return 0;
}
void b(char *in, char ** out)
{
char tmp[10];
for(int i=0;i<6;i++)
tmp[i]=in[i];
*out=tmp;
printf("%s\n", *out);
}
I except to get theses printf :
world
hello world
But I get these :
world
hello
Why the d variable isn't fullfilled ? :(
Thanks for any clue about that !

Inside of b(), you are setting the char* referred by out to point at a local char[] array, which is NOT being null-terminated (thus breaking "%s" in printf()), but also WILL go out of scope when b() exits, thus the caller (ie main()) ends up with a dangling char* pointer to invalid memory.
You tagged your question as c++. C++ is not C. You should use std::string instead of char[] in this situation, eg:
#include <iostream>
#include <string>
void b(const std::string &in, std::string &out);
int main()
{
std::string a = "world";
std::string d;
b(a, d);
std::cout << "hello " << d << "\n";
return 0;
}
void b(const std::string &in, std::string &out)
{
std::string tmp = in.substr(0, 6);
out = tmp;
std::cout << out << "\n";
}
Otherwise, if you really want to use char*, in C or C++, you will need to use dynamic memory allocation, eg:
#include <stdio.h> // or <cstdio> in C++
#include <string.h> // or <cstring> in C++
void b(char *in, char ** out);
int main()
{
char a[] = "world";
char *d = nullptr;
b(a, &d);
printf("hello %s\n", d);
delete[] d; // or free() in C
return 0;
}
void b(char *in, char ** out)
{
char *tmp = new char[7]; // or malloc() in C
for(int i = 0; i < 6; ++i) {
tmp[i] = in[i];
}
tmp[6] = '\0';
*out = tmp;
printf("%s\n", *out);
}

Related

"Warning: assignment makes integer from pointer without a cast" using a char malloc

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

C programming recursion question generating segfault

trying to convert any number to any base in a recursion with C:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char* anybase(int n, int b)
{
char * s;
int len;
if(n==0) {strcpy(s,""); return s;}
s = anybase(n/b, b);
len=strlen(s);
s[len] = "0123456789ABCEDFGHIGKLMNOPQRSTUVWXYZ"[n%b];
s[len+1]='\0';
printf ("%s, %d, %d\n", s, n, b);
/* return s; */
}
int main(){
char *s;
s = anybase(900000, 18);
/*printf ("%s, %d, %d\n", anybase(90000, 18), 90000, 18);*/
}
is it the recursion having a problem? not sure why one can't return a value in the function call. what would be needed to call this recursion function and return a value instead of void.
Why is it generating seg fault each time running it? Thanks!
You were pretty much there, except you never allocated any memory for the string you're trying to produce. Here's a version which (apparently) runs correctly:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char* anybase(int n, int b)
{
char *s;
int len;
if(n == 0)
{
s = malloc(200);
s[0] = '\0';
}
else
{
s = anybase(n/b, b);
len=strlen(s);
s[len] = "0123456789ABCEDFGHIGKLMNOPQRSTUVWXYZ"[n%b];
s[len+1]='\0';
}
return s;
}
int main()
{
char *result;
result = anybase(900000, 18);
printf("%s\n", result);
free(result);
}
Note that since the buffer returned by anybase is allocated dynamically (using the malloc library function) it must be free'd after use.
As others mentioned the issue is s is just a pointer that points to no where.
But instead of allocating memory for s inside of your anybase function a better approach is to allocate the memory in the main function. This avoids possible memory leaks when calling the function multiple times.
#include <stdio.h>
#include <string.h>
void anybase(int n, int b, char* s)
{
int len;
if(n==0) {strcpy(s,""); return;}
anybase(n/b, b, s);
len=strlen(s);
s[len] = "0123456789ABCEDFGHIGKLMNOPQRSTUVWXYZ"[n%b];
s[len+1]='\0';
printf ("%s, %d, %d\n", s, n, b);
printf("%d\n", len +1);
return;
}
int main(){
char s[33]; /* enough for all ints with base 2 */
anybase(90000, 18, s);
return 0;
}
The string buffer can be created statically in the main function but must then be passed to each recursive function call such that it can be written in to.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define BUFFER_SIZE 200
const char *selection = "0123456789ABCEDFGHIGKLMNOPQRSTUVWXYZ";
void anybase(int n, int b, char *s)
{
if (n) {
anybase(n / b, b, s);
strncat(&s[strlen(s)], &selection[n % b], sizeof(char));
printf("%s, %d, %d\n", s, n, b);
}
}
int main()
{
char buf[BUFFER_SIZE];
memset(buf, 0, sizeof(char) * BUFFER_SIZE);
anybase(900000, 18, buf);
printf("Ouput: %s, N: %d, B: %d\n", buf, 90000, 18);
}

How to pass 2d array of string to the function and print value of it?

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.

Receiving a string as a void pointer parameter and using strcpy to change it

Here's the code:
#include <stdio.h>
#include <string.h>
void print (void*);
int main (void)
{
char *a = "Mcwhat";
print(&a);
printf("\n%s", a);
return 0;
}
void print (void *text)
{
char* pchar[5];
*pchar = (char*)text;
strcpy( *pchar, "Mcthat" );
}
I am trying to make Mcwhat into Mcthat using a void parameter, but the printf gives me a segmentation fault afterwards. Where is my mistake? I managed to do it char by char but now I want to change the whole string. Didn't found enough material on this in the books on C I have.
Keep it simple and pay attention to the type of your variables :
#include <stdio.h>
#include <string.h>
void print (void*);
int main()
{
char a[] = "Mcwhat"; // a is now a read-write array
print(a); // a decays to a pointer, don't take its adress or you'll get a pointer-to-pointer
printf("\n%s", a);
return 0;
}
void print (void *text)
{
strcpy( text, "Mcthat" ); // Don't dereference text here
}
Note that this "print" function is unsafe in all imaginable ways, but that wasn't the question.
There are lot of issues in your code:
1. Char array should be big enough to store the string. char[5] cannot hold Mswhat.
2. char* pchar [5] declares 5 char pointers, whereas you need one char pointer pointing to a char array.
I have corrected it.
#include <stdio.h>
#include <string.h>
void print (char*);
int main (void)
{
char *a = malloc(10);
strcpy(a,"Mcwhat");
print(a);
printf("\n%s", a);
free(a);
return 0;
}
void print (char *text)
{
char *pchar = text;
strcpy( pchar, "Mcthat" );
}
Just write it like that
void print (char *text)
{
strcpy( text, "Mcthat" );
}
But make sure, the that size of text is large enough to put "Mcthat" inside it.
Also in main:
print(a);
instead of
print(&a); // would requite void print (char** text)
tho whole shebang:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
void print (void*);
int main (void)
{
char *a = malloc(strlen("Mcwhat")+1);
print(a);
printf("\n%s\n", a);
free(a);
return 0;
}
void print (void *text)
{
strcpy(text, "Mcthat" );
}

Right Justified Zero filled String in C

I want to right justify a string value with zero filled on left hand side. I have written following code but it prints white space instead of 0.
#include<stdio.h>
int main()
{
char s[4]="PJ";
printf("%04s",s);
}
Output: " PJ"
I need output as "00PJ".
You can do something like this :
#define MIN_LEN 4
if (strlen(s) < MIN_LEN) {
printf("%0*d%s", MIN_LEN-(int)strlen(s), 0, s);
}
else {
printf("%s", s);
}
Don't forget to include <string.h>
Edit :
To explain our discussion about buffer overflow, just try this piece of code :
int main()
{
struct
{
char s[4];
int i;
} test;
test.i = 0x12345678;
strcpy(test.s,"PJHA");
printf("Output =%s\nTest =%x",test.s,test.i);
}
Output :
Output =PJHA
Test =12345600
If you change the size to 5, the code is corrected and the stack following your string is not corrupted.
Here is the short line code answer for my question:-
This will take care of any length of input variable like s = "J", s="JH", s="JHA", s="PJHA"
and corresponding output will be "000J", "00JH", "0JHA", "PJHA" .
#include<stdio.h>
#include<string.h>
int main()
{
char s[4],s2[4];
strcpy(s,"JH");
sprintf(s2,"%04s",s);
memset(s2,'0',4-(int)strlen(s));
printf("Output =%s\n",s2);
}
Output =00JH
Appreciate the above simpler solution while giving an alternative more manual one:
#include<stdio.h>
#include<string.h>
void print(char *s, int ncount)
{
if(s == NULL) return;
int len = strlen(s);
if(len > ncount) printf("%s", s);
else {
for(int i = 0; i < ncount - len; ++i)
printf("0");
printf("%s", s);
}
}
int main()
{
char s[4]="PJ";
print(s, 4);
return 0;
}
#include <stdio.h>
#include <string.h>
int main(){
char s[5]="PJ";
char padding[sizeof(s)] = {0};
int width = sizeof(padding)-1;
memset(padding, '0', width);
width -= strlen(s);
//printf("%.*s%s\n", (int)(4-strlen(s)), "0000", s);
printf("%.*s%s\n", width, padding, s);
return 0;
}

Resources