C Programming: String arrays - how to check equality? [duplicate] - c

This question already has answers here:
How do I properly compare strings in C?
(10 answers)
Closed 4 years ago.
I have a struct such as this:
struct car{
char parts[4][10];
};
I initialize them in my main() function, as though:
char fill[10] = "none";
struct car c;
int i = 0;
for (i; i< 4; i++){
memcpy(c.parts[i], fill, 10);
}
At this point, each string in the array has "none", like this:
int j = 0;
for (j; j<4; j++){
printf("%s\n", c.parts[j]);
}
*OUTPUT*
none
none
none
none
This is correct - this is what I want. Now, however, I want to write a function and pass a pointer to c. Inside the function, I want to:
check if an element in the "parts" array is equal to "none".
if it is, then set that equal to "wheel".
Here is how I have attempted this:
void fun(struct car* c){
char fill[10] = "wheel";
int i = 0;
for (i; i<4; i++){
if (c->parts[i] == "none"){
memcpy(c->parts[i], fill, 10);
}
}
}
int main(){
char fill[10] = "none";
struct car c;
int i = 0;
for (i; i< 4; i++){
memcpy(c.parts[i], fill, 10);
}
struct car* c2 = c;
fun(c2);
return 0;
}
However, the if statement inside the function never gets hit! It keeps saying that each element in the array IS NOT equal to "none". However, I try printing it out RIGHT ABOVE the if statement - and sure enough, it says "none"! Not sure why?
EDIT
I tried the suggested methods in the "possible duplicate" post (strcmp), but to no avail. I'm still not getting what I want to achieve.

Use strcmp() from <string.h> to compare in fun() as shown below:
void fun(struct car* c){
char fill[10] = "wheel";
int i = 0;
for (i; i<4; i++){
if (!strcmp(c->parts[i], "none")) {
memcpy(c->parts[i], fill, 10);
}
}
}

Related

C: how to give 2D Array to a function

I want to pass a 2D array already filled with chars to a different method to do something with it.
Background: I am trying to implement GameOfLife. And I have already successfully implement the gameboard with a random amount of living cells. But now I want to pass the board(Array) to a different method to continue working with it. How to do so?
//wow das wird hurenshon
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <time.h>
void spielStarten(int x, int amountOfLiving){
char feld[x][x];
for(int i = 0; i < x; i++){
for(int j = 0; j < x; j++){
feld[i][j] = 'o';
}
}
for(int i = 0; i < amountOfLiving; i++){
int a = (rand()%x);
int b = (rand()%x);
feld[a][b] = 'x';
}
printf("Gameboard: \n");
for(int i = 0; i < x; i++){
for(int j = 0; j < x; j++){
printf("%c ", feld[i][j]);
}
printf("\n");
}
spielRun(feld);
}
void spielRun(char feld[][]){
int neighbCount;
char feldNew[][] = feld[][];
for(int i = 0; i < x; i++) {
for(int j = 0; j < x; j++) {
checkForNeighbours(feld[x][y]);
// in progress
}
}
}
int main(int argc, char* argv[]){
srand(time(NULL));
int x = 16;
if(argc < 2 || argc > 3){
printf("2. Argument eine Zahl fuer Feldgroesse eingeben\n");
printf("1. Argument eine Zahl 0-10 fuer ungefähre prozentuale Belegung mit lebenden
Zellen eingeben \n");
return 0;
}
if(argv[2] != NULL){
x = atoi(argv[2]);
}
int i;
i = atoi(argv[1]);
i = (x^2)*(0,1*i);
spielStarten (x,i);
return 0;
}
In the last line of the Method "Spiel starten" i want to give the array to the next Method "spielRun".
Edit: thanks to an other user I found this struture:
void printarray( char (*array)[50], int SIZE )
But it doesn't work for me since I can´t hardcode the number, because the arraysize depends on a user input.
thanks!
The difficulty here is that the size of your array is not known statically (once upon a time, your code would even not compile for the same reason).
That, combined with the fact that 2D-arrays are not arrays of 1D arrays (contrarily to what happen when you malloc a int ** and then every int * in it), and so it doesn't make sense not to specify the size when passing it to a function.
When using arrays of arrays (technically, pointers to a bunch of pointers to ints), like this
void f(int **a){
printf("%d %d %d\n", a[0][0], a[1][0], a[0][1]);
}
int main(){
int **t=malloc(10*sizeof(int *));
for(int i=0; i<10; i++) t[i]=malloc(20*sizeof(int));
f(t);
}
That code is useless, it prints only unitialized values. But point is, f understands what values it is supposed to print. Pointers arithmetics tells it what a[1] is, and then what a[1][0] is.
But if this 2D-array is not pointers to pointers, but real arrays, like this
void f(int a[][20]){
printf("%d %d %d\n", a[0][0], a[1][0], a[0][1]);
}
int main(){
int t[10][20];
f(t);
}
Then, it is essential that the called function knows the size (or at least all sizes, but for the first dimension) of the array. Because it is not pointers to pointers. It is an area of 200 ints. The compiler needs to know the shape to deduce that t[5][3] is the 5×20+3=103th int at address t.
So, that is roughly what is (better) explained in the link that was given in comments: you need to specify the size.
Like I did here.
Now, in your case, it is more complicated, because you don't know (statically) the size.
So three methods. You could switch to pointers to pointers. You could cast your array into a char * and then do the index computation yourself (x*i+j). Or with modern enough C, you can just pass the size, and then use it, even in parameters, declaration
void f(int x, int a[][x]){
printf("%d %d %d\n", a[0][0], a[1][0], a[0][1]);
}
int main(){
int t[10][20];
f(t);
}
Anyway, from an applicative point of view (or just to avoid segfault) you need to know the size. So you would have had to pass it. So why not pass it as first parameter (Note that the function in which you have this size problem, spielRun, does refers to a x, which it doesn't know. So, passing the size x would have been your next problem anyway)
So, spielRun could look like this (not commenting in other errors it contains)
void spielRun(int x, char feld[][x]){
int neighbCount;
char feldNew[][] = feld[][]; // Other error
for(int i = 0; i < x; i++) {
for(int j = 0; j < x; j++) {
checkForNeighbours(feld[i][j]); // Corrected one here
// in progress
}
}
}
And then calls to this spielRun could be
spielRun(x, feld);
Note that I address only the passing of array of size x here. There are plenty of other errors, and, anyway, it is obviously not a finished code. For example, you can't neither declare a double array char newFeld[][] = oldFeld[][]; nor affect it that way. You need to explicitly copy that yourself, and to specify size (which you can do, if you pass it).
I am also pretty sure that i = (x^2)*(0,1*i); does not remotely what you expect it to do.

How to increment a variable when strstr finds the specified string

I'm wanting to have my variable houseTot increment by one every time strstr finds a string with "house" in it. I've essentially done this in my code:
struct Owner1_def
{
int totProps;
char type[40];
float monthlyPrice;
float maintenance;
int bedrooms;
int bathrooms;
};
typedef struct Owner1_def Owner1;
int main(void)
{
char *ptr;
int i = 0;
ptr = strstr(database[i].hometype, "house");
for(i = 0; i <= 3; ++i)
{
if (ptr != NULL)
houseTot++;
}
return 0;
}
But when the program prints houseTot's value, it's still at it's initialized value 0. I don't know much about strstr, but from what I've read, this should work.
The call to strstr() should be moved inside the loop so that the value stored in database[i].hometype can be checked on each iteration:
for(i = 0; i <= 3; ++i) {
ptr = strstr(database[i].hometype, "house");
if (ptr != NULL)
houseTot++;
}
Note that posted code has no definition for the array of structs database[], and the struct provided has no hometype field.

Passing entire array to the function in C

I have written a program for insertion shot like following:
int _tmain(int argc, _TCHAR* argv[])
{
int arr[10] = {1,2,3,10,5,9,6,8,7,4};
int value;
cin >> value ;
int *ptr;
ptr = insertionshot(arr); //here Im passing whole array
BinarySearch(arr,value);
return 0;
}
int * insertionshot(int arr[])
{
//Changed after a hint (now, its fine)
int ar[10];
for(int i =0;i < 10; i++)
{
ar[i] = arr[i];
}
//Changed after a hint
int arrlength = sizeof(ar)/sizeof(ar[0]); //here array length is 1, it should be 10
for(int a = 1; a <= arrlength -1 ;a++)
{
int b = a;
while(b > 0 && ar[b] < ar[b-1])
{
int temp;
temp = ar[b-1];
ar[b-1] = ar[b];
ar[b] = temp;
b--;
}
}
return ar;
}
The problem is after passing the whole array to the function, my function definition only shows 1 element in array and also "arraylength" is giving 1.
int arr[] in a function formal parameter list is a syntax quirk, it is actually processed as int *arr. So the sizeof trick doesn't behave as you expect.
In C it is not possible to pass arrays by value; and furthermore, at runtime an array does not remember its length.
You could include the length information by passing a pointer to the whole array at compile time:
int * insertionshot(int (*arr)[10])
Of course, with this approach you can only ever pass an array of length 10. So if you intend to be able to pass arrays of differing length, you have to pass the length as another parameter.

C Struct Pointers

Default struct given:
struct counter {
long long counter;
};
struct instruction {
struct counter *counter;
int repetitions;
void(*work_fn)(long long*);
};
static void increment(long long *n){
n++;
}
My line:
n = 2;
struct counter *ctest = NULL;
int i;
if( ctest = malloc(sizeof(struct counter)*n){
for( i=0; i<n ;i++){
ctest[i].counter = i;
}
for( i=0; i<n ;i++){
printf("%lld\n", ctest[i].counter);
}
}
struct instruction itest;
itest.repetitions = 10;
itest.counter = ctest; //1. This actually points itest.counter to ctest[0] right?
//2. How do I actually assign a function?
printf("%d\n", itest.repetitions);
printf("%lld\n", itest.counter.counter); // 3. How do I print the counter of ctest using itest's pointer?
So I am trying to get those three things working.
Thanks
itest.counter = ctest; // This
actually points itest.counter to
ctest[0] right?
Right. itest.counter == &ctest[0]. Also, itest.counter[0] refers directly to the first ctest object, itest.counter[1] refers the 2nd, etc.
How do I actually assign a function?
itest.work_fn = increment;
How do I
print the counter of ctest using
itest's pointer?
printf("%lld\n", itest.counter->counter); // useful if itest.counter refers to only one item
printf("%lld\n", itest.counter[0].counter); // useful if itest.counter refers to an array
This points to addres of ctest. (which is same as addres of it's first element)
You should declare some function whith same signatur (say void f(long long *)) and here write itest.work_fn = f;
for(int i = 0; i < n; ++i) printf("%lld\n", itest.counter[i].counter);
Yes it does. But maybe it is more clear like this:
iter.counter = &ctest[0];
itest.work_fn = increment;
printf("%lld\n", itest.counter->counter);
That is if you plan to have only one counter. From your code you want multiple and maybe you should store the number in struct instruction.
If so, then it would be:
for (i = 0; i < itest.n; i++)
printf("%lld\n", itest.counter[i].counter);
In this case the function should also be changed.

Creating an array of int arrays in C?

Let us say I have the following method prototype:
void mix_audio(int *vocal_data_array, int *instrumental_data_array, int *mixed_audio_array, FOURTH ARGUMENT)
{
}
How would I:
Initialize an array_of_arrays before the above argument so as to pass it as the fourth argument?
In the method, make it so that the first value of my array_of_arrays is the array called vocal_data, that the second value of my array is instrumental_data_array and the third value is mixed_audio_array.
How would I later then loop through all the values of the first array within the array_of_arrays.
I hope I'm not asking too much here. I just thought it would be simple syntax that someone could spit out pretty quickly :)
Thanks!
EDIT 1
Please note that although I've showed by my example an array_of_arrays of length 3 I'm actually looking to create something that could contain a variable length of arrays.
Simple array of arrays and a function showing how to pass it. I just added fake values to the arrays to show that something was passed to the function and that I could print it back out. The size of the array, 3, is just arbitrary and can be changed to whatever sizing you want. Each array can be of a different size (known as a jagged array). It shows your three criteria:
Initialization, Assigning values to each index of arrayOfArrays, The function demonstrates how to extract the data from the array of arrays
#include <stdio.h>
void mix_audio(int *arr[3]);
int main() {
int *arrayOfArrays[3];
int vocal[3] = {1,2,3};
int instrumental[3] = {4,5,6};
int mixed_audio[3] = {7,8,9};
arrayOfArrays[0] = vocal;
arrayOfArrays[1] = instrumental;
arrayOfArrays[2] = mixed_audio;
mix_audio(arrayOfArrays);
return(0);
}
void mix_audio(int *arr[3]) {
int i;
int *vocal = arr[0];
int *instrumental = arr[1];
int *mixed_audio = arr[2];
for (i=0; i<3; i++) {
printf("vocal = %d\n", vocal[i]);
}
for (i=0; i<3; i++) {
printf("instrumental = %d\n", instrumental[i]);
}
for (i=0; i<3; i++) {
printf("mixed_audio = %d\n", mixed_audio[i]);
}
}
From your question it sounds like you actually want a struct containing your arrays, something like:
struct AudioData {
int* vocal_data_array;
unsigned int vocal_data_length;
int* instrumental_data_array;
unsigned int instrumental_data_length;
int* mixed_audio_array;
unsigned int mixed_audio_length;
};
For the array allocation using the example of an array of integers:
int** x = malloc (sizeof (int*) * rows);
if (! x) {
// Error
}
for (int i = 0; i < rows; ++i) {
x[i] = malloc (sizeof (int) * columns);
if (! x[i]) {
// Error
}
}

Resources