How do I pass an argument of string arrays e.g *p[50]?
void sortnames(char array[],int low,int high){
int mid;
if(low<high){
mid=(low+high)/2;
sortnames(array,low,mid);
sortnames(array,mid+1,high);
mergeSort(array,low,mid,high);
}
}
the code
Method to define
char *arr_ofptr[];
Example to fill its elements.Here filling first element
arr_ofptr[0] = "John Smith";
method to pass this array as argument
func(arr_ofptr,..
Method to pass perticular element of this array
func(arr_ofptr[nth], ..
You can do:
void sortnames(char **names, int low, int high, int num_names, int *sizes)
Here you pass the array of names on the first parameter. The size of the first coordinate has to be num_names, so you don't get into segmentation fault problems. Then you can pass on the last parameter an array with the length of each string. This last parameter must also be of size num_names, and then sizes[i] would inficate the length of string names[i].
EDIT: A segmentation fault is an error that you'll get whenever you're accessing memory that you are not allowed to be touching in C. That usually arrives when you are accessing array elements out of bounds. In order to avoid this, you have to make sure to allocate enough space for your arrays using an appropriate call to malloc. So, for example, in order to call your sortnames function, you should declare before an array of strings more or less like this (I say more or less because I don't know the context in which you're executing):
int num_names // This is the number of names you want to read
// Populate the variable num_names
// ...
char **to_sort = malloc(num_names * sizeof(char *));
int i;
for(i = 0; i < num_names; ++ i)
{
to_sort[i] = malloc(max_name_size); // Here max_name_size is a static value
// with the size of the longest string
// you are willing to accept. This is to
// avoid you some troublesome reallocation
}
// Populate the array with your strings using expressions like
// to_sort[i] = string_value;
//...
int *sizes = malloc(num_names * sizeof(int));
for(i = 0; i < num_names; ++ i)
{
sizes[i] = strlen(to_sort[i]);
}
sortnames(to_sort, 0, num_names, sizes);
And remember to null-terminate your strings to avoid segmentation faults on the call to strlen.
you can do this:
void sortnames(char *array,int low,int high)
{
int mid;
if(low<high)
{
mid=(low+high)/2;
sortnames(array,low,mid);
sortnames(array,mid+1,high);
mergeSort(array,low,mid,high);
}
}
with char *array you pass the address of the fist element of the array..
i hope this help..
Related
I want to filter an strings array passed in, something like this:
char **
filter_vids(char **vids, size_t n) {
int i;
int count = 0;
char ** filted = malloc(n * sizeof(char *));
for(i = 0; i < n; i++){
filted[i] = (char*)malloc(50 * sizeof(char));
}
for(i = 0; i < n; i++) {
if(some_filter(vids[i])) {
strcpy(filted[count++], vids[i]);
printf("in filter:%s\n", vids[i]);
}
}
return filted;
}
But the caller may not known the length of return array, it's extractly the counter variable, so what's the best practice of returning an array while telling him the right length of array?
such as
char **
filter_vids(char **vids, size_t n, int *output_length)
It's the best practice of using output_length?
I edit this function to this, as your suggestions:
char **
filter_vids(char **vids, size_t n) {
int i;
int count = 0;
char ** filted = malloc((n + 1) * sizeof(char *));
for(i = 0; i < n; i++) {
if(vids[i][0] <= 'f') {
filted[count++] = strdup(vids[i]);
}
}
filted[count] = NULL;
return filted;
}
To pass a pointer to an integer length variable whose value is then set in the function is certainly a good way. As Malcolm said, it is also general and can be used for sets of values which do not have an "invalid" member.
In the case of pointers with their invalid null pointer value one can mark the end of valid entries with a null pointer. For example, the array of string pointers which the C run time uses to pass command line arguments to main is thus terminated.
Which method to choose depends a little on how the caller wants to use the resulting array. If it is processed sequentially, a (while *p){ ..; ++p; } feels idiomatic. If, on the other hand, you need random access and must perform the equivalent of a strlen before you can do anything with the array, then it is probably better to return the length via a pointed-to length variable right away.
Two remarks:
First, note the difference between
a valid pointer to an empty string (if somebody called, let's say, myProg par1 "" par2, argv[2] could be a valid pointer to a zero byte);
and a null pointer which is pointing nowhere; in the example, argv[4] would be the null pointer, indicating the end of the argument list.
Second, You malloc more memory than you need which is wasteful in the case of longer strings and/or strict filters. You could instead allocate the string on demand inside the if clause.
These are common options:
Receive the allowed size as parameter by pointer, overwrite it with the actual size, return the array as return value.
Receive the output array as parameter by pointer, update as required, return the actual size as return value.
Append a sentinel value to the output array (here a null pointer), as suggested in the other answer.
Use a more sophisticated data structure as a return value. You could use a struct, which stores the size alongside the array or a linked list.
Example (untested):
typedef char* mystring;
typedef mystring* mystringarray;
typedef struct { mystringarray *arr; size_t size } mysizedstringarray;
/* returns filtered array, size will be updated to reflect the valid size */
mystringarray* myfun1(mystringarray in, size_t* size);
/* out will be allocated and populated, actual size is returned */
size_t myfun2(mystringarray in, size_t size, mystringarray* out);
/* output array contains valid items until sentinel value (NULL) is reached */
mystringarray* myfun3(mystringarray in, size_t size);
/* returns filtered array with actual size */
mysizedstringarray myfun4(mystringarray in, size_t size);
I have a trouble regarding to multi-dimensional array in C.
We have to make a multi-dimensional array in which in which the user has to input the size of the array. After that according to the size C has to create a multi-dimensional array. Remember, in the center there always has to be '1'.
At every side of one there should be '2'. on every side of '2' there should be '3', depends upon the size of array. Also shown in image.
can locate the mid point of an array but when i do this: int Array[size/2][size/2] it gives me error. and how i can adjust other 2,3 and and other numbers at the sides?
This is the code I have written for now:
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
int main(){
const size;
printf("Enter the size: ");
scanf("%d", &size);
int Grid[size][size];
Grid[size/2][size/2] = 1;
printf("%d", Grid[1][1]);
return 0;
}
Firstly, you shall not do such a thing in C :
int grid[size][size];
If you're interested in knowing why, look at C11's Initialization paragraph :
No initializer shall attempt to provide a value for an object not contained within the entity being initialized.
The type of the entity to be initialized shall be an array of unknown size or a complete object type that is not a variable length array type.
Then, I'm not a fan of
const size;
Since the type is not explicit and your variable isn't const here. Even if you're using scanf, you do modify the value of size during the function.
But then, let's hit the problem ;)
I suggest you use a function to allocate your array. It will help clarifying your code :
int** create_array(int size)
{
int i;
int** array;
i = 0;
// You allocate the first dimension of your array
// (the one that will contain other arrays)
array = malloc(size * sizeof(int *));
if (array != NULL)
{
while (i < size)
{
// You allocate each 'sub-array' that will contain... ints !
array[i] = malloc(size * sizeof(int));
i += 1;
}
}
return (array);
}
Now this function returns a well-allocated array of the size you want. Don't forget to check if it's NULL in your calling function, and to free it (if it has been allocated).
To free the array, I'll let you write the function yourself, since it is very similar to the initialization. But still, be careful considering some sub-array might be NULL!
Then the initialization. The most simple way I can think of is iterating on your array and calculating the delta from the center.
int most_far;
////
/// Insert the loop stuff here...
//
if (x == size/2 && y == size/2)
array[x][y] = 1;
else
{
// You could use a ternary here but I don't know if you're familiar with them
// You're getting the position that is the most far from center...
if (abs(x - size/2) > abs(y - size/2))
most_far = abs(x - size/2);
else
most_far = abs(y - size/2);
// With this position, you calculate the 'distance' between the center and your position.
// This distance is your number ! :D
array[x][y] = most_far;
}
//
/// End of the loop, interations, etc...
////
Little tip : I suggest you do the population stuff in some function that returns a boolean. This boolean will be false if one sub-array has been found NULL during the population. And if it's the case, you probably don't want to read/display it !
Pfiouh, what a massive answer I wrote !
Hope it won't scare you (and that you'll find some help in it)
If your targeted element is in position a[2][2] then the condition will be some what like this.
Consider i to be row and j to be column.
if(a[i+1][j]==a[i+1][j+1]==a[i+1][j-1]==a[i][j+1]==a[i][j-1]==a[i-1][j]==a[i-1][j+1]==a[i-1][j-1])
flag=1; \\any process you want
and you can only assign constant to an array while declaring it. You can't assign a value like
int array[size/2][size/2];
There are two ways of doing this you might consider:
Filling entries in a growing square. (i.e., filling all the 1s, then the 2s, then the 3s, ...)
Figuring out a "formula" or procedure for each row.
Looking at the first method:
void fillSquare(int **arr, int n, int size)
{
fillSquareTopSide(arr, n, size);
fillSquareLeftSide(arr, n, size);
fillSquareRightSide(arr, n, size);
fillSquareBottomSide(arr, n, size);
}
where n is the current number (1, 2, or 3) and size is 3. And then a possible implementation of fillSquareTopSide:
void fillSquareTopSide(int **arr, int n, int size)
{
for(int i = size - n; i < size + n; i++)
arr[size - n][i] = n;
}
I want to use only studio.h library to convert from decimal number to binary number by using an array to store remainder but the result is not correct, maybe i have problem with memory allocation or return value is wrong, please help me to check it.
Thank you so much!
#include <stdio.h>
int n = 0;
int* DecimalToBinary(int number){
int a[10];
while(number!=0){
a[n++] = number%2;
number/=2;
}
return a;
}
void main(){
int *d1 = DecimalToBinary(5);
int *d2 = DecimalToBinary(10);
for(int i = n-1 ;i>=0;i--)
printf(" %d",d1[i]);
printf("\n");
for(int i = n-1 ;i>=0;i--)
printf(" %d",d2[i]);
}
You return a pointer to a local array. That local array is on the stack, and when the function returns the array goes out of scope and that stack memory will be reused when you call the next function. This means that the pointer will now point to some other data, and not the original array.
There are two solutions to this:
Declare the array in the function calling DecimalToBinary and pass it as an argument.
Create the array dynamically on the heap (e.g. with malloc) and return that pointer.
The problem with method 2 is that it might create a memory leak if you don't free the returned pointer.
As noted by Craig there is a third solution, to make the array static inside the function. However in this case it brings other and bigger problems than the two solutions I originally listed, and that's why I didn't list it.
There is also another serious problem with the code, as noted by Uchia Itachi, and that is that the array is indexed by a global variable. If the DecimalToBinary function is called with a too big number, or to many times, this global index variable will be to big for the array and will be out of bounds for the array.
Both the problem with dereferencing a pointer to an out-of-scope array and the indexing out of bounds leads to undefined behavior. Undefined behavior will, if you're lucky, just lead to the wrong result being printed. If you're unlucky it will cause the program to crash.
You are returning a pointer to a locally allocated array. It is allocated on the stack, and goes away when the function returns, leaving your pointer pointing to garbage.
You have a few options. You could pass an array in to fill:
void DecimalToBinary(int result[10],int number){
while(number!=0){
result[n++] = number%2;
number/=2;
}
return result;
}
// usage example:
int b[10];
DecimalToBinary(b, 42);
Or you could allocate an array on the heap:
int* DecimalToBinary(int number){
int *a = (int *)malloc(sizeof(int) * 10);
while(number!=0){
a[n++] = number%2;
number/=2;
}
return a;
}
// usage example
int *b = DecimalToBinary(42);
free(b); // when finished with it
Or you could wrap the array in a struct:
typedef struct {
int b[10];
} result;
result DecimalToBinary(int number){
result r;
while(number!=0){
r.b[n++] = number%2;
number/=2;
}
return r;
}
// usage example
result r = DecimalToBinary(42);
If you do the malloc() option, do not forget to free() the returned data when you're done with it, otherwise it will hang around. This is called a memory leak. In more complex programs, it can lead to serious issues.
Note: By the way, if your number is larger than 1023 (10 binary digits), you'll overrun the array. You may also wish to explicitly stop once you've stored 10 digits, or pass the size of the array in, or compute the required size first and allocate that much space. Also, you will get some odd results if your number is negative, you might want to use number&1 instead of number%2.
Note 2: As noted elsewhere, you should make n local, or at the very least reinitalize it to 0 each time the function is called, otherwise it will just accumulate and eventually you'll go past the end of the array.
int[10] is not the same as int *; not only is the former created on the stack, it is a different type alltogether. You need to create an actual int * like so:
int *a = malloc (10 * sizeof (int));
Of course, don't forget to free() it after use!
What you can also do and what is commonly done in C is creating the array where it is called and provide a pointer to that array to the function, this way when the array is on the stack of the function that calls it and not in the function self. We also have to specify the size of the array on to that function, since the function cannot know to how many elements the pointer points to
void DecimalToBinary( int number, int* output, unsigned size ) {
/*adapt this to your liking*/
int i;
for ( i = 0; i < size && number != 0; i++) {
output[i] = number%2;
number/2;
}
}
and in you main function you would call it like this:
int array[10];
DecimalToBinary( 5, array, sizeof(array)/sizeof(array[0]));
now array has the same result as a would have had in your example.
The problem in your code lies here..
int * DecimalToBinary(int number){
int a[10];
while(number!=0){
a[n++] = number%2;
number/=2;
}
return a;
}
The array a scope is only till this function. Once this function terminates, the memory allocated for this array will be released, either u need to use dynamic memory allocation or make array a global.
This is the correct program:
#include <stdio.h>
int n = 0;
int a[10] = {0};
int* DecimalToBinary(int number){
n = 0;
while(number!=0){
a[n++] = number%2;
number = number/2;
}
return a;
}
int main(){
int *d1;
int *d2;
int i;
d1 = DecimalToBinary(5);
for(i = n-1;i>=0;i--)
printf(" %d",d1[i]);
printf("\n");
d2 = DecimalToBinary(10);
for(i = n-1;i>=0;i--)
printf(" %d",d2[i]);
printf("\n");
}
Suppose I have this logical array with, which I want to split into the 1 part and the 0 part, creating two separate vectors.
So I came up with the following method:
void cut_and_uncut(long* input, int length, long* cut_part, int* cut_length, long* uncut_part, int* uncut_length){
int i;
int n_cut=0;
for(i=0;i<length;i++) n_cut+=input[i];
cut_part = vecallocl(n_cut);
uncut_part = vecallocl(length-n_cut);
*cut_length = n_cut;
*uncut_length = length-n_cut;
int index_cut = 0;
int index_uncut = 0;
for(i=0;i<length;i++){
if(input[i]==1){
cut_part[index_cut] = i;
index_cut++;
} else {
uncut_part[index_uncut] = i;
index_uncut++;
}
}
}
input is the input vector of length length (so imaginative!)
cut_part is the vector with the indices of the 1s, of length cut_length
uncut_part is the vector with the indices of the 0s, of length uncut_length
(Note: vecallocl(k) is just a shortcut for malloc(k*sizeof(long)) )
I call this function with
int len,len2;
long* cut_vec;
long* uncut_vec;
cut_and_uncut(split,matrix.m+matrix.n,cut_vec,&len,uncut_vec,&len2);
The two ints (len and len2) are correctly filled, but when I try to look into the cut_vec and uncut_vec vectors, segfault happens.
I have the hunch that I am doing something wrong with the memory, because I initialize the two pointers without them actually pointing to anything.. but then in the function, with the actual vecallocl, they should be initialized correctly.
When I print the vectors from inside this cut_and_uncut function, everything works.. when doing it outside (i.e. at the same level this function is called) it does not.
What's wrong?
Try this:
void cut_and_uncut(long* input, int length, long** cut_part,
int* cut_length, long** uncut_part, int* uncut_length)
....
// inside the function you now use `*cut_part` instead of `cut_part`, etc.
if(input[i]==1){
*cut_part[index_cut] = i;
index_cut++;
} else {
*uncut_part[index_uncut] = i;
index_uncut++;
}
and pass not the (still unallocated) pointers but the address where they reside:
long *cut_part;
long *uncut_part;
cut_and_uncut(... &cut_part, &uncut_part, ...)
This way, modifications will be retained after cut_and_uncut() returns.
Basically I have this working code that manipulates an array of strings:
for (i = 0; i < numentries; i++)
if (strcmp(compare_str, strings[i]) < 0)
break;
for (j = numentries; j > i; j--)
strcpy(strings[j], strings[j - 1]);
strcpy(strings[i], compare_str);
strcat(strings[i], " ");
strcat(strings[i], whole_str);
numentries++;
I want to make it so I can call to a method to do the manipulation like:
//call to method
compare(strings, numentries, compare_str, whole_str);
numentries++;
//method
void compare(char array[], int entries, char compare[], char whole[]) {
int i, j;
for (i = 0; i < entries; i++)
if (strcmp(compare, array[i]) < 0)
break;
for (j = entries; j > i; j--)
strcpy(array[j], array[j - 1]);
strcpy(array[i], compare);
strcat(array[i], " ");
strcat(array[i], whole);
}
The above code doesn't work, I know you have to use pointers some how much im not exactly sure how. How do I pass my array of characters (strings) so I can manipulate the values inside the array?
I know this is only a code snippet, but I thought it would be enough to solve my problem. if you need more of my program to help me let me know.
It crashes at the line
strcat(array[i], " ");
with the message
Program received signal SIGSEGV, Segmentation fault. 0x75bf8df6 in strcat () from C:\Windows\system32\msvcrt.dll n Single stepping until exit from function strcat, which has no line number information. 0x77776299 in ntdll!LdrGetDllHandleByName () from C:\Windows\system32\ntdll.dll
void compare(char *array[], int entries, char compare[], char whole[]) {
^
Proof: http://ideone.com/6xSaq
I would just use a double pointer (pointer to a pointer). In fact I would just use pointers instead of arrays. Eventually they all boil down to the same thing anyway.
void compare(char **array, int entries, char *compare, char *whole) {
I don't think any of the body needs to be modified.
EDIT:
Also the segmentation fault you are seeing in your code is probably occuring because of insufficient storage space. If you're using malloc for allocation use realloc to allocate enough space for the string concatenation. If you're using stack storage, then allocate enough space for every element of the array, incase you need to perform concatenations.
Given the declaration char strings[30][161];, I think you need the function to be
void compare(char array[][161], int entries, char compare[], char whole[])
because you are not passing an array of pointers to chars, you are passing an 2D array of chars. C needs to know the inner dimension of 2D arrays to do indexing correctly. See this article for details
The alternative to hardcoding sizes would be to add something like this before the function call:
char* stringPtrs[N_STRINGS];
for (i=0;i<N_STRINGS;i++) { stringPtrs[i]=strings[i]; }
compare(stringPtrs, entries, ...);