C: Function to generate random string and add it to struct - c

Coming from some experience with Java/C#, I'm struggling to get my head around some parts of C. I have an array of structs. These structs, at the moment, have only one member (I'll be adding others down the track) - an array of chars. This array is a string of 6 characters - two letters, four digits (e.g. XY1234).
The follow code produces the objectCode I'm looking for:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>
#define LETTERS_IN_ALPHABET 26
typedef struct object {
char objectCode[6];
} object_t;
void GetRandomSeed() {
srand((unsigned)time(NULL));
}
char RandomLetter() {
return 'A' + rand() % LETTERS_IN_ALPHABET;
}
int RandomDigit() {
return rand() % 10;
}
int main() {
GetRandomSeed();
object_t object1;
for (int i = 0; i < 2; i++) {
object1.objectCode[i] = RandomLetter();
}
for (int i = 2; i < 6; i++) {
object1.objectCode[i] = '0' + RandomDigit();
}
// Print objectCode string to screen
for (int i = 0; i < 6; i++) {
printf("%c", object1.objectCode[i]);
}
printf("\n");
return 0;
}
I'm trying to wrap the for loops (the ones randomly generating the code) in a function. However, the print out of my attempt to do this is just gibberish:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>
#define LETTERS_IN_ALPHABET 26
typedef struct object {
char objectCode[6];
} object_t;
void GetRandomSeed() {
srand((unsigned)time(NULL));
}
char RandomLetter() {
return 'A' + rand() % LETTERS_IN_ALPHABET;
}
int RandomDigit() {
return rand() % 10;
}
void GenerateCode(object_t object) {
for (int i = 0; i < 2; i++) {
object.objectCode[i] = RandomLetter();
}
for (int i = 2; i < 6; i++) {
object.objectCode[i] = '0' + RandomDigit();
}
}
int main() {
GetRandomSeed();
object_t object1;
// Print objectCode string to screen
for (int i = 0; i < 6; i++) {
printf("%c", object1.objectCode[i]);
}
printf("\n");
return 0;
}
I'm bit of an infant when it comes to C so I really appreciate any help you can give. Thanks.

You're missing the call to GenerateCode on main, that's the reason the print output is gibberish.
However another issue is that on the GenerateCode function, the parameter is by value and the function won't modify the original struct on main. In C, all and every parameters are by value. You should pass a pointer to the struct:
void GenerateCode(object_t* object) {
for (int i = 0; i < 2; i++) {
object->objectCode[i] = RandomLetter();
}
for (int i = 2; i < 6; i++) {
object->objectCode[i] = '0' + RandomDigit();
}
}
int main() {
// ...
object_t object1;
GenerateCode(&object1);
}

Because you pass in an object by value to GenerateCode() the function modifies only the value on the stack (ie: the parameter itself), not the actual object you want to change. use a pointer:
void GenerateCode(object_t* object) {
for (int i = 0; i < 2; i++) {
object->objectCode[i] = RandomLetter();
}
for (int i = 2; i < 6; i++) {
object->objectCode[i] = '0' + RandomDigit();
}
}
and call it like:
GenerateCode(&object1);

Related

C how to return arrays from multiple functions?

I am trying to make a program that first creates an array in another function, returns it and then calls another function that shuffles the contents of the array and returns it. However I am struggling to do this in C since I do not quite understand the array pointer system that has to be used here.
So far my code doesnt return the values 1-20 from makeArray() but instead returns an array full of 0s and I have a feeling it has to do with the c's array pointer system.
Any help would greatly be appreciated! Thank you in advance
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int arrShuffle();
int arrShuffle(int * arr) {
int arr[21];
// shuffle array
for(int j=0; j<20; j++) {
int randInd = (rand() % 20) + 1;
int temp = arr[j];
arr[j] = arr[randInd];
arr[randInd] = temp;
}
return arr;
}
int makeArray() {
int arr[21];
// make array of 1-20
for(int i=0; i < 20; i++) {
arr[i] = i + 1;
}
return arr;
}
void main() {
int *orgArr;
int *modArr;
srand(time(NULL));
orgArr = makeArray();
for(int i=0; i < 20; i++) {
printf("OrgArr: %d\n", orgArr);
}
modArr = arrShuffle(orgArr);
}
You cannot use variables with automatic storage (aka local ones). You must allocate the array so the memory remains valid after the function ends:
int* makeArray() {
int *arr = calloc(21, sizeof *a);
// make array of 1-20
for(int i=0; i < 20; i++) {
arr[i] = i + 1;
}
return arr;
}
Remember to release the array when it is no longer used:
int main() {
int *orgArr;
...
orgArr = makeArray();
...
free(orgArr);
}
As tstanisl pointed out in their answer, a possible solution is to use dynamic memory allocation. My answer, instead, will give you yet another solution: using an array passed by the caller.
NOTE: both solutions are valid and their usefulness depends on the specific needs of your program. There's no "right" universal solution.
void makeArray(int arr[], size_t len) {
for (size_t i = 0; i < len; i += 1) {
arr[i] = (int) (i + 1);
}
}
void cloneAndModifyArray(const int orig[], int new[], size_t len) {
for (size_t i = 0; i < len; i += 1) {
new[i] = orig[i] * 2; // or some other modification
}
}
And you use it like this:
#define ARR_LEN (100)
int main(void) {
int arr[ARR_LEN];
makeArray(arr, ARR_LEN);
int modified_arr[ARR_LEN];
cloneAndModifyArray(arr, modified_arr, ARR_LEN);
return 0;
}

Beginner writing C code to program a round of yahtzee, function to hold dice values?

I'm at the very beginning of learning C code, and I'm having some issues with my homework. I need to have a function to hold dice values. I've written code for it, but once I try to put it into a function(keepArray) it doesn't seem to work for me. Here's what I have so far. Without a function, it seems to work. When I do put it into a function, no values are held.
#include <stdio.h>
#include <stdlib.h>
int main(void) {
const int NUM_ELEMENTS = 4;
int diceArray[NUM_ELEMENTS];
int keepArray[NUM_ELEMENTS];
int i = 0;
for (i = 0; i <= NUM_ELEMENTS; i++) {
diceArray[i] = (rand() % 6) + 1;
printf("%d ", diceArray[i]);
}
printf("\n");
for (i = 0; i <= NUM_ELEMENTS; i++) {
scanf("%d", &keepArray[i]);
if (keepArray[i] == 1) {
keepArray[i] = diceArray[i];
}
if (keepArray[i] == 0) {
keepArray[i] = (rand() % 6) + 1;
}
}
for (i = 0; i <= NUM_ELEMENTS; i++) {
diceArray[i] = keepArray[i];
printf("%d ", diceArray[i]);
}
return 0;
}
So I deleted my functions out of frustration, but I didn't get very far in the first place. Here's a try at what my functions might look like. It is mostly a copy paste of the above code.
#include <stdio.h>
#include <stdlib.h>
const int NUM_ELEMENTS = 5;
int diceArray[NUM_ELEMENTS];
int keepArray[NUM_ELEMENTS];
int i = 0;
void
Roll(){
for (i = 0; i < NUM_ELEMENTS; i++)
{
diceArray[i] = (rand () % 6) + 1;
printf ("%d ", diceArray[i]);
}
}
Reroll(){
for (i = 0; i < NUM_ELEMENTS; i++)
{
scanf ("%d", &keepArray[i]);
if (keepArray[i] == 1)
{
keepArray[i] = diceArray[i];
}
if (keepArray[i] == 0)
{
keepArray[i] = (rand () % 6) + 1;
}
}
for (i = 0; i < NUM_ELEMENTS; i++)
{
diceArray[i] = keepArray[i];
printf ("%d ", diceArray[i]);
}
}
int main(void)
{
Roll();
Reroll();
}
I did mess around with my functions previously and got some sort of output, but I think it was still predicated on incorrect code. For the code now, I get and error
"main.c:9:7: error: variably modified ‘diceArray’ at file scope
int diceArray[NUM_ELEMENTS];
^~~~~~~~~
main.c:13:7: error: variably modified ‘keepArray’ at file scope
int keepArray[NUM_ELEMENTS];
^~~~~~~~~
main.c:40:1: warning: return type defaults to ‘int’ [-Wimplicit-int]
Reroll(){
^~~~~~"
const int NUM_ELEMENTS = 5; cannot be used for statically sized arrays in C.
When using it as array size it attempts to create "Variable Length Arrays" instead (which are not allowed in file scope, as the error is telling you).
You can fix this issue by making it a "true" constant, e.g.:
#define NUM_ELEMENTS 5;
int diceArray[NUM_ELEMENTS];
int keepArray[NUM_ELEMENTS];
Or alternatively
enum { NUM_ELEMENTS = 5 };
int diceArray[NUM_ELEMENTS];
int keepArray[NUM_ELEMENTS];
Also you forgot to add a return type for your Reroll function, it should be void Reroll(void)

Problems with a dictionary implementation in c

So, I've been trying to implement a dictionary using an array(still haven't written DiDelete function, not relevant right now), but two problems emerged, here's the code:
#include <stdio.h>
#include <stdlib.h>
#define MAX 1000
typedef int elementtype;
typedef struct{
int last;
elementtype elements[MAX];
}Dictionary;
void DiMakeNull(Dictionary *A)
{
(*A).last = -1;
}
int DiMember(elementtype x, Dictionary A)
{
int f,m,l;
f = 0;
l = A.last;
m = (f+l)/2;
while(f <= l )
{
if( A.elements[m] == x) return 1;
else if( A.elements[m] < x) f = m+1;
else l = m-1;
m = (f+l)/2;
}
return 0;
}
void DiInsert(elementtype x, Dictionary *A)
{
int i = 0,j;
elementtype temp;
while( ((*A).elements[i] < x) && ((*A).last >= i) )
{
i++;
}
for(j = i ; j <= (*A).last; j++)
{
(*A).elements[j+1] = (*A).elements[j];
}
(*A).elements[i] = x;
(*A).last++;
}
int DiEmpty(Dictionary A)
{
if(A.last == -1) return 1;
return 0;
}
void DiPrint(Dictionary A)
{
int i;
printf("Dict:\n");
for(i = 0; i <= A.last; i++)
printf("%d\n",A.elements[i]);
printf("End!");
}
Question 1: why does DiPrint not work? After giving a Dictionary with confirmed numbers in its' array of elements it prints out random numbers. It seems fairly simple, I don't understand what I've gotten wrong there!
Question 2: Why is it, that when a function is e.g.
void function(Dictionary *A)
can't I use the notation A->last, but insted I have to use (*A).last
Thanks in advance!
EDIT: main program looks like this:
#include <stdio.h>
#include <stdlib.h>
#include "atp_dictionary_pomocu_liste.c"
int main()
{
Dictionary A;
DiMakeNull(&A);
DiInsert(4,&A);
DiInsert(3,&A);
DiInsert(32,&A);
DiPrint(A);
return 0;
}
Well I will tell you how I debugged. I like my compiler so I compiled the code.
error: could not convert '& A' from 'Dictionary*' to 'Dictionary'
DiPrint(&A);
^
It said to me that I have type mismatch in DiPrint().
Then three changes and it worked.
void DiPrint(Dictionary* A)
{
int i;
printf("Dict:\n");
for(i = 0; i <= (*A).last; i++)
printf("%d\n",(*A).elements[i]);
printf("End!");
}
And also in answer to your question why do we need to derefence it before using? Because we passed the address of the structure. Unless we dereference it , we won't get the struct instance.
From the comment I again had to rollback the code, we need to pass the structure instance directly and so we did
DiPrint(A);
and
void DiPrint(Dictionary A)
{
int i;
printf("Dict:\n");
for(i = 0; i <= A.last; i++)
printf("%d\n",A.elements[i]);
printf("End!");
}
And this would work without those unary *'s because we are working directly on the structure instance.
Isn't A->last and (*A).last the same thing?
Yes they are. That's why when you call it DiPrint(&A) this function would also work.
void DiPrint(Dictionary* A)
{
int i;
printf("Dict:\n");
for(i = 0; i <= A->last; i++)
printf("%d\n",A->elements[i]);
printf("End!");
}
You have an error in your code; in DiPrint(Dictionary A), your function expects type Dictionary but not type Dictionary *, you need to modify this calling function part in your code, so it would be:
DiPrint(A);
Not
DiPrint(&A);
Or another solution is modifying your function to accept a pointer instead, so it would be:
void DiPrint(Dictionary* A)
{
int i;
printf("Dict:\n");
for(i = 0; i <= (*A).last; i++)
printf("%d\n",(*A).elements[i]);
printf("End!");
}

Sort array of pointers

I'm looking to create a program that creates and stores N random complex numbers. However, it's necessary to use another array (of pointers) which points to every element on the complex array. Then, I have to present it sorted by its norm to the user.
To "sort" it, I just change to where the pointer array is pointing to. Then I just show the "sorted" array of pointers.
But I'm not getting it right. How can I achieve this?
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <math.h>
#define FORMATLOG "FORMATLOG: invalid parameters: ex3 <N>"
#define RANGE 18 - 6
enum { true, false };
typedef struct {
double real,
imag,
norm;
} Complex;
void generateComplex(int N) {
int i, test;
Complex vector[N];
for(i = 0; i < N; i++) {
vector[i].real = rand() % RANGE;
do { vector[i].imag = rand() % RANGE; } while(vector[i].imag == 0);
vector[i].norm = sqrt(pow(vector[i].real, 2) + pow(vector[i].imag, 2));
}
Complex *p_vect = &vector;
/* makes array point in order */
while(test == false) {
test == true;
for(i = 0; i < N - 1; i++)
if(vector[i].norm > vector[i + 1].norm) {
*p_vect[i] = &vector[i + 1];
*p_vect[i + 1] = &vector[i];
test = false;
}
}
for(i = 0; i < N; i++)
printf("\t%d -| %2g + %2gi | = %g\n", i, vector[i].real,
vector[i].imag,
vector[i].norm);
printf("********************************\n");
for(i = 0; i < N; i++)
printf("\t%d -| %2g + %2gi | = %g\n", i, p_vect[i].real,
p_vect[i].imag,
p_vect[i].norm);
}
int main(int argc, char **argv) {
if(argc != 2) {
puts(FORMATLOG);
return false;
}
srand(time(NULL));
int i, N = atoi(argv[1]);
generateComplex(N);
return true;
}
Complex *p_vect = &vector;
This creates a pointer to the existing array. The requirement is to create an array of pointers, not a pointer to an array.
Complex *p_vect[N];
for (i = 0; i < N; i++) {
p_vect[i] = &vector[i];
}
If you start with this, you can then sort p_vect without touching vector. Your sorting code, when written correctly, will make no mention of vector at all.

Cannnot Convert int to int. Arrays C

Hello I am having a hard time getting arrays to work in functions. I keep getting this error called C2664 "void ranNumPerm_10(int)' : cannot convert argument 1 from 'int [10]' to 'int'" I don't understand how to fix it...
Function ranNumPerm_10(int):
void ranNumPerm_10(int bubble_1[])
{
int oneRandno;
int haveRand[ARRAY_SIZE_1] = { 0 };
for (int i = 0; i < ARRAY_SIZE_1; i++)
{
do
{
oneRandno = rand() % ARRAY_SIZE_1;
} while (haveRand[oneRandno] == 1);
haveRand[oneRandno] = 1;
bubble_1[i] = oneRandno;
}
return;
}
This program is a unfinished program that will use bubble, selection, insertion sort algorithms. I just can't seem to populate arrays yet. I am trying to make a function that will do that by being a "random number permutation generator" so that every number is random and no number repeats its self. I could use some help in getting this code to work and solving error C2664.
FULL CODE:
#define _CRT_SECURE_NO_WARNINGS
#define ARRAY_SIZE_1 10
#include <stdio.h>
#include <stdlib.h>
void ranNumPerm_10(int bubble_1);
int main(void)
{
//Declarations
int bubble_1[ARRAY_SIZE_1];
//Bubble population # 10
ranNumPerm_10(bubble_1);
for (int i = 0; i < ARRAY_SIZE_1; i++)
{
printf("%d\n", bubble_1[i]);
}
printf("Array population test...\n");
return 0;
}
void ranNumPerm_10(int bubble_1[])
{
int oneRandno;
int haveRand[ARRAY_SIZE_1] = { 0 };
for (int i = 0; i < ARRAY_SIZE_1; i++)
{
do
{
oneRandno = rand() % ARRAY_SIZE_1;
} while (haveRand[oneRandno] == 1);
haveRand[oneRandno] = 1;
bubble_1[i] = oneRandno;
}
return;
}
The declaration and definition of ranNumPerm_10 have conflicting signatures. At the top of the full code, you declare it as void (int), but then the definition is void (int []).

Resources