How to pass array from library in c - c

I'm new in c programming and I want to pass array from library.
I have function in library c file that creates char array. How to use this array in main function. This is short code of something I tried:
libfile.c
char *myArray;
void PopulateArray()
{
// Getting data from serial port in char buffer[100]
myArray = buffer;
}
libfile.h
exter char *myArray;
void PopulateArray();
program.c
int main()
{
// in fore loop
printf("%s\n" , myArray[i]);
}
This is just one of combinations that I have tried but nothing works.
How to do this?

To pass an array from a library function to the surrounding code, you can use the return value of a function or use a pointer-to-pointer argument.
See the following example code.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char* createSourceCopy() {
const char *source = "Example Text";
// We got some text in variable source;
const size_t sourceSize = strlen(source);
char *result = (char*)malloc(sizeof(char)*(sourceSize+1));
strncpy(result, source, sourceSize);
return result;
}
A user of your library could use the function like this:
main() {
char *result = createSourceCopy();
// Do something with result.
// After the use, destroy the array
delete[] result;
return 0;
}
Another way how to pass an array is this:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
bool copySourceText( char **outText ) {
const char *source = "Example Text";
// We get some text in variable source;
const size_t sourceSize = strlen(source);
*outText = new char[sourceSize];
strncpy(*outText, source, sourceSize);
return true; // success
}
This second variant has the benefit that the return value can be used as status. The function could return true on success, or false if there was an error.
This second version can be used like this.
int main() {
char *result;
if (copySourceText(&result)) {
// Do something with result.
// After the use, destroy the array
free(result);
result = NULL;
} else {
// Error handling
}
return 0;
}

It's not clear exactly what's going wrong in the code you posted (it would help to see more code), but assuming your problem isn't a compilation error, one of these lines might be wrong:
char *myArray;
printf("%s\n" , myArray[i]);
char *myArray declares a pointer to char (which would be appropriate for a single string).
The printf line dereferences myArray (producing a char, i.e. one character). You're passing down a char, but the %s format expects a pointer-to-char.
If you want to print the string character-by-character, you could use %c:
for (i = 0; i < length; i++) {
printf("%c\n", myArray[i]); /* or %x or %d if you want */
}
Otherwise, if myArray is one string and is null-terminated (see Why is a null terminator necessary?), then you could do:
printf("%s\n" , myArray); /* [i] removed, no for loop necessary */

Related

passing string to a pointer in c

I am fairly new in C. I want to assign string in a function to a pointer but I have no idea why it is not working?
This is the initial code:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <stdint.h>
#include <stdbool.h>
#include <string.h>
void test(char* result) {
*result = "HELLO";
}
int main() {
char result[64];
test(result);
printf("%s", *result);
}
This is the error: warning: assignment makes integer from pointer without a cast. Since * result should store value and result is the address, shouldn't this work out?
Hello and welcome to C.
Your statement:
*result = "HELLO";
is the same as attempting to do the following:
result[0] = "HELLO"
which is attempting to set a single character to a string, and you can't do that.
you will need to copy the string character by character
luckily there is a function for that which you have included already with <string.h> called strcpy
strcpy(result,"HELLO")
This will work as long as your string to copy is fewer than 63 characters as you have defined in your main() function.
char result[64];
you should probably also send the length of the string to the test function and use strncpy
strncpy(result,"HELLO",length); // safe copy
and then terminate the string with '\0'
result[length-1] = 0;
your printf doesn't need to dereference the string pointer. So simply printf("%s",result); is fine.
so in summary:
void test(char* result,uint32_t len) {
strncpy(result,"HELLO",len); // safe copy (however "HELLO" will work for 64 length string fine)
result[len-1] = 0; // terminate the string
}
#define MY_STRING_LENGTH 64
int main() {
char result[MY_STRING_LENGTH ];
test(result,MY_STRING_LENGTH);
printf("%s",result); // remove *
}
You declared an array in main
char result[64];
Passed to the function it is converted to rvalue of the type char * that points to the first element of the array. The function deals with a copy of this pointer. Changing this copy of the pointer fors not influence on the original array.
Within the function the expression *result has the type char. So this assignment
*result = "HELLO";
does not make a sense.
In this call
printf("%s", *result);
there is again used an incorrect expression of the type char *result.
What you need is to use standard string function strcpy.
For example
#include <stdio.h>
#include <string.h>
void test(char* result) {
strcpy( result, "HELLO" );
}
int main( void ) {
char result[64];
test(result);
puts( result );
}
Problem:
When you store a character in a char varible,it puts the ASCII of the character in the memory.
char c='a';is the same aschar c=97;
You can verify this by using the code:
char c='a';
printf("%d",c);
So here is one way:
void test(char* result) {
*result++ = 'H';
*result++ = 'E';
*result++ = 'L';
*result++ = 'L';
*result = 'O';
}
int main() {
char result[64];
test(result);
printf("%s", result);
}
But it is redundant because there is a function called strcpy in <string.h>.
#include <stdio.h>
#include <string.h>
void test(char* result) {
strcpy( resul, "HELLO" );
}
int main() {
char result[64];
test(result);
puts( result );
}
Remove the '*' of the variable "result" after you've declared it and use the function "strcpy()" in your code.

What's wrong with my code function to make strcat function in C?

#include <stdio.h>
#include <stdlib.h>
char wordsum(char FW[256],char SW[256]){
int i;
int j=strlen(FW);
for (i=0;i<=strlen(SW);i++)
FW[i+j+1]=SW[i];
printf("%c",FW);
return FW;
}
int main()
{
char F[256];
char S[256];
printf("Enter the first word\n");
gets(F);
printf("Enter the Second word\n");
gets(S);
wordsum(F,S);
return 0;
}
I don't know what is wrong with my code to make strcat function. I hope to find the answer.
I assume that the code is written to learn more about the C language. If so, may I present an alternative implementation which does not use strlen(). The intention is to present some of the really nice features in the language. It may be a bit complicated to wrap ones head around the first time, but IIRC the code can be found in K&R's book The C Programming Language.
Here we go:
char* mystrcat(char *dest, const char *src)
{
char *ret = dest;
while (*dest)
dest++;
while ((*dest++ = *src++))
;
return ret;
}
The first while-loop finds the end of the destination string. The second while-loop appends the source string to the destination string. Finally, we return a pointer to the original dest buffer.
The function could've been even nicer if it didn't return a pointer.
void mystrcat(char *dest, const char *src)
{
while (*dest)
dest++;
while ((*dest++ = *src++))
;
}
HTH
There are several mistakes in your code. They are:
1) A function can't return an array in C and you don't need to do so. Change the return type from char to void of wordsum and erase the line return FW;
2) You want to print a string, right? Format specifier for string is %s. So write printf("%s",FW); instead of printf("%c",FW);.
3) Do this: FW[i+j]=SW[i];. Why did you add an extra 1 to i+j? Just think logically.
4) Add header file for strlen(), it's <string.h>.
5) Erase those asterisk marks before and after FW[i+j]=SW[i];.
There are a few problems in your function, I've changed and commented them below:
char *wordsum(char FW[256],char SW[256]){ // correct function type
int i;
int j=strlen(FW);
for (i = 0; i <= strlen(SW); i++)
FW[i+j] = SW[i]; //change 'i + j + 1' to 'i + j'
printf("%s",FW); //change format specifier as you are printing string not character
return FW;
}
Then dot forget to capture the returned pointer using a char* variable in the calling function (here main())
char *result;
result = wordsum(F,S);
printf("\n%s\n", result);
Working example: https://ideone.com/ERlFPE

How to return a multidimensional character array from a function in a header file in C

I have a main file, and a header file.
In main file, I want to return a 2D char array from a char function from header file. My char function is as following:
char character_distribution(int length, char redistribution[length][2])
{
char *buffer, distribution[256][2] = {0};
long lSize;
struct Bar result = funct();
buffer = result.x;
lSize = result.y;
length = collect_character_distribution(buffer, lSize, distribution);
reorganize_character_distribution(length, distribution, redistribution);
return redistribution;
}
And my main function is as follows:
#include <stdio.h>
#include "character_distribution.h"
void main()
{
int length;
char distribution[length][2];
distribution = character_distribution(length, distribution[length][2]);
int a;
for(a = 0; a < length; a++)
{
printf("%c\n", distribution[a][0]);
}
}
When I run my code, I get the following error:
warning: return makes integer from pointer without a cast
How can I fix the problem?
void character_distribution(int length, char redistribution[][2])
{
char *buffer, distribution[256][2] = {0};
long lSize;
struct Bar result = funct();
buffer = result.x;
lSize = result.y;
length = collect_character_distribution(buffer, lSize, distribution);
reorganize_character_distribution(length, distribution, redistribution);
}
int main()
{
int length = 2; //initialize
char distribution[length][2];
character_distribution(length, distribution);
int a;
for(a = 0; a < length; a++)
{
printf("%c\n", distribution[a][0]);
}
return 0;
}
If you really have to return the 2d array, one way (easy way) is to just put it in a struct
struct distribution_struct {
char x[256];
char y[2];
};
struct distribution_struct character_distribution(int length, char redistribution[][2]) {
struct distribution_struct dis;
//initialize the struct with values
//return the struct
}
And another way is to manually allocate memory for the 2d array in the function and return it
char** character_distribution(int length, char redistribution[][2]) {
//use malloc to create the array and a for loop to populate it
}
You cannot actually return an array from a C function. You can, however, return a pointer to such an array. The correct declaration in that case is:
char (*character_distribution(int length, char redistribution[][2]))[][2]
Sizing the initial dimension is not necessary and not, I suspect, actually conformant with standard C (at least, sizing it with length as you did in your question looks dubious to me). This is because arrays are passed by reference implicitly (and in this case, returned by reference explicitly) and it is not necessary to know the first dimension in order to calculate the address of an element having been given a pointer to the array (and the indices).
Note that you should not return a pointer to an array that is scoped locally to the function, since its storage is deallocated once the function returns (and such a pointer would then be invalid).
However, your question shows that you don't really need to return an array. Since arrays are passed by reference anyway, altering the passed-in array will causes changes that are also visible to the caller. Your code could be written as:
void character_distribution(int length, char redistribution[][2])
{
char *buffer, distribution[256][2] = {0};
long lSize;
struct Bar result = funct();
buffer = result.x;
lSize = result.y;
length = collect_character_distribution(buffer, lSize, distribution);
reorganize_character_distribution(length, distribution, redistribution);
}
And
#include <stdio.h>
#include "character_distribution.h"
void main()
{
int length = 256; // you need to initialise this...
char distribution[length][2];
// No assignment needed here!:
character_distribution(length, distribution /* [length][2] - remove this! */);
int a;
for(a = 0; a < length; a++)
{
printf("%c\n", distribution[a][0]);
}
}
(Of course this relies on the various other functions you call performing as they are supposed to).
Change the signature to this:
char** character_distribution(int length, char redistribution[length][2])
You are returning a multidimensional array, not a character.

How to Return Char Array?

As you can see I have this code it takes a command (char array ) and divides it into two diffrent arrays if there is "|" between them.What I want is not to print it with the function but return these two new arrays to main and then print them ?
How can I do it ?
#include <fcntl.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <stdlib.h>
#include <unistd.h>
int main()
{
int a;
int status,n,i;
char command[4000];
write(STDOUT_FILENO,"Shell>",6);
n=read(STDIN_FILENO,command,4000);
void getArguments(char **,char*);
char *getStdOutFileName(char *);
if(n>0)
{
for(i=0;i<n;i++)
{
bugrafonk(command,&i);
printf("%s",First);
printf("%s",Second);
}
}
}
void bugrafonk(char* c,int*length)
{
int i;
int a;
char First[4000];
char Second[4000];
for(i=0;i<length;i++)
{
if(c[i]=='|')
{
i=a;
for(i=0;i<a;i++)
{
char First[i];
}
printf("---");
for(i=a;a<length;i++)
{
char Second[i];
}
}
}
return(First,Second); //is this true ?
}
There are some unnecssery declaration in the main now just avoid them I will use them later on.
To retun char * to main you need to send pointers to your function which are attached to memory that you can use
For example,
....
char return1[50]
char return2[50]
....
split_function(command, return1, return2);
....
The answer depends on where you store the results of your calculations.
In your current implementation both First and Second arrays are allocated inside the bugrafonk function and thus will be destroyed when the function is finished.
One possible option would be to allocate memory for result arrays outside the function and pass pointers to the function.
char first[4000], second[4000];
bugrafonk(..., first, second);
// use first and second
And bugrafonk implementation:
void bugrafonk(your arguments..., char *first, char *second)
{
...
}
Also, I have no idea what the mysterious word bugrafonk means ;)
The function implemented here splits the string by terminating the first part, and returns a pointer to the second part.
You don't need to return 2 pieces of information since you already know where the first string is. Note that this will not work if a string literal is passed since you cannot modify it, but that's not the case here.
#include <stdio.h>
#include <string.h>
char* bugrafonk(char* c); // function prototype
int main(void)
{
char command[4000];
char *split;
scanf("%3999s", command); // enter limited length string
split = bugrafonk(command); // this splits the string
printf("First part: %s\n", command); // print first half
if (split != NULL) // if there is a second half
printf("Second part: %s\n", split); // print second half
}
char* bugrafonk(char* c) // returns string pointer
{
char *cptr = strchr(c, '|'); // find that char
if (cptr != NULL) // if it was found
{
*cptr = '\0'; // terminate first part here
cptr++; // advance pointer to next part
}
return cptr;
}
Program output:
one|two
First part: one
Second part: two
You may choose to return a pointer to char, and then pass two arrays that will be modified in the body of the function.:
char *func(char arr[], char* arr2 /* other parameters */)
{ /* process arr and arr2 */
// return new array one. arr2 doesn't need to be returned.
return arr;
}
// in main:
char command[4000];
char arr2[4000]; // First
char *arr3 = func(command, arr2); // Second
Or just pass all arrays as arguments to the function and then return void, since they will be modified in the function.

Want to pass a single char pointer from a double pointer

I have to write a function which takes in 2 double pointers (both to char type). The first double pointer has a string of query values and the 2nd one has stopwords. The idea is to eliminate the stopwords from the query string and return all the words without those stopwords.
For example
Input - query: “the”, “new”, “store”, “in”, “SF”
stopwords: “the”, “in”
OUTPUT
new
store
SF
I have written the following code while trying to use strtok which takes in only single pointers to char types. How do I access the contents of a double pointer?
Thanks
#include <stdio.h>
void remove_stopwords(char **query, int query_length, char **stopwords, int stopwords_length) {
char *final_str;
final_str = strtok(query[0], stopwords[0]);
while(final_str != NULL)
{
printf("%s\n", final_str);
final_str = strtok(NULL, stopwords);
}
}
For simplicity's sake, you can assume a double pointer to be equivalent to a 2d array (it is not!). However, this means that you can use array-convention to access contents of a double pointer.
#include <stdio.h>
#include <string.h>
char *query[5] = {"the","new","store","in","SF"};
char *stopwords[2] = {"the","in"};
char main_array[256];
void remove_stopwords(char **query,int query_length, char **stopwords, int stopwords_length);
int main()
{
remove_stopwords(query,5,stopwords,2);
puts(main_array);
return 0;
}
void remove_stopwords(char **query,int query_length, char **stopwords, int stopwords_length)
{
int i,j,found;
for(i=0;i<query_length;i++)
{
found=0;
for(j=0;j<stopwords_length;j++)
{
if(strcmp(query[i],stopwords[j])==0)
{
found=1;
break;
}
}
if(found==0)
{
printf("%s ",query[i]);
strncat(main_array,query[i],strlen(query[i]));
}
}
}
Output: new store SF newstoreSF
#Binayaka Chakraborty's solution solved the problem but I thought it might be useful to provide an alternative that used pointers only and showed appropriate use of strtok(), the use of which may have been misunderstood in the question.
In particular, the second parameter of strtok() is a pointer to a string that lists all the single-character delimiters to be used. One cannot use strtok() to split a string based on multi-character delimiters, as appears to have been the intention in the question.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
void remove_stopwords(char *query, char **stopwords) {
char *final_str = strtok(query, " ");
while(final_str != NULL) {
int isStop = 0;
char **s;
for (s = stopwords; *s; s++) {
if (strcmp(final_str,*s) == 0) {
isStop = 1;
}
}
if (!isStop) printf("%s ", final_str);
final_str = strtok(NULL, " ");
}
}
int main() {
const char *q = "the new store in SF";
char *query = malloc(strlen(q)+1);
/* We copy the string before calling remove_stopwords() because
strtok must be able to modify the string given as its first
parameter */
strcpy(query,q);
char *stopwords[] = {"the", "in", NULL};
remove_stopwords(query,stopwords);
return 0;
}
The approach shown here also avoids the need to hard code the sizes of the arrays involved, which therefore reduces potential for bugs.

Resources