Create program Random - c

i want to randomize this program that recreates a quiz
I tried to add the rand function but I don't know how to proceed
#include <stdio.h>
int main(void) {
int domanda, punti=0;
puts("Quiz sul Riscaldamento Globale\n Otterrai 1 punto per ogni risposta esatta e 0 per ogni risposta sbagliata o non valida\n");
puts("D1) Secondo il tredicesimo Obiettivo di Sviluppo Sostenibile, la minaccia piu' grande allo sviluppo e'/sono:\n");
puts("[1] I cambiamenti climatici\n"
"[2] L'inquinamento \n"
"[3] Lo scioglimento della calotta glaciale polare \n"
"[4] La crescita demografica\n");
scanf("%d", &domanda);
if(domanda == 1){
puts("risposta corretta\n");
punti = punti + 1;
}else{
puts("risposta sbagliata\n");
punti= punti + 0;
}
puts("D2) Il tempo e il clima sono la stessa cosa.");
puts("[1] Vero \n"
"[2] Falso \n");
scanf("%d", &domanda);
if(domanda == 2){
printf("risposta corretta\n");
punti =punti + 1;
}else{
printf("risposta sbagliata\n");
punti= punti + 0;
}
printf("hai fatto un punteggio di %d su 2", punti);
}
to work it works but I don't understand how to add the random if anyone knows how to do it help me thanks.

A rand() function is available in C standard library: man 3 rand. If you want to explore random number generation, check random.org.
As is, your program is not designed to support randomness: Questions and answers are hard-coded. A first step to make it randomizable would be to store them into a variable. For instance (with correct answer always at first position, end of questions identified with NULL, end of answers of a question identified with NULL, maximum of nine answers per question):
struct {
char * question;
char * answers[10];
} qa[] = {
{
"Secondo il tredicesimo Obiettivo di Sviluppo Sostenibile, la minaccia piu",
{
"I cambiamenti climatici",
"L'inquinamento",
"Lo scioglimento della calotta glaciale polare",
"La crescita demografica",
NULL,
}
},
{
"Il tempo e il clima sono la stessa cosa.",
{
"Falso",
"Vero",
NULL,
}
},
{ NULL, NULL }
};
A program using this variable would then count the number of questions, take one randomly, then display the answers randomly and remember what is the display index of the correct one.

Related

Taking data from a function to use it in another one in C language

typedef struct Projet
{
/* data */
char theme[20];
int diff;
char etudiant1[4]; //L'Etudiant 1 affecté dans le projet par Matricule
char etudiant2[4]; //L'Etudiant 2 affecté dans le projet par Matricule
}Projet;
/****---Function to add a project---****/
int AddProjet(int nmbProjet){
int rows;
Projet TabProj[nmbProjet]; // Table to store the projects
/* --Loop to get the project info-- */
for ( rows = 0; rows < nmbProjet; rows++)
{
printf("\t--> Theme %d : ",rows+1);
scanf(" %s",&TabProj[rows].theme);
/****Project Theme****/
printf("\t--> La difficulte [1-10] : ");
scanf(" %i",&TabProj[rows].diff);
/*****its difficulty*****/
printf("\n");
}
}
/*****************************************/
/****---Function to add 2 students in a project---****/
int AffEtudiant(int nmbPrjAff){
int choix_prj_aff;
Projet TabProj[nmbPrjAff];//Table of the projects
puts("--> Choisir un projet :");//Choose a project
/***--Loop to list all the project that the user has added--***/
for (int i = 0; i < nmbPrjAff; i++)
{
printf("\t%d- Projet %d :\n",i+1,i+1);
printf("\t -> %s",TabProj[i].theme);
printf("\n");
printf("\t -> %d",TabProj[i].diff);
printf("\n\n");
}
printf("--> Votre choix est : ");//Choice
scanf("%d",&choix_prj_aff);
printf("\n<----------------------->\n\n");
printf("--> Entrer le Matricule de 1 etudiant : ");//Enter the code of student 1
scanf("%s",&TabProj[choix_prj_aff-1].etudiant1);
printf("--> Entrer le Matricule de 2 etudiant : ");//Enter the code of student 2
scanf("%s",&TabProj[choix_prj_aff-1].etudiant2);
printf("\n<----------------------->\n\n");
}
/*****************************************************/
The problem is when I try to add two students after adding the projects the second function which is called (AffEtudiant) can't get the projects data (theme/difficulty) to list them. Instead it shows some garbage values, even though I called the same table that I have set in the function of adding projects (Project TabProj[]);
How can I get that table of data to use it in another function?
TabProj is a local variable inside each of the functions and it gets freed once the function exists. You should define it outside the functions and pass a point to it to the function when you want the function to update it.

how to create a list which contains another list in C

so i wanted to create a sub list liste_fav of the main list abbones , and here is the structure
/*********************************/
typedef struct liste_fav
{
signed char numf[20];
struct liste_fav *suiv;
}liste_fav;
/***********************************/
typedef struct abonnes// lz structure principale
{
signed char num_c[20];
signed char operateur [20];
signed char profil[20];
int credit;
liste_fav *liste;// on sait pas si on doit mettre une etoile ici
struct abonnes *adr;
}abonnes;
si I have created a list that contains
i want to create the main list that contains the information about the subscriber and his information we have a pointer to another sub list that contains the favourite numbers of this subscriber .
I want to create an application that will allow the subscriber to manipulate his list of favourite numbers ( adding a new one , or deleting ...) , before this I have to record data in the main and the sub list . I've done this function that allow us fill up the information and also to full the list of favourite numbers , ,could you help please
P.S:I have a doubt that is : the affectation of the head of the sub list in the field (liste_fav *liste)
the functions used :
liste_fav *allouer_fav ()// allouer un espace memoire, elle retourne l'adresse de l'espace alloue
{
return ((liste_fav*)malloc(sizeof(liste_fav)));
}
abonnes *allouer_abo ()
{
return ((abonnes*)malloc(sizeof(abonnes)));
}
void creation_abo(abonnes **R)
{
signed char ope [20],numm[20],prof[20],rr[20],num[20];
abonnes *s,*tet;
liste_fav *b,*a;
//(*R)->liste=NULL;
int i,cred,no,eee;
int k=1;
printf(" number of nodes to create : ");
scanf("%d",&no);//the number of the nodes to link of the list abonnes
printf("~~~~~~~~~~~~\n");
*R= allouer_abo();
printf("operateur %d :",k);
scanf("%s",&ope);
aff_operateur(R,ope);//strcpy((p -> operateur ),r);
printf("his number:");
scanf("%s",&numm);
aff_num_c(R,numm);//strcpy((p -> num_c),num)
printf("donnez son credit : ");
scanf("%d",&cred);
aff_credit(R,cred);// p-> credit =n;
printf("donnez son profil : ");
scanf("%s",&prof);
aff_profil(R,prof);//strcpy((p->profil),f)
printf("creation de la liste des favoris: ");
printf("donnez le nombre de mailons a creer :");
scanf("%d",&eee);
printf("donnez le numero du contact 1 : ");
scanf("%s",&rr);
// abonnes *pp = (*R )->liste -> numf;
//strcpy(pp,rr);
abonnes *J= (*R)->liste ;//I have doubt here, it's supposed to be the affectation oh the head of the list in J
J=allouer_fav();//return ((liste_fav*)malloc(sizeof(liste_fav)));
affnum_fav_propre(J,rr);//strcpy((p ->numf ),n);
for ( i=1;i<eee;i++)
{
b=allouer_fav();
printf("donnez le numero du contact %d :",i+1);
scanf("%s",&num);
affnum_fav_propre(b,num);strcpy((p ->numf ),n);
aff_adr_fav_propre(J,b);// s -> suiv = q; s a pointer to list abonnes
}
aff_adr_fav_propre(b,NULL);
// we affected the heads, now we will affect the other structures to link
tet= R;
for(i=1;i<no;i++)
{
k++;
s= allouer_abo();
printf("_-__-_-_-_-_-_-_-_-_-_-_-_-_\n");
printf("give the operateur %d :",k);
scanf("%s",&ope);
aff_operateur(s,ope);
printf("donnez son numero : ");
scanf("%s",&numm);
aff_num_c(s,numm);
printf("the credit : ");
scanf("%d",&cred);
aff_credit(s,cred);
printf("the profil : ");
scanf("%s",&prof);
aff_profil(s,prof);
printf("creation of list favoris: ");
printf(" numbre of nodes you wanna create :");
scanf("%d",&eee);
printf(" numero the favoris 1 : ");
scanf("%s",&rr);
abonnes *J= (*R)->liste ;
J=allouer_fav();
affnum_fav_propre(J,rr);
for ( i=1;i<eee;i++)
{
b=allouer_fav();
printf("numero %d :",i+1);
scanf("%s",&num);
affnum_fav_propre(b,num);// strcpy((p ->numf ),n);
aff_adr_fav_propre(J,b);// s -> suiv = q;
J=b;
}
// aff_adr_fav_propre(b,NULL);
aff_adr_abo(R,s);//p-> adr=q
R=s;
}
aff_adr_abo(R,NULL);
aff_adr_fav_propre(b,NULL);
//s=NULL;
////tet=NULL; i was not sure
return ( tet);
}
Any help or proposition? hope you understood my problem
Yes, your doubt is correct. This line:
abonnes *J= (*R)->liste;
will not give you the desired result. Also, J needs to be a liste_fav*, not an abonnes*. Like so:
liste_fav* J = allouer_fav();
(*R)->liste = J;
You'll need to make the same change in the code below.
[As an aside, you'd make your life easier if you created a function which populated a single abonnes instance, and call it once for the head, then inside the "affect other structures to link" loop. As it is, you've got a large chunk of duplicated code which you'll have to fix twice.]
I have my doubt about aff_adr_fav_propre because you don't show the code, and the comment is wrong [it is not "a pointer to list abonnes", it is "a pointer to liste_fav"]. It needs to perform the following:
J->suiv = b;
J = b;
Also you fail to mention in your writeup is the problems you have with returning the results. You attempt to return tet, but you've declared creation_abo to be void. I think what you want to do is declare it as follows:
abonnes *creation_abo()
{
<existing code>
return tet;
}
The caller would look like this:
abonnes *master_list = creation_abo();
Your life would be improved with consistent indentation and descriptive variable names as well.

malloc() triggers breakpoint in C

I have this program (school exercise) that simulates a software for managing tests and exercises. Everything works fine... until it doesn't. The second time, in the menu of the program, I want to add an exercise (calling so the function called inserisciEsercizio, "addExercise" in English), the malloc (esercizioPtr newEsercizio = (esercizioPtr)malloc(sizeof (esercizio));) "triggers a breakpoint". I attach the function and where the structs are declared.
What does that mean? How can I resolve it?
Thank you.
I tried looking it up, but I couldn't find anything that could help me understand.
The variables are written in Italian (half in Italian, half in English to be honest). Hope it's not too much of a problem.
struct ListaEsercizi
{
esercizioPtr esercizio;
struct ListaEsercizi *nextListaEsercizi;
};
typedef struct ListaEsercizi listaEsercizi;
typedef listaEsercizi *listaEserciziPtr;
struct Esercizio
{
char titolo[20];
char domanda[40];
char risposte[3][50];
int difficolta;
struct Esercizio *nextEsercizio;
};
typedef struct Esercizio esercizio;
typedef esercizio *esercizioPtr;
void inserisciEsercizio(esercizioPtr *firstEsercizio, autorePtr Autore)
{
listaEserciziPtr newLista = (listaEserciziPtr)malloc(sizeof (listaEsercizi));
esercizioPtr newEsercizio = (esercizioPtr)malloc(sizeof (esercizio)); // <--- here!
//se ne stabiliscono i parametri
if (newEsercizio != NULL)
{
newEsercizio->nextEsercizio = NULL;
printf("Inserisci titolo esercizio ");
scanf_s("%s", newEsercizio->titolo, 20);
printf("Inserisci domanda esercizio: ");
scanf_s("%s", newEsercizio->domanda, 30);
printf("Inserisci difficolta esercizio: ");
scanf_s("%d", &(newEsercizio->difficolta));
for (int i = 0; i < 3; i++)
{
printf(" Scrivere la risposta:\n");
scanf_s("%s", newEsercizio->risposte[i], 100);
}
if (*firstEsercizio == NULL) //caso in cui creo il primo oggetto
{
*firstEsercizio = newEsercizio;
}
else //se non il primo lo inserisco all'interno della lista oggetti
{
newEsercizio->nextEsercizio = *firstEsercizio;
*firstEsercizio = newEsercizio;
}
//mettere malloc
if (newLista != NULL)
{
newLista->nextListaEsercizi = NULL;
newLista->esercizio = newEsercizio;
if (Autore->esercizi == NULL) //caso in cui creo il primo oggetto
{
Autore->esercizi = newLista;
}
else //se non il primo lo inserisco all'interno della lista oggetti
{
newLista->nextListaEsercizi = Autore->esercizi;
Autore->esercizi = newLista;
}
}
else
{
//nel caso malloc restituisca NULL
printf("Memoria non disponibile \n");
}
}
else
{
//nel caso malloc restituisca NULL
printf("Memoria non disponibile \n");
}
}
In you declarations you have:
char risposte[3][50];
And later in the code you have:
scanf_s("%s", newEsercizio->risposte[i], 100);
It allows a 100 chars in a 50 chars array, which probaly leads to memory corruption in the first call to inserisciEsercizio. Using sizeof instead of a constant with scanf_s is usually a good idea:
scanf_s("%s", newEsercizio->risposte[i], sizeof(newEsercizio->risposte[i]));

Why the last iteration repeats?

My question refers to the while(!feof(arch)) that repeats the last registry two times. Thanks if you take some of your time to answer. I'm in first year learning basics.
The information is on an archive, so the first input shouldn't be 's' because it isn't the first time to input. Then the program list the infomation but the last registry repeats two times.
#include <stdio.h>
typedef struct{
int legajo;
char nombre[30];
int ingreso;
int pparcial;
int sparcial;
} reg_alumno;
reg_alumno funcionleer(void);
typedef FILE * archivo; //Se define el tipo de dato "archivo".
archivo arch; //Se declara una variable de archivo.
int main(void){
reg_alumno alumno,alu;
int ca,i,j=0;
char respuesta;
printf("Desea ingresar datos por primera vez?");
scanf("%c",&respuesta);
printf("Ingrese cantidad alumnos");
scanf("%d",&ca); //Pide cantidad alumnos
if(respuesta=='s'){
arch = fopen("alumnos.dat","w"); //Crear archivo para escribir, crea si no existe)
for(i=0;i<ca;i++){
alumno = funcionleer(); //Lee alumno
fseek(arch,sizeof(reg_alumno)*i,SEEK_SET); //Busca la última posición del archivo
fwrite(&alumno,sizeof(reg_alumno),1,arch); //Escribe en la última posición
}
}
else{
arch = fopen("alumnos.dat","r+");
while(!feof(arch)){
fseek(arch,sizeof(reg_alumno)*j,SEEK_SET); //Pasa de registro en registro(alumno en alumno).
fread(&alu,sizeof(reg_alumno),1,arch); //Trae a la memoria principal un alumno
printf("Legajo N %d: %s\n",alu.legajo,alu.nombre);
j++;
}
}
fclose(arch); //Cierra el archivo
}
reg_alumno funcionleer(void){ //Función leer
reg_alumno alumno;
printf("Ingrese el numero de legajo:\n");
scanf("%d",&alumno.legajo);
printf("Ingrese el nombre:\n");
scanf("%s",alumno.nombre);
return(alumno);
}
Good to check result of IO operations #WhozCraig.
The code's problem is that its prints even if fread() fails.
// No check of return value.
fread(&alu,sizeof(reg_alumno),1,arch);
printf("Legajo N %d: %s\n",alu.legajo,alu.nombre);
Code uses feof() incorrectly. Many SO posts on that.
Since OP implies code is required to use feof() by teacher: following are 2 good ways to use feof()
for (;;) {
if (fseek(arch,sizeof(reg_alumno)*j,SEEK_SET)) break;
if (fread(&alu,sizeof(reg_alumno),1,arch) == 0) break;
printf("Legajo N %d: %s\n",alu.legajo,alu.nombre);
j++;
}
// If loop quit because of EOF
if (feof(arch)) printf("Success");
else if (!ferror(arch)) printf("IO Error");
Or
for (;;) {
if (fseek(arch,sizeof(reg_alumno)*j,SEEK_SET)) break;
fread(&alu,sizeof(reg_alumno),1,arch);
if (!feof(arch)) break;
if (!ferror(arch)) break;
printf("Legajo N %d: %s\n",alu.legajo,alu.nombre);
j++;
}

Stack overflow with pointers in C

I'm new in C, and I'm trying some exercises that I found.
In one of the exercises I'm trying to use a pointer to a string (a char array), but it doesn't work. It compiles, but when is executed, it throws "stack overflow" (well, I think is an "stack overflow" because I have it in spanish).
These are the problematic lines:
//This is the variable declaration, before this, there is the "main function" declaration
char entrada[100];
char *ult=entrada;
char cantidadstr[10];
int i,j,k = 0;
int res;
scanf ("%s",entrada);
printf ("\n%s",entrada);
//Here crashes
printf ("Hola %s",ult);
while (*ult != "\0"){
//And here there's more code
Thank you in advance!!
EDIT
(I can't answer me :))
Then, I'll post a bit more of code.
When I execute, after inserting data, it throws "Violación de segmento", and google says that means Stack Overflow
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
int main(void){
char entrada[1001*11*101];
/*Asi tenemos el tamano maximo:
1001 por las 1000 posibles lineas, mas la primera
11 por el tamano maximo del numero (1 + 9 ceros), mas el espacio o salto de linea siguiente
101 por el numero de numeros por linea, mas el primero
*/
char *ult=entrada;
char cantidadstr[10];
int i,j,k = 0;
int res;
memset (entrada,'\0',1001*11*101);
scanf ("%s",entrada);
printf ("\n%s",entrada);
//poniendo ese print ahi arriba, ese me lo muestra, por tanto, el fallo esta en el puntero de debajo de esta linea
printf ("Hola %s",ult);
while (*ult != "\0"){
if(*ult == "\n"){
if(i != 0){
printf("\n");
}
i++;
j = 0;
}
else if(i != 0){
if(*ult == " "){
j++;
k=0;
res = atoi(cantidadstr);
printf("%d ",res*2);
//Este es el otro cambio que hablaba
cantidadstr[10] = '\0';
}
else if(j != 0){
cantidadstr[k] = *ult;
}
}
k++;
*ult++;
}
return 0;
}
This is the exact and full code, with comments in spanish for another forum. The size of "entrada" is big enough for any data send in the exercise. The "memset" is just added. The second comment shows where it crashes
Thank you for your quick answer!!
The code before the while loop is fine as it compiles and runs correctly(as far as i can think)
But the while loop has an error i'm not sure how it compiled in your case.
because you have written
while (*ult != "\0"){
which gives compiler error as
*ult is of type char
"\0" is of type const char*
you have to convert "\0" to '\0'
The following line:
cantidadstr[10] = '\0';
will write past the end of cantidadstr, which is definitely bad and most likely causing your stack overflow. If you want to null terminate cantidadstr, use cantidadstr[9]= '\0';. Arrays in C are zero based, not one based, so the first element of an array of size N starts at [0] and the last referenceable element is [N-1].

Resources