the function does not update the parameter C - c

i have this function that extract the first name and the gendre form a file combined and then seperate them
for example the function extract "Aaliyah,F" and the separate them as prenom = Aaliyah and genre = F
the problem is that the function does not update the genre value and still at NULL
so for this code
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>
int AleaNombre(int min, int max) {
return (rand() % (max - min + 1)) + min;
}
void recuperer_prenom(char genre , char prenom[20] ) {
FILE* f2 = fopen("C:\\Users\\PC PRO DZ\\Desktop\\Projects\\C\\TP essai\\prenom.txt", "r");
fseek(f2, 0, SEEK_END);
int length = ftell(f2);
fseek(f2, 0, SEEK_SET);
char line1[length + 1];
fgets(line1, length + 1, f2);
int i = AleaNombre(1, 100);
int cpt = 0;
char* tok = strtok(line1, " ; ");
cpt++;
while (cpt != i) {
tok = strtok(NULL, " ; ");
cpt++;
}
//separer le prenom et le genre tel que prenom,genre et le genre est le dernier caractere en utilisant strtok
char* tok2 = strtok(tok, ",");
strcpy(prenom, tok2);
tok2 = strtok(NULL, ",");
genre = tok2[0];
printf("%s %c", prenom, genre); // the result is for example: "Aaliyah F"
rewind(f2);// ^ ^
fclose(f2);// |prenom| |genre|
}
int main () {
srand (time(NULL));
char prenom[20];
char genre;
recuperer_prenom(genre, prenom);
printf ("%s %c", prenom, genre);// however the result here is "Aaliyah"
return 0;
}
i tried changing the way that the prenom and genre are separated and change the type of genre from char to a sting but didn'f fixe it

I have removed the random part and created a struct to store your fields:
You should pass by reference as said in comment
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>
#define MAXLINE 256
typedef struct data {
char prenom[20];
char genre;
} data;
void recuperer_prenom(data *d) {
FILE* f2 = fopen("prenom.txt", "r");
char line1[MAXLINE];
fgets(line1, MAXLINE, f2);
char* tok = strtok(line1, " ; ");
//separer le prenom et le genre tel que prenom,genre et le genre est le dernier caractere en utilisan>
char* tok2 = strtok(tok, ",");
strcpy(d->prenom, tok2);
tok2 = strtok(NULL, ",");
d->genre = tok2[0];
printf("%s %c\n", d->prenom, d->genre); // the result is for example: "Aaliyah F"
fclose(f2);// |prenom| |genre|
}
int main () {
data d;
recuperer_prenom(&d);
printf ("%s %c\n", d.prenom, d.genre);// however the result here is "Aaliyah"
return 0;
}

Related

Reading from binary file LANG C

I am having trouble reading from a bin file.
I am recording some text in binary (correctly i think), but my code isn't able to read the text I wrote and print it in the console. When i open the file the information is there (this document is use to storage the information from the client and the login access) and i can login, but when i try to read and print in console it doesn't show me.
I am using a struct to get the values from the document, and then i open the document "fopen()" but when i try to read with the "fread()" in a "while" I don't get in, the print don't give me the right information
I try to reduce as much i could of the code.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <locale.h>
#include <dir.h>
#include <unistd.h>
#include <time.h>
#include <conio.h>
#define SIZE 1000
typedef struct
{
char id[10];
char nome[100];
char passe[100];
}Pacient;
Pacient p1;
FILE* filepaciente;
//variables
char tmpnome[100], tmppassword[100];
//variable for path
char nomedoc[15];
char pasta[250];
char sessionName[15];
char tmp_name[15];
char fullpath[200];
char tmp_nome[15];
void vedocumento(int* i, char* line, char pacienteData[])
{
// DEFINE A VARIÁVEL USERDATA COMO UMA STRING VAZIA
strcpy(pacienteData, "");
// IF FINDS "|", GO TO THE NEXT CHARACTER
if (line[*i] == '|')
{
(*i)++;
}
//WHEN THE CHARACTER IS DIFERENT THEN |, ADD THAT CHARACTER TO THE ARRAY USERDATA
while (line[*i] != '|') // *i = 0
{
strncat(pacienteData, &line[*i], 1); // userData = "" ; userData = userData + carater
(*i)++;
}
}
findpath()
{
//PROCURA O CAMINHO ONDE SE ENCONTRA O PROJETO
if (getcwd(pasta, sizeof(pasta)) == NULL)
{
printf("ERROR!\n");
}
else
{
strcat(pasta, "\\file\\");
//CRIA O FICHEIRO COM O NUMERO DE INTERNO
strcpy(nomedoc, strcat(tmp_nome, ".bin"));
//JUNTA O CAMINHO COMPLETO AO NOME DO FICHEIRO
strcat(pasta, nomedoc);
strcpy(fullpath, pasta);
}
}
int main() //where i write in the bin file
{
//GETTING REGISTRY DATA
fflush(stdin); //para ir so buscar os dados
printf("\nName pacient: ");
scanf("%[^\n]", p1.nome);
printf("\nPassword do pacient %s: ", p1.nome);
scanf("%s", p1.passe);
printf("\nID pacient %s: ", p1.nome);
scanf(" %s", p1.id);
strcpy(tmp_nome, p1.nome);
strcpy(tmp_nome, strlwr(tmp_nome));
findpath();
if (access(fullpath, F_OK) == 0)
{
//IF EXISTS
printf("Este nome de utilizador já foi registado! Por favor, tente novamente!\n");
}
else
{
// IF DOESN'T EXIST
filepaciente = fopen(fullpath, "wb");
if (filepaciente == NULL)
{
printf("\nerror\n");
}
//size_t elements_written = fwrite(&p1, sizeof(Paciente), 1, filepaciente);
//PRINTING ON FILE
fprintf(filepaciente, "%s|%s|%s\n", p1.nome, p1.passe, p1.id);
fclose(filepaciente);
}
//WHERE I WANT TO PRINT ON THE CONSOLE
{
printf("Name do pacient: ");
scanf(" %[^\n]", tmpnome);
strcpy(tmp_nome, tmpnome);
strcpy(tmp_nome, strlwr(tmp_nome));//this is to get the name of the document
findpath(); //Find the path to the document
if (access(fullpath, F_OK) == 0)
{
filepaciente = fopen(fullpath, "rb"); //Open the document
Pacient pacient[100];
char line[SIZE];
int nline = 0;
fgets(line, SIZE, filepaciente);
int i = 0;
vedocumento(&i, line, pacient[nline].nome);
vedocumento(&i, line, pacient[nline].passe);
nline++;
//LOOP TO CHECK
for (i = 0; i < 1; i++)
{
if (strcmp(tmpnome, pacient[i].nome) == 0)
{ //WRITE INFO
char buf[SIZE];
if (filepaciente == NULL)
{
printf("\nERRO OPENING\n");
}else printf("\nOPEN THE FILE\n");
//IF I PUT "==1" DON'T GET IN THE WHILE
while( fread(&p1, sizeof(p1), 1, filepaciente) == 1)
{
printf("%c", p1); //NOT SURE IF THIS IS CORRECT
}
}
}
}
}
}

C program stops after traing to access string array

i'm making a program in C that let the user insert the number of names that he wants, this names is stored in a global array and then they are printed, but the program finishes before, specifically when i try to access to the global array to print the names to show them to the user. I need to have my global array as follows: char *array[10]. This problem just happens when i use the previus syntax, but when i use: char array[10][], all runs fine, what's the problem here? somebody can help me please, i have tried so many hours.
CODE:
#include <stdio.h>
#define MAX 10
int counter = 0;
char *concts[MAX];
void add_2(char *name){
printf("Se anadira un elemento en el index %d\n", counter);
concts[counter] = name;
counter++;
}
void main(){
char *name;
int ingresando = 1, i;
do{
printf("ingresa un nombre: ");
scanf("%s", &name);
add_2(name);
printf("Seguir ingresando? ");
scanf("%d", &ingresando);
}while(ingresando == 1);
printf("Terminado. contador: %d\n", counter);
for(i = 0; i < counter; i++){
char *otherName = concts[i];
printf("%s\n", otherName);
}
}
PROBLEM:
I don't really know, but the program ends before what is expected, it compiles well and does not prompt errors.
EDIT:
The program stops after print "Terminado. contador: %d\n"
Here I made some changes
#include <stdio.h>
#include <string.h>
#define MAX 10
int counter = 0;
char concts[MAX][20];
void add_2(char *name){
printf("Se anadira un elemento en el index %d\n", counter);
strcpy(concts[counter], name);
counter++;
}
int main(){
char name[20];
int ingresando = 1, i;
do{
printf("ingresa un nombre: ");
scanf("%s", name);
add_2(name);
printf("Seguir ingresando? ");
scanf("%d", &ingresando);
}while(ingresando == 1);
printf("Terminado. contador: %d\n", counter);
for(i = 0; i < counter; i++){
char *name = concts[i];
printf("%s\n", name);
}
return 0;
}
Now run it.
#include <stdio.h>
#include <string.h>
void add_2(char *name); //defining prototype of function
#define MAX 10
int counter = 0;
char concts[MAX][20];
void add_2(char *name){
printf("Se anadira un elemento en el index %d\n", counter);
strcpy(concts[counter], name);
counter++;
}
main(){
char name[20];
int ingresando = 1, i;
do{printf("ingresa un nombre: ");
scanf("%s", &name);
add_2(name);
printf("Seguir ingresando? ");
scanf("%d", &ingresando);
}while(ingresando == 1);
printf("Terminado. contador: %d\n", counter);
for(i = 0; i < counter; i++){
char *name = concts[i];
printf("%s\n", name);
}
}
The above answers seem right but the other way is using malloc.
first you must include <stdlib.h> and then edit line 12(char *name) like this
char *name=malloc(21);
*for old version of gcc you must cast the output of malloc to char *

Why is a Printf in a Function Preventing a Variable in a Struct Array from going Corrupt in Another Function?

I have got a function to read a file and attribute to a struct array multiple ints and strings, my fscanf format string looks like this: "%d.%d.%d.%d %d %60c%60c%d %8c".
And everything is OK if while I scan it and if I use a printf, but if I don't then the 2 last strings become corrupted at the end.
Since the file is gigantic and that is not the purpose of the function, I would like to take that printf out.
typedef struct
{
int nacional;
int regional;
int distrital;
int municipal;
}id_geo;
typedef struct
{
id_geo id_geo;
long int cartao_cid;
char nome_dono[61];
char morada[61];
int num_porta;
char codigo_postal[9];
}prop_id_dono;
prop_id_dono *ler_ficheiro(char *file_name, int num_linha) {
prop_id_dono *info_geral;
long int cartao_cid;
char nome_ficheiro;
char nome_dono[60];
char morada[60];
int num_porta;
char codigo_postal[8];
int nacional;
int regional;
int distrital;
int municipal;
int i = 0;
FILE *fp;
fp = fopen(file_name, "r");
if (fp == NULL)
printf("Peço desculpa, mas não foi possível abrir o ficheiro.");
info_geral = (prop_id_dono *)malloc(sizeof(prop_id_dono) * num_linhas);
while (fscanf(fp, "%d.%d.%d.%d %ld %60c%60c%d %8c\n",
&nacional, &regional, &distrital, &municipal,
&cartao_cid, nome_dono, morada, &num_porta, codigo_postal) != EOF) {
// Faz o scan ao ficheiro através de variáveis temporais, sendo que só
// depois é que atribui valores ao vetor que contém a informação geral
info_geral[i].id_geo.nacional = nacional;
info_geral[i].id_geo.regional = regional;
info_geral[i].id_geo.distrital = distrital;
info_geral[i].id_geo.municipal = municipal;
info_geral[i].cartao_cid = cartao_cid;
strcpy(info_geral[i].nome_dono, nome_dono + '\0');
strcpy(info_geral[i].morada, morada + '\0');
info_geral[i].num_porta = num_porta;
strcpy(info_geral[i].codigo_postal, codigo_postal + '\0');
//This is the magical printf
printf("%d.%d.%d.%d %ld %s%s%d %s \n",
info_geral[i].id_geo.nacional, info_geral[i].id_geo.regional,
info_geral[i].id_geo.distrital, info_geral[i].id_geo.municipal,
info_geral[i].cartao_cid, info_geral[i].nome_dono,
info_geral[i].morada, info_geral[i].num_porta,
info_geral[i].codigo_postal);
i++;
}
fclose(fp);
return info_geral;
}
The input is something like this, but it repeats 20,000 something times in the file
1.1.1.1 1234568 Name, 60 caracters in total(including the spaces)Adress(same thing with the spaces here)House Number Postal Code
You parse input fragments with %60c into character arrays of size 60.
Assuming the conversion succeeds, these arrays will not contain proper C strings, and your attempt at concatenating a '\0' does not work in C.
Here are ways to improve your program:
you should read lines into a local array for easier error reporting in case of conversion failures, and use sscanf() fo parsing.
you should make the destination arrays one byte longer and set a null terminator at the end. The arrays in the prop_id_dono structure should be made large enough too.
you should check the return value of sscanf and report conversion failures
you should stop scanning after num_linhas lines.
you should check for memory allocation failure.
Here is a corrected version:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct {
int nacional;
int regional;
int distrital;
int municipal;
} id_geo;
typedef struct {
id_geo id_geo;
long int cartao_cid;
char nome_dono[61];
char morada[61];
int num_porta;
char codigo_postal[9];
} prop_id_dono;
prop_id_dono *ler_ficheiro(const char *file_name, int num_linha) {
char buf[256];
prop_id_dono *info_geral;
long int cartao_cid;
char nome_ficheiro;
char nome_dono[61];
char morada[61];
int num_porta;
char codigo_postal[9];
int nacional;
int regional;
int distrital;
int municipal;
int i = 0;
FILE *fp;
fp = fopen(file_name, "r");
if (fp == NULL) {
printf("Peço desculpa, mas não foi possível abrir o ficheiro.");
return NULL;
}
// use calloc to allocate an array initialized to all bits zero
info_geral = (prop_id_dono *)calloc(num_linhas, sizeof(prop_id_dono));
if (info_geral == NULL) {
fclose(fp);
return NULL;
}
while (i < num_linhas && fgets(buf, sizeof buf, fp) != NULL) {
// Faz o scan ao ficheiro através de variáveis temporais, sendo que só
// depois é que atribui valores ao vetor que contém a informação geral
if (sscanf(buf, "%d.%d.%d.%d %ld %60c%60c%d %8c",
&nacional, &regional, &distrital, &municipal,
&cartao_cid, nome_dono, morada, &num_porta, codigo_postal) != 9) {
printf("parsing error: %s", buf);
continue;
}
info_geral[i].id_geo.nacional = nacional;
info_geral[i].id_geo.regional = regional;
info_geral[i].id_geo.distrital = distrital;
info_geral[i].id_geo.municipal = municipal;
info_geral[i].cartao_cid = cartao_cid;
nome_dono[60] = '\0';
strcpy(info_geral[i].nome_dono, nome_dono);
morada[60] = '\0';
strcpy(info_geral[i].morada, morada);
info_geral[i].num_porta = num_porta;
codigo_postal[8] = '\0';
strcpy(info_geral[i].codigo_postal, codigo_postal);
i++;
}
fclose(fp);
// note that the caller does not receive the number of lines parsed.
// passing the address of a int for this purpose if a good solution.
return info_geral;
}

fprintf in File not found

I have a problem in the fprintf in the function "menor" because the data is not visible in the file selected, i dont know what is the problem, please help, i think is the reference file, but not idea.
I have a problem in the fprintf in the function "menor" because the data is not visible in the file selected, i dont know what is the problem, please help, i think is the reference file, but not idea
#include < stdio.h >
#include < stdlib.h >
#include < string.h >
typedef struct {
char * nombre;
char * editorial;
int valor;
int area;
int vendido;
}
Libro;
int conteo(FILE * _entrada);
void datos(FILE * _entrada, Libro * _trabajo, int cantidad);
void menor(FILE * _entrada, FILE * _salida, Libro * _trabajo, int cantidad);
int main() {
FILE * entrada;
char ingreso[256];
printf("Direccion del archivo de entrada \n");
scanf("%255s", ingreso);
entrada = fopen(ingreso, "r");
if (entrada == NULL) {
printf("No se pudo acceder al archivo de entrada \n");
exit(1);
}
FILE * salida;
char final[256];
printf("Direccion del archivo de salida \n");
scanf("%255s", final);
salida = fopen(final, "r");
if (salida == NULL) {
printf("No se pudo acceder al archivo de salida \n");
exit(1);
}
int cantidad = conteo(entrada);
Libro * trabajo;
trabajo = (Libro * ) malloc(sizeof(Libro) * cantidad);
datos(entrada, trabajo, cantidad);
menor(entrada, salida, trabajo, cantidad);
return 0;
}
int conteo(FILE * _entrada) {
char auxiliar1[100];
int conteo = 0;
while (!feof(_entrada)) {
fgets(auxiliar1, 100, _entrada);
conteo++;
}
rewind(_entrada);
return (conteo / 5);
}
void datos(FILE * _entrada, Libro * _trabajo, int cantidad) {
char auxiliar2[100];
char * token;
while (!feof(_entrada)) {
fgets(auxiliar2, 100, _entrada);
token = strtok(auxiliar2, ":");
token = strtok(NULL, ":");
(_trabajo - > nombre) = strdup(strtok(token, "\n"));
fgets(auxiliar2, 100, _entrada);
token = strtok(auxiliar2, ":");
token = strtok(NULL, ":");
(_trabajo - > editorial) = strdup(strtok(token, "\n"));
fgets(auxiliar2, 100, _entrada);
token = strtok(auxiliar2, ":");
(_trabajo - > valor) = atoi(strtok(NULL, ":"));
fgets(auxiliar2, 100, _entrada);
token = strtok(auxiliar2, ":");
(_trabajo - > area) = atoi(strtok(NULL, ":"));
fgets(auxiliar2, 100, _entrada);
token = strtok(auxiliar2, ":");
(_trabajo - > vendido) = atoi(strtok(NULL, ":"));
}
}
void menor(FILE * _entrada, FILE * _salida, Libro * _trabajo, int cantidad) {
int i;
int menor = 0;
int posicion = 0;
for (i = 0; i < cantidad; i++) {
if ((_trabajo - > area) == 1) {
menor = (_trabajo - > vendido);
_trabajo++;
}
}
_trabajo--;
fprintf(_salida, "%s", (_trabajo - > nombre));
}
In main, change:
salida = fopen(final, "r");
Into:
salida = fopen(final, "w");
This will truncate the file. If you wanted to update the file (meaning change the existing file's contents without deleting it), you'd want "r+".
Your description of the problem is vague. Please update your question to show us the exact (copy-and-pasted) error message.
But when I compile your program, I get:
c.c:1:26: fatal error: stdio.h : No such file or directory
#include < stdio.h >
^
compilation terminated.
Remove the spaces from the #include directives. Change this:
#include < stdio.h >
#include < stdlib.h >
#include < string.h >
to this:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
(The interpretation of the name between < and > is compiler-specific, but in this case the compiler is probably looking for a file whose name is literally " stdio.h ", including the leading and trailing spaces.)

char pointer in struct and fprintf

In the function imprimir I have a problem when I do the fprintf in a file, because _materias->nombres does not return the value, for this reason, the text not show this information, please help because i don't know what is happening, if other person know how to create the in the struct nombre in array is better, because i don't do this for reason of the strtok because he return a char pointer
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct {
char *nombre;
int creditos;
float nota;
} curso;
int conteo (FILE * _entrada);
void semestre (FILE * _entrada, curso * _materias, int *_cantidad,
int *_ganadas, int *_perdidas, float *_promedio);
void imprimir (curso * _materias, int *_cantidad, int *_ganadas,
int *_perdidas, float *_promedio);
int main (int argc, char *argv[])
{
int ganadas = 0;
int perdidas = 0;
float promedio = 0.0;
int cantidad = 0;
char archivoEntrada[256];
curso *materias;
printf ("Archivo de entrada \n");
scanf ("%255s", archivoEntrada);
FILE *entrada;
entrada = fopen (archivoEntrada, "r");
if (entrada == NULL) {
printf ("No se logro abrir el archivo de entrada\n");
exit (EXIT_FAILURE);
}
cantidad = conteo (entrada);
materias = (curso *) malloc (sizeof (curso) * cantidad);
semestre (entrada, materias, &cantidad, &ganadas, &perdidas, &promedio);
imprimir (materias, &cantidad, &ganadas, &perdidas, &promedio);
free (materias);
}
int conteo (FILE * _entrada)
{
int i = 0;
char auxiliar[40];
while (!feof (_entrada)) {
fgets (auxiliar, 40, _entrada);
i++;
}
rewind (_entrada);
return i / 3;
}
void semestre (FILE * _entrada, curso * _materias, int *_cantidad,
int *_ganadas, int *_perdidas, float *_promedio)
{
int i = 0;
int sumaCreditos = 0;
float sumaNotas = 0.0;
char auxiliar2[100];
char *token;
fgets (auxiliar2, 100, _entrada);
while (i < *_cantidad) {
fgets (auxiliar2, 100, _entrada);
token = strtok (auxiliar2, ":");
token = strtok (NULL, ":");
(_materias->nombre) = token;
fgets (auxiliar2, 100, _entrada);
token = strtok (auxiliar2, ":");
float val2 = atof (strtok (NULL, ":"));
(_materias->nota) = val2;
fgets (auxiliar2, 100, _entrada);
token = strtok (auxiliar2, ":");
float val = atoi (strtok (NULL, ":"));
(_materias->creditos) = val;
sumaCreditos = sumaCreditos + (_materias->creditos);
if ((_materias->nota) < 3.0) {
*_perdidas = (*_perdidas) + 1;
}
else {
*_ganadas = (*_ganadas) + 1;
}
sumaNotas = sumaNotas + ((_materias->nota) * (_materias->creditos));
i++;
*_materias++;
}
*_promedio = (sumaNotas / sumaCreditos);
}
void imprimir (curso * _materias, int *_cantidad, int *_ganadas,
int *_perdidas, float *_promedio)
{
char archivoSalida[256];
FILE *salida;
printf ("Archivo de salida \n");
scanf ("%255s", archivoSalida);
salida = fopen (archivoSalida, "w");
if (salida == NULL) {
printf ("No se logro abrir el archivo de salida\n");
exit (EXIT_FAILURE);
}
int i = 0;
fprintf (salida, "Archivo de Salida: \n");
fprintf (salida, "Materia\tNota\tCreditos \n");
while (i < *_cantidad) {
fprintf (salida, "%s\t%f\t%d \n", (_materias->nombre),
(_materias->nota), (_materias->creditos));
*_materias++;
i++;
}
fprintf (salida, "\nTotal de materias: %d \n", *_cantidad);
fprintf (salida, "Materias ganadas: %d \n", *_ganadas);
fprintf (salida, "Materias perdidas: %d \n", *_perdidas);
fprintf (salida, "Promedio ponderado: %f \n", *_promedio);
}

Resources