I'm new to programing and was given a task of making a function that puts one array into the other with the following criteria: a variable in the destination array will repeat only once and the source and destination array will be of the same size.
the function i came up with is:
int RemoveDup (int src[],int dst[])
//recive two array compare them and copy the src array to dst,and only the none reacuring
//numbers,the arrays must be from the same size
{
int size_src;
int size_dst;
int i,n=0;
size_src = sizeof(src)/sizeof(int);//determine the size of source array
size_dst = sizeof(dst)/sizeof(int);//determine the size of destination array
if (size_src = size_dst);//checks that the array are in the same size
{
for(i = 0;i < size_src;i++)//the loop for advancing the copying process
{
dst[i] = src[i];
}
while (i<size_dst)
{
dst[i] = dst[i++];
if (dst[i] = dst[i++])//relay on the fact that if the function will find a similar varibale, the tested varibale will be set to 0 and the other one will come out clean in the check
dst[i] = 0;//eliminating the varibale in that specific address
}
}
return dst [i];
but it doesn't seems to work and have no idea where it is going wrong.
any help or clue will be appreciated .
I noticed that you're using sizeof(src) within a function that takes int src[] as a parameter. This is not doing what you think it is doing. In C, the size of arrays is not passed to functions along with the array itself (unlike some other languages you may be familiar with). You will have to pass the actual size as a separate parameter.
Also, some printf() statements will definitely help your debugging efforts. Make sure values are what you think they should be. Hopefully you have access to an interactive debugger, that would probably be really useful for you too.
In C you cannot declare a function that takes a parameter that is an array. When you use an array declarator as a function parameter the type is silently adjusted to the corrsponding pointer type. Any explicit array size (if specified) is discarded.
In other words, when you use this:
int RemoveDup (int src[],int dst[])
it is exactly equivalent to this:
int RemoveDup( int *src, int *dst )
It should now be obvious why sizeof(src)/sizeof(int) doesn't do the calculation that you wanted it to do.
well in fact it is possible to make a function recieve an array and not a pointer (given of course the size of the array is pre-defined).
so you can use:
int RemoveDup(int src[M],int dst[N]){
.
.
.
return whatever;
I will agree though that using pointers is better.
In my opinion you should write a recursive function to do that using of course pointers.
so that the next call is (*src+1) so you look at the next cell.
the exit condition is then:
if (sizeof(src) == 0) {
//exit recursion statement.
}
Related
So I have this code:
char inte[10];
while(j<noinput) {
fscanf(circuit,"%s",inte);
vararray[count]=inte;
count++;
j++;
}
However when I print the contents of the array like this:
for (h=0;h<noinput+2;h++){
printf("%dth variable: %s\n",h,vararray[h]);
}
The elements past the first two (which are reserved for special elements) are all equal to the LAST string that I had taken in from fscanf earlier. I have no idea how one of the strings from fscanf could be equal to multiple slots in the array when I am only setting
vararray[count]=inte;
Shouldn't this mean that each element of the array will be different since I am incrementing count every time? I am so confused. I also tried doing:
fscanf(circuit,"%s",vararray[count]);
But this also did not work and gave me null elements for certain indexes.
you are doing something too wrong. By "vararray[count]=inte;" you are doing pointer assignment so all of your vararray is getting filled by same string. I am guessing you are new to C so I will answer due to that. Correct way would look something like below
Fixed size solution:
char vararray[ROWCOUNT][BUFFERSIZE];
for(count=0; j<noinput; ++count, ++j) {
fscanf(circuit,"%s",(char*)vararray[count]);
}
With dynamic memory management
char * vararray[ROWCOUNT];
for(count=0; j<noinput; ++count, ++j) {
vararray[count] = (char*)malloc(BUFSIZE);
fscanf(circuit,"%s", vararray[count]);
}
I want to warn you in the way of becoming an expert on C nowadays is somewhat madness , i mean unless you have another choice. Examples below I put and the thing you wrote are completely unsafe and unsecure...
You're not copying the string. Here's what's happening:
char *vararray[462]; // declare an array of string pointers
char inte[10]; // declare a char array (to function as a string)
for (int i = 0; i < 462; i += 1) {
// do something
vararray[i] = inte;
}
This is causing all of the items of vararray to point to the memory also referred to as inte... but you're overwriting that each time! Instead, do something like this:
#include <string.h> // write me at the top, outside main()!
char vararray[462][10]; // declare an array of strings (max length 9)
char inte[10]; // declare a char array (to function as a string)
for (int i = 0; i < 462; i += 1) {
fscanf(circuit,"%10s",inte); // use buffer size to make xscanf safer
strncpy(vararray[i], inte, 9); // copy inte, making sure not to buffer overflow!
vararray[i][9] = '\0'; // if inte is too big, a null byte won't be added to the end of the string; make sure that it's there
}
This copies the string! Your problem should go away when you do this.
I've been trying for a while now and I can not seem to get this working:
char** fetch (char *lat, char*lon){
char emps[10][50];
//char** array = emps;
int cnt = -1;
while (row = mysql_fetch_row(result))
{
char emp_det[3][20];
char temp_emp[50] = "";
for (int i = 0; i < 4; i++){
strcpy(emp_det[i], row[i]);
}
if ( (strncmp(emp_det[1], lat, 7) == 0) && (strncmp(emp_det[2], lon, 8) == 0) ) {
cnt++;
for (int i = 0; i < 4; i++){
strcat(temp_emp, emp_det[i]);
if(i < 3) {
strcat(temp_emp, " ");
}
}
strcpy(emps[cnt], temp_emp);
}
}
}
mysql_free_result(result);
mysql_close(connection);
return array;
Yes, I know array = emps is commented out, but without it commented, it tells me that the pointer types are incompatible. This, in case I forgot to mention, is in a char** type function and I want it to return emps[10][50] or the next best thing. How can I go about doing that? Thank you!
An array expression of type T [N][M] does not decay to T ** - it decays to type T (*)[M] (pointer to M-element array).
Secondly, you're trying to return the address of an array that's local to the function; once the function exits, the emps array no longer exists, and any pointer to it becomes invalid.
You'd probably be better off passing the target array as a parameter to the function and have the function write to it, rather than creating a new array within the function and returning it. You could dynamically allocate the array, but then you're doing a memory management dance, and the best way to avoid problems with memory management is to avoid doing memory management.
So your function definition would look like
void fetch( char *lat, char *lon, char emps[][50], size_t rows ) { ... }
and your function call would look like
char my_emps[10][50];
...
fetch( &lat, &lon, my_emps, 10 );
What you're attempting won't work, even if you attempt to cast, because you'll be returning the address of a local variable. When the function returns, that variable goes out of scope and the memory it was using is no longer valid. Attempting to dereference that address will result in undefined behavior.
What you need is to use dynamic memory allocation to create the data structure you want to return:
char **emps;
emps = malloc(10 * sizeof(char *));
for (int i=0; i<10; i++) {
emps[i] = malloc(50);
}
....
return emps;
The calling function will need to free the memory created by this function. It also needs to know how many allocations were done so it knows how many times to call free.
If you found a way to cast char emps[10][50]; into a char * or char **
you wouldn't be able to properly map the data (dimensions, etc). multi-dimensional char arrays are not char **. They're just contiguous memory with index calculation. Better fit to a char * BTW
but the biggest problem would be that emps would go out of scope, and the auto memory would be reallocated to some other variable, destroying the data.
There's a way to do it, though, if your dimensions are really fixed:
You can create a function that takes a char[10][50] as an in/out parameter (you cannot return an array, not allowed by the compiler, you could return a struct containing an array, but that wouldn't be efficient)
Example:
void myfunc(char emp[10][50])
{
emp[4][5] = 'a'; // update emp in the function
}
int main()
{
char x[10][50];
myfunc(x);
// ...
}
The main program is responsible of the memory of x which is passed as modifiable to myfunc routine: it is safe and fast (no memory copy)
Good practice: define a type like this typedef char matrix10_50[10][50]; it makes declarations more logical.
The main drawback here is that dimensions are fixed. If you want to use myfunc for another dimension set, you have to copy/paste it or use macros to define both (like a poor man's template).
EDITa fine comment suggests that some compilers support variable array size.
So you could pass dimensions alongside your unconstrained array:
void myfunc(int rows, int cols, char emp[rows][cols])
Tested, works with gcc 4.9 (probably on earlier versions too) only on C code, not C++ and not in .cpp files containing plain C (but still beats cumbersome malloc/free calls)
In order to understand why you can't do that, you need to understand how matrices work in C.
A matrix, let's say your char emps[10][50] is a continuous block of storage capable of storing 10*50=500 chars (imagine an array of 500 elements). When you access emps[i][j], it accesses the element at index 50*i + j in that "array" (pick a piece of paper and a pen to understand why). The problem is that the 50 in that formula is the number of columns in the matrix, which is known at the compile time from the data type itself. When you have a char** the compiler has no way of knowing how to access a random element in the matrix.
A way of building the matrix such that it is a char** is to create an array of pointers to char and then allocate each of those pointers:
char **emps = malloc(10 * sizeof(char*)); // create an array of 10 pointers to char
for (int i = 0; i < 10; i++)
emps[i] = malloc(50 * sizeof(char)); // create 10 arrays of 50 chars each
The point is, you can't convert a matrix to a double pointer in a similar way you convert an array to a pointer.
Another problem: Returning a 2D matrix as 'char**' is only meaningful if the matrix is implemented using an array of pointers, each pointer pointing to an array of characters. As explained previously, a 2D matrix in C is just a flat array of characters. The most you can return is a pointer to the [0][0] entry, a 'char*'. There's a mismatch in the number of indirections.
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
How to find the sizeof(a pointer pointing to an array)
I know this to find the size of array = sizeof(arr)/sizeof(arr[0])
But I have to implement the following (It's just a demo):
demo.h
#ifndef __DEMO_H
#define __DEMO_H
void heap_sort(int *);
#endif
demo.c
void heap_sort(int *ptrA)
{
//implementing heap sort
But here it requires length of array
}
main.c
#include "demo.h"
int main(void)
{
int A[10];
heap_sort(A)
return 0;
}
FYI .. It's just a demo.. but here I have to implement it in some other scenarios in which there is restriction that "DON'T CHANGE ANYTHING IN HEADER FILE" which means i can't change the function signature . Then how to get the array length in demo.c For char it's easy to get by help of strlen() Isn't there anything similar to get the length of int,float double types
The only alternatives I see are:
use a special value as terminator (as strlen does).
use the Pascal trick, and place array length in the first element.
store the array size in a global external variable.
use a separate function.
E.g.:
int arraySize(int newSize)
{
static int arraySize = 0;
int oldSize;
oldSize = arraySize;
if (newSize)
arraySize = newSize;
return oldSize;
}
in main.c:
arraySize(10);
in demo.c:
arraylen = arraySize(0);
if you can't change the function signature, then maybe you could pass the size of the array in the first element.
A[0] = 10;
heap_sort(A);
Or mark the end of the array with some special value, but I don't like this one because you'd have to iterate the whole array to find the length and you need to make sure this value is not used in the array:
A[LENGTH-1] = END//some value;
void array_length(A) {
while (*A++ != END) {
length++;
}
}
This is just a solution for the restrictions you imposed, what I would normally do, is either pass the size of the array as a second argument, or use a struct for the array:
struct array_t {
int *data; //allocate this
int size;
};
Note: other horrible solutions include global variables.
Thinking of strlen() is going into the right direction.
Strings are character arrays with a '\0' as array termination, as last element.
You could take the same approach for any other type of array.
Just define one value as the value which indicates the last element in an array. Searching for this value then helps you to find the size of the array.
Update:
I like mux's idea of using the first element in an array.
Anyhow, using it to store the numbers of element in there might lead to problems in case the number of elements in the array is larger as what can be store in an array's element (a char array, for example, whould then be limited to 255 elements).
My approach on the other hand has the draw back that the value used as terminator to the array is not usable as real value in the arra itself.
The combining the former and the latter approaches, I propose to use the first element of the array to store the value which is used as terminator of the array.
The constraint seems a bit odd, but whatever.
Why not use a global variable to store the size.
EDIT: Thank you very much for your responses. I understand this properly now!
I am trying to learn more on C pointers. Tinkering around, I am questioning the difference between two actions I am using.
This code seems to work at first glance, but I am not sure of what's the difference, and if any of these two approaches is wrong in some way.
I'd like to know what's the difference between the two pieces of code, when I should I pass the adress, and when a pointer to an array?
Is any of the pieces wrong? If so, what would be the proper way?
having a simple struct grid pretty much like struct grid { int val; } (for demonstration purposes)
First piece of code. Passing address of the pointer to the array.
void set (mygrid *grid, int foo){
grid->bar = foo; //should this be '*grid->bar?' But this seems to work properly.
}
void main(){
int i;
int* array;
int max = 24;
array = malloc(sizeof(grid) * max);
for(i = 0; i < max; i++){
set(&array[i], 0);
}
}
Second piece of code. I am not entirely sure why this works, but the compiler doesn't output any warning.
I am supposed to be passing the pointer to the start of the array like this?
void set(mygrid *grid, int foo){
int i; int max = 24; //so this example code compiles :P
for(i = 0; i < max; i++){
grid[i].bar = foo;
}
}
void main(){
int* array;
int max = 24;
array = malloc(sizeof(grid) * max);
set(array, 0); //Why not &array?
}
Passing an array decays into a pointer that points to the first member of the array, just like &array[0].
In your second example, array is just a pointer, and the return value from malloc is just the address of the start of the block of memory you get.
It doesn't have to be used for an array; it could be used for storage of an arbitrary sizeof(int) * max bytes of data. An array (in C) is really just a nice way of thinking about & working with a solid block of memory divided up into equal size portions.
Secondly, you should understand how my_array[i] works. All it does is take the address of where your block of array data starts (which is the actual value of my_array), and then look at what value is stored at a particular offset from there. Specifically, if my_array is of a (made up) type of WhatEver, then it will access the data from my_array + i*sizeof(WhatEver) to my_array + (i+1)*sizeof(WhatEver).
On a related note (since you're learning C), it's highly recommended to check that the return from malloc is not NULL before doing anything with it.
I'm no C guru but am also trying to improve my understanding so if this is incorrect, please leave a comment or edit my answer so I can learn from my mistakes :)
In your first piece of code
grid->bar is same as (*grid).bar
. and using name of an array refers to its base address. so writing array is equivalent &array[0]
&array[i] is equivalent to array+i
array[i] is equivalent to *(array +i)
In you second piece of code i dont understand why there is no error because in your function set you do not declare max and i dont see a global max variable too.
also in your second piece of code you use
set(array,0) because array is already an integer pointer(see the declaration int * array).As far as i understand the mygrid is not a struct but is an array of structs in the second example
In C, an array is pretty much the same as a pointer. For me this isn't so amazing, since it is one of the earlier programming languages I learned, but if you're coming from a high level language where an array is a different type of object, then it might come across as strange.
I am making my first C program, and it utilizes a 2D array, and the code seems weird to me. First, why do I have to store "White" in [1][6]? I tried [0][6], but the compiler complains and won't run but when I call it in printf, it's [0][6]. Also, when trying to store "Bl" in codes [2][6], it says conflicting type for codes. Any help would be appreciated, thanks.
int main (int argc, const char * argv[]) {
for (q=0; q<=457; q++) {
for (w=0; w<=6; w++) {
codes[q][w] = 0;
}
}
char codes[1][6] = {'W','h','i','t','e','\0'};
char codes[2][6] = {'B','l,'\0'};
printf("%c\n", codes[0][0]);
You are confusing two tasks that you need to perform. One task is to declare a variable, and tell the compiler what type it's going to hold. The second task is to put data into it.
You are doing both tasks at the same time, and this is confusing you. In your first statement you are telling the compiler, "codes is a 2-dimensional, 1x6 array. By the way, here are the values to put into it: "White"." Your second sattement says, "codes is a 2-dimensional, 2x6 array. By the way, put "BI" into it."
The compiler is complaining and saying, "It can't be a 2x6 array, becuase you already told me it's a 1x6 array."
What you need is something like this:
char codes[2][6] = { {'W','h','i','t','e','\0'}, {'B','l,'\0'} };
You would then get your 'W' by looking at codes[0][0], etc.
You cant initalize array [0][6]
beucase this is a vector, and first
index dont have elements.
And you cant 1D (vector) array
assign to 2D array.
{'W','h','i','t','e','\0'} and
{'B','l,'\0'} is a 1D array like a
something[6] or in second case
something[3].
And you have triple declaration of
codes variable. You can only one
declare variable.
Instead of codes[0][6] if you want the compiler to decide the size of array depending on your initialization, you could say:
char codes[][6] = {'W','h','i','t','e','\0'};
if you're trying to initialize 2D array:
Try:
char codes[2][6] = {{'W','h','i','t','e'}, {'B','l'}};
Or
char codes[][6] = {{'W','h','i','t','e'}, {'B','l'}};
You're confusing initialization with assignment. You can either initialize the array when you declare it, as in
char codes[N][6] = { // where N is the total number of codes
"White", // assigns codes[0][0] - codes[0][5] as 'W','h','i','t','e',\0
"Bl", // assigns codes[1][0] - codes[1][2] as 'B','l',\0
...
};
which is equivalent to writing
char codes[N][6] = {
{'W','h','i','t','e',\0},
{'B','l',\0},
...
};
or you can assign elements of the array after the declaration, as in
char codes[N][6];
...
strcpy(codes[0], "White");
strcpy(codes[1], "Bl");
...
What you've done is munged the two together, so you're redeclaring codes with different types (the compiler is interpreting your use of [0][6] and [1][6] as array sizes, not locations), hence the compiler errors.