My project is simple. It is just a quiz game with user input. As for the questions and answers I used a file to keep them as a data base.
I also defined a structure:
typedef struct QUESTION
{
char question[MAXCARACTERES];
char answer1[MAXCARACTERES];
char answer2[MAXCARACTERES];
char answer3[MAXCARACTERES];
char answer4[MAXCARACTERES];
} QUESTION;
What I wish to know if there is a possible way to print the answers randomly. Otherwise, the right one stays always in the same place.
Thanks in advance!
I turned William Pursell's comment into an answer. You can't run the code because is missing the answers and some other stuff, but it should work.
typedef struct QUESTION
{
char question[MAXCARACTERES];
char answer[4][MAXCARACTERES];
} QUESTAO;
void randPerm( int *surp );
int main() {
int surprise[4] = {0, 1, 2, 3};
randPerm( surprise );
for(int i = 0; i < 4; i++) {
printf("%s\n", QUESTAO.answer[surprise[i]])
}
return 0;
}
void randPerm( int *surp )
{
for(int i = 4; i > 1; i--) {
int luck = rand() % i;
int hold = surp[luck];
surp[luck] = surp[i-1];
surp[i-1] = hold;
}
}
Related
The following questions might have been asked already. In addition, I am aware of the fact that there are a lot of posts that discuss the topic. However, after searching, I couldn't find answers to those specific questions.
Note: the questions appear below the code.
The code:
#include <stdio.h>
#define ARRAY_SIZE 3
typedef struct
{
const char* name;
const char* color;
int age;
}Cat;
void printCat1(Cat* cat)
{
printf("\n%s\n", cat->name);
printf("%s\n", cat->color);
printf("%d\n", cat->age);
printf("\n");
}
void printCat2(Cat cat)
{
printf("\n%s\n", cat.name);
printf("%s\n", cat.color);
printf("%d\n", cat.age);
printf("\n");
}
void printCatArray(Cat catArr[])
{
int i = 0;
for (i = 0; i < ARRAY_SIZE; i++)
{
//WHICH OPTION IS BETTER? (printCat1 OR printCat2)
//CALLING TO PRINTING FUNCTION.
}
}
void swap(_____ cat1, _____ cat2)
{
Cat temp = //cat1 or *cat1 ?
//cat1 = cat2 or *cat1 = *cat2?
cat2 = temp;
}
void sortbyage(Cat catarr[])
{
int i, j;
for (i = 0; i < ARRAY_SIZE - 1; i++)
for (j = 1; j < ARRAY_SIZE; j++)
if (catarr[i].age > catarr[j].age)
swap(______, ______]);
}
int main() {
Cat catArray[ARRAY_SIZE] =
{ {"cat1", "white", 1},
{"cat2", "black", 2},
{"cat3", "gray", 3} };
printCatArray(catArray);
return 0;
}
The questions:
1. What is the difference between both functions that print the data of a single cat structure?
2. Which printing function is better to use and why? it will be essential and meaningful if you would like to explain.
3. What is better to write and why? void swap(Cat cat1, Cat cat2) OR void swap(Cat* cat1, Cat* cat2)
4. Is the calling to swap function from the function soryByAge, swap(&catArr[i], &catArr[j]), correct? Would you write it differently?
5. The following line of code is correct: catArray[2] = catArray[1];
It will be great to get an explanation about what it actually does.
If one or more of the questions are not clear enough, I will be glad to clarify them.
Thank you very much beforehand!
printCat1 uses a pointer, it's more efficient because it doesn't make a temporary duplicate.
printCat2 passes the value, it makes a duplicate of cat, it's less efficient.
swap function has to use pointers. If it doesn't, it will simply swap copied values. The original array will be unchanged.
void swap(Cat *cat1, Cat* cat2)
{
Cat temp = *cat1;
*cat1 = *cat2;
*cat2 = temp;
}
When passing parameter to swap, use the address of the variable. For example,
swap(&arr[i], &arr[j]);
printCat1(&arr[i]);
The structure:
typedef struct
{
const char* name;
const char* color;
int age;
}Cat;
...
Cat catArray[ARRAY_SIZE] =
{ {"cat1", "white", 1},
{"cat2", "black", 2},
{"cat3", "gray", 3} };
You want to declare strings as character arrays.
typedef struct
{ char name[50]; char color[50]; int age; }Cat;
Or declare as pointers and allocated dynamically.
I would not declare cat name and colour as const. If they are defined as const you will not be able to change it runtime, for example to get it from the user or read the file with your database.
foo(cat cats[]) and foo(cat *cats) are exactly the same as arrays are passed as pointers. It is good to pass the size too as in real life you do not know big the array is.
void swap(Cat cat1, Cat cat2) OR void swap(Cat* cat1, Cat* cat2) - the fist one will work on local copies of the structures. It will not affect the original array. So only the second version will do something meangfull.
It is the correct way of doing it. You can also swap structs from the different arrays. You can also add index to the pointer (as in the example below)
It copies the whole structure from the index 1 to the structure at index 2. After that you will have identical elements at indexes 1 and 2
typedef struct
{
char* name;
char* color;
int age;
}Cat;
void printCat1(const Cat* cat)
{
printf("\n%s\n", cat->name);
printf("%s\n", cat->color);
printf("%d\n", cat->age);
printf("\n");
}
void printCat2(Cat cat)
{
printf("\n%s\n", cat.name);
printf("%s\n", cat.color);
printf("%d\n", cat.age);
printf("\n");
}
void printCatArray(const Cat *catArr, size_t size)
{
for (size_t i = 0; i < size; i++)
{
printCat1(catArr + i);
/* or */
printCat2(catArr[i]); // in this case the whole structure will passed to the function
}
}
void swap(Cat *cat1, Cat *cat2)
{
Cat temp = *cat1;
*cat1 = *cat2;
*cat2 = temp;
}
void sortbyage(Cat *catarr, size_t size)
{
size_t i, j;
for (i = 0; i < size - 1; i++)
for (j = 1; j < size; j++)
if (catarr[i].age > catarr[j].age)
swap(catarr + i, catarr + j);
}
int main() {
Cat catArray[] =
{ {"cat1", "white", 1},
{"cat2", "black", 2},
{"cat3", "gray", 3} };
printCatArray(catArray, sizeof(catArray) / sizeof(catArray[0]));
}
https://godbolt.org/z/xodsToqxa
I was doing my Huffman homework and I got stumble on a tiny thing that I cant understand why it happens.
So I created a structure that has an int array a char and an int that holds the size of the array.
struct kodlar{
char karakter;
int* code;
int codesize;
};
typedef struct kodlar kodlar;
kodlar* yenikod(char karakter, int* code,int codesize){
kodlar* yenikod = (kodlar*)malloc(sizeof(kodlar));
if(yenikod){
yenikod->karakter = karakter;
yenikod->code = code;
yenikod->codesize = codesize;
}
return yenikod;
}
Then inside of my main, I created an array that holds these structures:
kodlar* K[taille];
taille is the number of char that it is going to store.
In order to put the characters and codes correspondence, I created the function
printCodes(HuffTree,arr,top,&p,K);
and it works like this:
void printCodes(node* root, int arr[], int top,int* i,kodlar** K)
{
if (root->left) {
arr[top] = 0;
printCodes(root->left, arr, top + 1,i,K);
//printf("%c\n",'l');
}
if (root->right) {
arr[top] = 1;
printCodes(root->right, arr, top + 1,i,K);
//printf("%c\n",'r');
}
if (isLeaf(root)) {
printArr(arr,top);
K[*i]=yenikod((root->lettre),arr,top);
*i = *i + 1;
//printArr(K[*i]->code,K[*i]->codesize);
//printf("%i en son if te i \n",*i );
}
}
But it seems like I cant store arrays inside of my array of kodlar structure. if I commented out the parties //printArr(K[*i]->code,K[*i]->codesize); it gives me a segmentation fault and if I try to print like this:
for (int i = 0; i < taille; ++i){
printf("%c :", K[i]->karakter);
printf(" ");
printArr(K[i]->code,K[i]->codesize);
printf("\n");
}
it gives me codes but only with 1's. I got stuck on this it has been 2 days I would appreciate it if somebody can help me.
struct kodlar{
char karakter;
int codesize;
int code[50];
};
typedef struct kodlar kodlar;
kodlar* yenikod(char karakter, int* code,int codesize){
kodlar* yenikod = (kodlar*)malloc(sizeof(kodlar));
if(yenikod){
yenikod->karakter = karakter;
yenikod->codesize = codesize;
for (int i = 0; i < codesize; ++i)
{
yenikod->code[i] = code[i];
}
}
return yenikod;
}
So thanks to #wcochran I understood that the problem was in my struct but memcpy did not work on my code and I was already giving an array that has been already allocated before entering to yenikod. And I gave a size to my code array in the kodlar struct and my problem was solved.
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);
}
}
}
If i had an array such as int numbers[5] i could assign values to it with numbers[0] = 1 or numbers[3] = 4. Then if i had a struct such as
struct structName
{
int number0;
int number1;
int number2;
};
is there any way to do something like the following (note this is not working code)
int main(void)
{
struct structName name; //how could i declare this to do the following
for(int i = 0; i < 2; i++)
{
name[i] = i; //maybe name.[i]
}
}
so is there a way to write name[ variable ] = someNumber to assign someNumber to say number0 (if variable was 0) or number2 (if variable was 2). ive been looking for days and cant find anything that does this. (maybe i just don't know what to look for)
is there any way to do something like the following
No, there's no way to access the fields of the structure by index. You use the names of the fields instead:
struct structName name;
name.number0 = someNumber;
name.number1 = someOtherNumber;
If you want to access the values by index, use an array instead, even if it's embedded in the structure:
struct structName
{
int numbers[3];
// other fields here
};
Then you can say:
struct structName name;
for (int i = 0; i <= 2, i++) {
name.numbers[i] = i;
}
You could write a function which uses a switch statement that allows you to access fields by index. Something like:
#include<stdio.h>
struct structName{
int number0;
int number1;
int number2;
};
void assign(struct structName * name, int i, int j){
switch(i){
case 0:
name->number0 = j;
break;
case 1:
name->number1 = j;
break;
case 2:
name->number2 = j;
break;
}
}
int main(void){
int i;
struct structName name;
for(i = 0; i <= 2; i++){
assign(&name,i,i);
}
//test:
printf("%d\n",name.number0);
printf("%d\n",name.number1);
printf("%d\n",name.number2);
return 0;
}
(which prints 0,1,2 as expected).
Needless to say, there isn't much point in doing this (as opposed to just having a field which is an array) unless the struct in question is already defined as part of an API or already part of a code base which isn't easily refactored.
Yes, with some weird and inadvisable memory manipulation. You're much better off using an array.
struct structName
{
int numbers[3];
};
int main(void)
{
struct structName name;
for(int i = 0; i <= 2; i++)
{
name.numbers[i] = i;
}
}
Also note that you had some syntax errors in your for loop and an off-by-one error.
Macros with arguments should work
#define name(x) x
So name(1) would become 1. name(2) would become 2 and so on.
In C, there is no spoon.
struct structName name;
int *idx = &name; // First we need a memory address to the struct
for (int i = 0; i < sizeof(name) / sizeof(*idx); ++i) {
// idx[i] == name.numberX
idx[i] = i;
}
Now, if you check the values of name.number0, name.number1, name.number2 you will see they contain the correct values.
This is not a very good way of doing things with structs, but I felt compelled to answer after the top response claims it is impossible.
I have a function
struct Analysis reduce (int n, void* results)
Where n is the number of files to be analyzed, and I'm passing an array of Analysis structs to results.
The Analysis struct is defined as follows:
struct Analysis {
int ascii[128]; //frequency of ascii characters in the file
int lineLength; //longest line in the file
int lineNum; //line number of longest line
char* filename;
}
I've cast the void * as such,
struct Analysis resArray[n];
struct Analysis* ptr = results;
resArray[0] = ptr[0];
but I can't figure out how to iterate through the resArray properly. I've tried
for (i = 0; i < n; i++){
printf("lineLength: %d\n", resArray[i].lineLength);
}
with n = 3, and I'm getting garbage values. resArray[0] is correct, but resArray[1] is an insanely high number and resArray[2] is just 0. Why wouldn't resArray[1] or resArray[2] give the correct values? If I was incrementing the address incorrectly then it would make sense but I'm just accessing the array at a certain index. Pretty lost here!
resArray[0] is correct because there is "something":
resArray[0] = ptr[0];
Other elements are garbage because you didn't set there any values. If you want to copy entire array you need to change copying method to:
for (i = 0; i < n; i++)
{
resArray[i] = ptr[i];
}
You can't assign a pointer to an array directly because they are different typessince array[n] is type struct analysis(*)[n] and ptr is type struct analysis(*). Check here for more info.
Hopefully this code will help you.
#include <stdio.h>
#define d 3
struct Analysis {
int ascii[128];
int lineLength;
int lineNum;
char *filename;
};
struct Analysis Analyses[d];
struct Analysis reduce(int n, void *results) {
struct Analysis resArray[n];
struct Analysis *ptr = results;
for (int i = 0; i < n; i++) {
resArray[i] = ptr[i];
}
for (int i = 0; i < n; i++) {
printf("lineLength: %d\n", ptr[i].lineLength);
}
return *ptr;
}
int main(void) {
struct Analysis a = {{5}, 2, 2, "George"};
struct Analysis b = {{6}, 3, 3, "Peter"};
struct Analysis c = {{7}, 4, 4, "Jane"};
Analyses[0] = a;
Analyses[1] = b;
Analyses[2] = c;
reduce(d, &Analyses);
return 0;
}
You can try it online.