i don't understand why when i try to print values in archivio[] with stampa function,this program prints
"studente","matricola","nome","cognome"
correctly, but doesn't print values from stampaEsami.
#include <stdio.h>
#include <stdlib.h>
#define MAXSTUDENTI 20
#define MAXSTRINGA 100
#define MAXESAMI 25
/* run this program using the console pauser or add your own getch, system("pause") or input loop */
typedef char Stringa[MAXSTRINGA];
typedef enum { uno, due, tre, FC
} AnnoCorso;
typedef struct {
Stringa nomeEsame;
int voto;
} Esame;
typedef struct {
Esame listaEsami[MAXESAMI];
int numeroEsami;
}ListaEsame;
typedef struct {
int matricola;
Stringa nome;
Stringa cognome;
AnnoCorso anno;
ListaEsame esami;
} Studente;
void init(Studente[], int);
void acquisisciEsami(Studente, int);
void stampa(Studente[], int);
void stampaEsami(ListaEsame);
void init(Studente archivio[], int n){
int i;
int nEsami;
for(i = 0; i < n; i++){
printf("Studente n. %d\n", i+1);
printf("Inserire matricola: ");
scanf("%d", &archivio[i].matricola);
printf("Inserire nome: ");
scanf("%s", &archivio[i].nome);
printf("Inserire cognome: ");
scanf("%s", &archivio[i].cognome);
printf("Inserire il numero di esami svolti: ");
scanf("%d", &archivio[i].esami.numeroEsami);
nEsami = archivio[i].esami.numeroEsami;
if(nEsami != 0) {
acquisisciEsami(archivio[i], nEsami);
}
}
}
void acquisisciEsami(Studente studente, int n){
int i;
for(i = 0; i < n; i++) {
printf("Inserire nome esame:");
scanf("%s", studente.esami.listaEsami[i].nomeEsame);
printf("Inserire voto esame:");
scanf("%d", &studente.esami.listaEsami[i].voto);
}
}
void stampa(Studente archivio[], int n){
printf("\nGli studenti presenti in archivio sono:\n");
int i;
for(i = 0; i < n; i++){
printf("Studente n. %d:\n", i+1);
printf("Matricola: %d\n", archivio[i].matricola);
printf("Nome: %s\n", archivio[i].nome);
printf("Cognome: %s\n", archivio[i].cognome);
stampaEsami(archivio[i].esami);
}
}
void stampaEsami(ListaEsame esami){
int i = 0;
int n = esami.numeroEsami;
for(i = 0; i < n; i++){
printf("Nome esame: %s\n", esami.listaEsami[i].nomeEsame );
printf("Voto esame: %d\n", esami.listaEsami[i].voto);
}
}
int main(int argc, char *argv[]) {
Studente studenti[MAXSTUDENTI] ;
int n;
printf("Inserire il numero di studenti da memorizzare in archivio:\n ");
scanf("%d", &n);
init(studenti, n);
stampa(studenti, n);
return 0;
}
If input is:
Inserire il numero di studenti da memorizzare in archivio:1
Inserire matricola: 13434
Inserire nome: test
Inserire cognome: test
Inserire il numero di numero di esami svolti: 1
Inserire nome esame: asd2
Inserire voto esame: 20
it prints:
Gli studenti presenti in archivio sono:
Studente n.1:
Matricola: 13434
Nome : test
Cognome: test
Nome esame:
Voto esame: 0
Your problem is acquisisciEsami function.
It should accept Studente *, instead of a variable passed by value.
void acquisisciEsami(Studente *studente, int n)
{
int i;
for(i = 0; i < n; i++)
{
printf("Inserire nome esame:");
scanf("%s", studente->esami.listaEsami[i].nomeEsame);
printf("Inserire voto esame:");
scanf("%d", &studente->esami.listaEsami[i].voto);
}
}
So what is the problem? Your code is compiling a structure that has local scope into acquisisciEsami function and all data will be lost when function ends. So esami member of archivio[i] is not modified.
Passing archivio[i] by reference to acquisisciEsami you can change content of esami memeber of archivio[i]
Obviously the call to acquisisciEsami will be:
acquisisciEsami(&archivio[i], nEsami);
As I commented you have issue to fix:
scanf("%s", &archivio[i].nome); must be scanf("%s",archivio[i].nome);
scanf("%s", &archivio[i].cognome); should be scanf("%s",archivio[i].cognome);
Related
#include <stdio.h>
void chercherVal(int tab[], int N, int A, int *pos, int *nb_occ) {
int i = 0;
while (i < N) {
if (tab[i] == A) {
*pos = i;
*nb_occ = *nb_occ + 1;
}
i++;
}
printf("la position est %d et le nombre d'occurence est %d", pos, nb_occ);
}
int main() {
int pos = -1, nb_occ = 0;
char A;
int i, N;
int tab[100];
printf("saisir le nombre d'elements de tab :");
scanf("%d", &N);
for (i = 0; i < N; i++) {
printf("saisir l'element %d du tableau tab :", i + 1);
scanf("%d", &tab[i]);
}
printf("saisir la valeur a rechercher :");
scanf("%s", &A);
chercherVal(tab, N, A, &pos, &nb_occ);
}
Here is one pointer problem (or lack of)
printf("la position est %d et le nombre d'occurence est %d", pos, nb_occ);
should be
printf("la position est %d et le nombre d'occurence est %d", *pos, *nb_occ);
The compiler should have warned that the wrong argument types are being passed.
Reading a string with scanf("%s", &A); into a single char has undefined behavior because scanf() will store the bytes and a null terminator, writing beyond the destination variable.
You should either make A and int and read a number: scanf("%d", &A);
Or you should read a single char with scanf(" %c", &A); (note the space before the % to skip pending white space, including the newline left in the standard input by previous calls to scanf().
Here is a modified version:
#include <stdio.h>
void chercherVal(const int tab[], int N, int A, int *posp, int *nb_occp) {
int pos = -1, occ = 0;
for (int i = 0; i < N; i++) {
if (tab[i] == A) {
occ++;
if (pos < 0) { /* only store the first position */
pos = i;
}
}
}
/* always store the return values */
*posp = pos;
*nb_occp = occ;
}
int main() {
int tab[100];
int N, A, pos, nb_occ;
printf("saisir le nombre d'elements de tab : ");
if (scanf("%d", &N) != 1)
return 1;
if (N > 100) /* prevent buffer overflow */
N = 100;
for (int i = 0; i < N; i++) {
printf("saisir l'element %d du tableau tab : ", i + 1);
if (scanf("%d", &tab[i]) != 1)
return 1;
}
printf("saisir la valeur a rechercher : ");
if (scanf("%d", &A) != 1)
return 1;
chercherVal(tab, N, A, &pos, &nb_occ);
printf("la position est %d et le nombre d'occurences est %d\n", pos, nb_occ);
return 0;
}
im trying to do a programa in C. Capture name, age, album number, names and songs withing each album. Im ok but it only prints the last albums name. Lets say i input 3 albums, "a", "b" and "c". It would only print c 3 times. And it should be a,b and c. Thank you.
#include <stdio.h>
int main() {
//variables
int edadCantante;
int x,numeroCanciones[x];
char nombreCantante;
char nombreDiscos[30][x];
printf("Introduzca el nombre del artista: ");
scanf(" %[^\n]",nombreCantante);
printf("Introduzca edad del artista: ");
scanf("%d", &edadCantante);
printf("Introduzca número de discos: ");
scanf("%d\n",&x );
// taking input and storing it in an array
for(int i = 0; i < x; ++i) {
scanf("%[^\n]%*c", nombreDiscos[i]);
}
printf("Desplegando albumes:\n ");
// printing elements of an array
for(int i = 0; i < x; ++i) {
printf("%s\n", nombreDiscos[i]);
}
printf("Número de canciones por album respectivamente:\n ");
for(int i = 0; i < x; ++i) {
scanf("%d", &numeroCanciones[i]);
}
printf("Desplegando número de canciones:\n ");
// printing elements of an array
for(int i = 0; i < x; ++i) {
printf("Número de canciones en album %d = %d\n",i+1,numeroCanciones[i]);
}
return 0;
}
You need to move the declaration of numeroCanciones and nombreDiscos. Like this:
int x;
scanf("%d\n",&x );
int numeroCanciones[x];
But don't forget to check the return value of scanf in case a reading failed.
I'm a beginner in C, I'm trying to read a file in order to update a struct but every time I do it it gives me an error (I'm working with visual studio 2013).
This is my code so far:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct Registro{
int cedula;
char nombre[20];
char apellido[20];
char direccion[50];
int ingreso;
};
void agregarP(struct Registro * informacion, int * n){
int op,i,aux;
printf("Cuantas personas desea agregar?\n");
fflush(stdin);
scanf_s("%i", &op);
aux = op;
op += *n;
for (i = *n; i < op; i++){
printf("Introduzca la cedula\n");
scanf_s("%i", &informacion[i].cedula);
printf("Introduzca el nombre\n");
fflush(stdin);
gets_s(informacion[i].nombre);
printf("Introduzca el apellido\n");
gets_s(informacion[i].apellido);
printf("Introduzca la direccion\n");
gets_s(informacion[i].direccion);
printf("Introduzca el ingrso anual\n");
scanf_s("%i", &informacion[i].ingreso);
system("cls");
}
*n += aux;
}
bool comprobacion(int n1, int n2){
if (n1 == n2){
return true;
}
else {
return false;
}
}
void borrar(struct Registro * s, int *n){
int i, ced;
struct Registro aux;
bool compr;
printf("Introduzca la cedula de la persona que desea borrar\n");
fflush(stdin);
scanf_s("%i",&ced);
for (i = 0; i < *n; i++){
if (s[i].cedula == ced){
compr = comprobacion(*n, i);
if (compr){
break;
}
else{
aux = s[*n - 1];
s[*n - 1] = s[i];
s[i] = aux;
break;
}
}
}
*n -= 1;
}
void mostrar(struct Registro * informacion, int n){
int i;
printf("Cedula \t Nombre \t Apellido \t Direccion \t Ingreso \n");
for (i = 0; i < n; i++){
printf("%i \t ", informacion[i].cedula);
printf("%s \t ", informacion[i].nombre);
printf("%s \t ", informacion[i].apellido);
printf("%s \t ", informacion[i].direccion);
printf("%i \n", informacion[i].ingreso);
}
}
void mostrarPorOrden(struct Registro * s, int n){
int i, j,cont = 0, op;
struct Registro aux;
printf("1 para mostrar por orden de cedula\n");
printf("2 para mostrar por orden de apellido\n");
fflush(stdin);
scanf_s("%i", &op);
switch (op){
case 1: for (i = 0; i < n+1; i++){
cont = 0;
for (int j = 0; j < n - 1; j++)
{
if (s[j].cedula > s[j + 1].cedula){
aux = s[j+1];
s[j + 1] = s[j];
s[j] = aux;
cont++;
}
}
if (cont == 0) break;
}
mostrar(s, n);
break;
case 2: for (i = 0; i < n + 1; i++){
cont = 0;
for (int j = 0; j < n - 1; j++)
{
if (s[j].apellido[0] > s[j + 1].apellido[0]){
aux = s[j+1];
s[j + 1] = s[j];
s[j] = aux;
cont++;
}
}
if (cont == 0) break;
}
mostrar(&s[0], n);
break;
}
}
void guardarArch(FILE * ff, struct Registro * s, int n){
fopen_s(&ff, "Datos.txt", "w");
int i;
for (i = 0; i < n; i++){
fprintf(ff,"%d", s[i].cedula); fprintf(ff, "\n");
fprintf(ff, s[i].nombre); fprintf(ff, "\n");
fprintf(ff, s[i].apellido); fprintf(ff, "\n");
fprintf(ff, s[i].direccion); fprintf(ff, "\n");
fprintf(ff, "%d",s[i].ingreso); fprintf(ff, "\n");
}
fclose(ff);
}
void leerArch(FILE * ff, struct Registro * s, int * n){
fopen_s(&ff, "Datos.txt", "r");
int i = 0;
while (!feof(ff)){
}
fclose(ff);
}
void main(){
FILE * infor = new FILE;
struct Registro informacion[30];
int op = -1;
int persona = 0;
while (op != 0){
printf("1 para agregar una persona\n");
printf("2 para mostrar\n");
printf("3 para borrar\n");
printf("4 para mostrar ordenado\n");
printf("5 para guardarlo en un archivo\n");
printf("6 para leer de un archivo\n");
printf("0 para salir\n");
scanf_s("%i", &op);
fflush(stdin);
switch (op)
{
case 1: agregarP(&informacion[0], &persona);
printf("%i", persona);
break;
case 2: mostrar(&informacion[0], persona);
break;
case 3: borrar(&informacion[0], &persona);
break;
case 4: mostrarPorOrden(&informacion[0], persona);
break;
case 5: guardarArch(infor, &informacion[0], persona);
break;
case 6: leerArch(infor, &informacion[0], &persona);
break;
}
system("pause");
system("cls");
}
}
PD: Sorry for my english.
Edited.
This is the part where I'm having trouble, it breaks automatically. It reads the stuff now but with a lot of new lines
int ayudaLeer(FILE * ff, struct Registro * s, int * n){
if (feof(ff)) return -1;
char * c = new char[];
int p = fgetc(ff);
fscanf_s(ff, "%d", &s[*n].cedula);
fgets(c, 20, ff);
fgets(s[*n].nombre, 20, ff);
fgets(s[*n].apellido, 20, ff);
fgets(s[*n].direccion, 20, ff);
fscanf_s(ff, "%d", &s[*n].ingreso);
*n+=1;
ayudaLeer(ff, s, n);
}
void leerArch(FILE * ff, struct Registro * s, int * n){
fopen_s(&ff, "Datos.txt", "r");
int i = 0;
ayudaLeer(ff, s, &i);
*n = i-1;
fclose(ff);
}
i'm learnig how to code in C.
i have to create a record for a person, with an birthday and a ID number
the code is composed of 3 files
the fist is a header
// definição do tipo
typedef int vetor[10];
typedef struct
{
char nome[50];
vetor nasceu;
vetor cpf;
} dados ;
void cadastro (dados*, char[50], vetor, vetor);
then there is the definitions of the header
#include <stdio.h>
#include <string.h>
#include "cadastro.h"
void cadastro (dados *usuario, char name[50], vetor ddn, vetor cpf)
{
int i;
strcpy(usuario->nome,name);
for (i = 0; i < 50; i++)
{
usuario->nasceu[i] = ddn[i];
}
for (i = 0; i < 10; i++)
{
usuario->cpf[i] = cpf[i];
}
}
and the last file uses the header to generate the record
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "cadastro.h"
int preenche_cadastro (char a[],vetor b,vetor c)
{
int i;
printf ("inserir nome: ");
gets (a);
printf("inserir data de nascimento (campos separados por espaco): ");
for (i = 0; i < 3; i++)
{
scanf("%d",&b[i]);
}
printf ("inserir CPF (campos separados por espaco): ");
for (i = 0; i < 4; i++)
{
scanf("%d",&c[i]);
}
return (0);
}
int imprime_cadastro (dados usuario)
{
printf("\nnome: %s",usuario.nome);
printf("\ndata de nascimento: %d / %d / %d\n", usuario.nasceu[0],usuario.nasceu[1],usuario.nasceu[2]);
printf("CPF: %d . %d . %d - %d\n", usuario.cpf[0],usuario.cpf[1],usuario.cpf[2],usuario.cpf[3]);
return(0);
}
int main(void)
{
dados new_entry;
char name[50];
vetor born, cpf;
int i;
preenche_cadastro (name,born,cpf);
cadastro(&new_entry, name, born, cpf);
imprime_cadastro(new_entry);
return (0);
}
i don't really know how to debug, but as far as i could tell, the `Segmentation fault' occurs only at the line
return (0);
i'm going mad here, can anybody help me?
sorry for my english, it's not mother language
You invoked undefined behavior by accessing out-of-range of array in the line
usuario->nasceu[i] = ddn[i];
in function cadastro, and then the program happened to crash there.
Do not invoke undefined behavior. Instead of using magic number 10, you should define the number of elements in the array and use it.
Also note that using values of uninitialized variables having automatic storage duration, which are indeterminate, also invokes undefined behavior.
corrected header:
// definição do tipo
#define VETOR_NUM 10
typedef int vetor[VETOR_NUM];
typedef struct
{
char nome[50];
vetor nasceu;
vetor cpf;
} dados ;
void cadastro (dados*, char[50], vetor, vetor);
corrected implementation of cadastro:
#include <stdio.h>
#include <string.h>
#include "cadastro.h"
void cadastro (dados *usuario, char name[50], vetor ddn, vetor cpf)
{
int i;
strcpy(usuario->nome,name);
for (i = 0; i < VETOR_NUM; i++)
{
usuario->nasceu[i] = ddn[i];
}
for (i = 0; i < VETOR_NUM; i++)
{
usuario->cpf[i] = cpf[i];
}
}
corrected main() function:
int main(void)
{
dados new_entry;
char name[50];
vetor born = {0}, cpf = {0}; /* initialize arrays */
/* i is removed because it wasn't used */
preenche_cadastro (name,born,cpf);
cadastro(&new_entry, name, born, cpf);
imprime_cadastro(new_entry);
return (0);
}
One more note: You shouldn't use gets(), which has unavoidable risk of buffer overrun.
Your first loop should only copy 10 items rather than 50.
for (i = 0; i < 10; i++)
{
usuario->nasceu[i] = ddn[i];
}
This loop in your cadastro function:
for (i = 0; i < 50; i++)
{
usuario->nasceu[i] = ddn[i];
}
Seems to not be in line with the size of the nasceu arrary:
typedef int vetor[10];
typedef struct
{
char nome[50];
vetor nasceu;
vetor cpf;
} dados ;
Have you tried changing to:
for (i = 0; i < 10; i++)
{
usuario->nasceu[i] = ddn[i];
}
?
I need to write a file(not binary) with students and each ones grades(int note[10] under this form). I do not get any errors but when I try to write the file just the last grade is printed, and I don't know how to print the entire list. For example (int nr_note means how many grades does the student have) if a students grades are 6, 8, 9 it just prints the 9.
Thank you in advance.
#include <stdio.h>
#include <stdlib.h>
struct student{
int nr_matricol;
char nume[10];
int nr_note;
int note[10];
};
void citire_date(struct student *studenti, int n, FILE *f){
int i, j;
for(i=0;i<n;i++){
printf("Studentul %d\n", i+1);
printf("Numarul matricol: "); scanf("%d", &(studenti+i)->nr_matricol);
printf("Numele studentului: "); fflush(stdin); gets((studenti+i)->nume);
printf("Numarul de note: "); scanf("%d", &(studenti+i)->nr_note);
for(j=0;j<((studenti+i)->nr_note);j++){
printf("Nota %d: ", j+1); scanf("%d", &(studenti+i)->note[i]);
}
fprintf(f, "Numar matricol: %d\nNume: %s\nNote: %d \n", ((studenti+i)->nr_matricol) ,((studenti+i)->nume), ((studenti+i)->note[i]));
}
}
int main()
{
struct student studenti[20];
FILE *f;
int n;
f = fopen("studenti.txt", "w");
if(f==NULL){
printf("Nu s-a putut deschide/crea fisierul pentru scriere.");
exit(1);
}
printf("Introduceti numarul de studenti: "); scanf("%d", &n);
citire_date(studenti, n, f);
fclose(f);
return 0;
}
Change citire_date() function like this :
void citire_date(struct student *studenti, int n, FILE *f){
int i, j;
for(i=0;i<n;i++){
printf("Studentul %d\n", i+1);
printf("Numarul matricol: "); scanf("%d", &(studenti+i)->nr_matricol);
printf("Numele studentului: "); fflush(stdin); gets((studenti+i)->nume);
printf("Numarul de note: "); scanf("%d", &(studenti+i)->nr_note);
for(j=0;j<((studenti+i)->nr_note);j++){
printf("Nota %d: ", j+1); scanf("%d", &(studenti+i)->note[j]);
}
fprintf(f, "Numar matricol: %d\nNume: %s\n", ((studenti+i)->nr_matricol) ,((studenti+i)->nume) );
// Printing the notes
for(j=0;j<((studenti+i)->nr_note);j++){
fprintf(f, "Note: %d = %d \n", j+1, ((studenti+i)->note[j]));
}
}
}
You need to use a loop to print all the notes.