Find if string exist in a vector of structs - c

Good afternoon,
I'm here with a doubt that i am not able to overcome and i've tried a number of ways. I'm doing a program that among other things the user has to enter data about a product where the serial number has to be unique and of type char. What is happening is that when i type the 1st product serial number the program returns that is already a product with this serial number despite being the 1st.
Here's the code I have:
#include <stdio.h>
#include <stdlib.h>
typedef struct
{
char numeroserie;
char descricao;
float preco;
} stProduto;
/********************** Funcoes dos produtos *************************/
void inserirProduto(stProduto produtos[], int *contadorProdutos);
int procurarNumeroserie(stProduto produtos[], int contadorProdutos, char produtoAProcurar);
int main()
{
stProduto produtos[500];
int contadorProdutos=0;
inserirProduto(produtos,&contadorProdutos);
return 0;
}
void inserirProduto(stProduto produtos[], int *contadorProdutos)
{
char string1;
char posicao;
do
{
printf("Introduza o numero de serie do produto:");
scanf("%s",&string1);
posicao = procurarNumeroserie(produtos,*contadorProdutos, string1);
if (posicao == 0)
{
printf("Ja existe um produto com esse numero de serie!!!\n");
}
}
while(posicao == 0);
strcpy(produtos[*contadorProdutos].numeroserie,string1);
(*contadorProdutos)++;
}
int procurarNumeroserie(stProduto produtos[], int contadorProdutos, char produtoAProcurar)
{
int i;
char posicao;
posicao = 0;
for(i = 0 ; i < contadorProdutos ; i++)
{
if (strcmp(produtos[i].numeroserie, produtoAProcurar) == 0)
{
posicao=i;
i=contadorProdutos;
}
}
return posicao;
}
Someone help please !!I am already getting frustrated.
Thanks

You got it wrong, char is not a string type in c, it's an integer type.
A string is defined as a sequence of bytes non-nul that are followed by a nul byte.
They type char is 1 byte and hence a string can be an array of char, like the following
char string[6] = {'H', 'e', 'l', 'l', 'o', '\0'};
/* ^ nul: it's mandatory
* for this to be a
* string
*/
The code you posted above seems to be Java originally with some fixes to make it compile, but if you enable compilation warnigs the compiler will really piss you off.
You can build a string from an array like I did above, or by using a pointer of char, in that case you need to point to an array or to dynamic memory allocated using malloc().
An example would be
char *hello;
hello = malloc(6);
if (hello == NULL)
return ERROR; /* or whatever is need but do not continue */
strcpy(hello, "Hello");
/* do whatever you want with hello */
free(hello);

I have managed to put i to work:
#include <stdio.h>
#include <stdlib.h>
typedef struct
{
char numeroserie[9];
char descricao;
float preco;
} stProduto;
/********************** Funcoes dos produtos *************************/
void inserirProduto(stProduto produtos[], int *contadorProdutos);
int procurarNumeroserie(stProduto produtos[], int contadorProdutos, char produtoAProcurar[9]);
int main()
{
stProduto produtos[500];
int contadorProdutos=0;
inserirProduto(produtos,&contadorProdutos);
return 0;
}
void inserirProduto(stProduto produtos[], int *contadorProdutos)
{
char string1[9];
char posicao;
do
{
printf("Introduza o numero de serie do produto:");
scanf("%s",&string1);
posicao = procurarNumeroserie(produtos,*contadorProdutos, string1);
if (posicao == 0)
{
printf("Ja existe um produto com esse numero de serie!!!\n");
}
}
while(posicao == 0);
strcpy(produtos[*contadorProdutos].numeroserie,string1);
(*contadorProdutos)++;
}
int procurarNumeroserie(stProduto produtos[], int contadorProdutos, char produtoAProcurar[9])
{
int i;
char posicao;
posicao = 0;
for(i = 0 ; i < contadorProdutos ; i++)
{
if (strcmp(produtos[i].numeroserie, produtoAProcurar) == 0)
{
posicao=i;
i=contadorProdutos;
}
}
return posicao;
}
Putting numeroserie [8] i assure that the user just insert 8 characters ??
Thanks

Related

Change values in a struct array

Can someone explain me, please, why can't I insert values into a struct array.
Here's a piece of my code to help understand what I'm trying to accomplish.
I want to insert values inside an array which is formed by structs, whenever I try to insert values it gives me a segmentation error.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define TAM_TABELA 10
#define PRIMO 7
#define MAX_NOME 50
typedef struct {
char nome[MAX_NOME];
int telemovel;
} pessoa;
void insert(pessoa *grupo[]) {
char nome[MAX_NOME];
printf("\nInsert name:\n");
scanf("%s", nome);
int lenght = strnlen(nome, MAX_NOME);
printf("\nInsert phone:\n");
scanf("%d", &tel);
for (i = 0; i < TAM_TABELA; i++) {
if (grupo[i] == NULL) {
grupo[i]->telemovel = tel;
strcpy(grupo[i]->nome, nome);
break;
}
}
if (i == TAM_TABELA)
printf("\nO valor não pode ser inserido!\n");
}
void main() {
int opt;
pessoa p;
pessoa grupo[TAM_TABELA] = {NULL};
insert(grupo);
}
You need to pass the address of grupo to insert() function.
int main(void) { } is a valid C main() function prototype
size_t is a valid data type for lengths, iterate through arrays
Always check whether scanf() conversion was successful or not
Do not use "%s", use "%<WIDTH>s", to avoid buffer-overflow
for( i = 0; i < TAM_TABELA; i++) i was never defined
parameter of the function insert() should be pessoa ***grupo, in de-reference it later in your function like *grupo
Initialize your char [] using {}, which are stored on stack memory
for (i = 0; i < TAM_TABELA; i++) {
if (grupo[i] == NULL) {
grupo[i]->telemovel = tel;
strcpy(grupo[i]->nome, nome);
break;
}
}
Notice how you've checked that grupo[i] is NULL and then you try to access a struct member on that value that is NULL.
You possibly want to check that grupo[i] != NULL, which should make member access safe.

How to read pointer to string in my main function, error "expected argument of char* in scanf"

I am a beginner learning C.
I am trying to write two functions, one to allocate a string and the other to insert string1 in string2 from position i.
my code:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
#include <unistd.h>
//alocation
char * allouerChaine(int n)
{
char * s =(char*)malloc(n*sizeof(char *));
if(s!=NULL)
return s;
exit(-1);
}
char * strinsert(char *M, char* T ,int i)
{
char * temp=allouerChaine(strlen(M)+strlen(T));
strncpy(temp,M,i);
temp[i]='\0';
strcat(temp,T);
strcat(temp,M+i);
temp[strlen(M)+strlen(T)]='\0';
return temp;
}
int main(){
char *M;
char *T;
char*p;
int i;
printf("faites entre la chaine M: ");
scanf("%s",&M);
printf("\nfaites entre la chaine T: ");
scanf("%s",&T);
printf("faites entrer I: ");
scanf("%d",&i);
p=strinsert(M, T ,i);
printf("%s",p);
return 0;
}
when I try with static strings like :
p=strinsert("hello", "ss" ,2);
printf("%s",p);
the code works, which means I don't have a problem with my functions but I do have a problem inside the main.

trying to add a variable of a certain type inside an array of that type

So i want to create an array of a structure that i made called jogo
Structure:
typedef struct jogo
{
int ident;/*idp of a product*/
char nome[1024]; /* string that describes a team eg. Barcelona */
char *equipas[2]; /*array of strings like {"Barcelona","Madrid"}*/
int score[2]; /*array of strings like {"Barcelona","Madrid"}*/
}* jogo;
I want to create an array without a specific size to store variables of type jogo.
When i type (add) a nome:equipa1:equipa2_score1:score2 like a elclassico:barcelona:madrid:1:0,i want to create a variable of type jogo and store it inside the array sistema_jog.
if i store something and the array is full i want reallocate the size of the array in order to store more variables of type jogo.
But for some reason im always getting segmentation fault core dumped when i try to do it and i dont know why.
Program:
#include<stdlib.h>
#include<stdio.h>
#include <string.h>
#define MAX_CHARS 1024 /* max characters of a word */
#define MAX_SIZE 5
int line = 1; /* counts the number of lines of the stdin */
static int size = MAX_SIZE;
int i = 0; /*ident of the variable jogo*/
int size_until = 0;
typedef struct jogo
{
int ident;/*idp of a product*/
char nome[MAX_CHARS]; /* string that describes a team eg. Barcelona */
char *equipas[2];
int score[2];
}* jogo;
jogo *sistema_jog;
void a(char nome[],char team1[],char team2[],int score1,int score2);
int team_not_in(char team1[],char team2[]);
int nome_in(char nome[]);
void cria_jogo(jogo s,char nome[],char equipa1[],char equipa2[],int score1,int score2);
int main() {
char c; char nome_jg[MAX_CHARS]; char eq1[MAX_CHARS]; char eq2[MAX_CHARS]; int pont1; int pont2;
sistema_jog = (jogo*) calloc(MAX_SIZE,sizeof(jogo));
while ((c = getchar())!= 'x') {
switch (c)
{
case 'a':
{
scanf("%1023[^:\n]:%1023[^:\n]:1023%[^:\n]:%d:%d",nome_jg,eq1,eq2,&pont1,&pont2);
i++;
printf("nome: %s",sistema_jog[0]->nome);
//a(nome_jg,eq1,eq2,pont1,pont2);
break;
}
}
}
return 0;
}
int nome_in(char nome[])
{
int i;
for(i=0; i < size; i++)
{
if (strcmp(sistema_jog[i]->nome,nome) == 0)
return 1;
}
return 0;
}
int team_not_in(char team1[],char team2[])
{
int i;
for (i=0;i<size;i++)
{
if((strcmp(sistema_jog[i]->equipas[0],team1) != 0) || (strcmp(sistema_jog[i]->equipas[1],team2) != 0))
return 1;
}
return 0;
}
void cria_jogo(jogo s,char nome[],char equipa1[],char equipa2[],int score1,int score2)
{
strcpy(s->nome,nome);
strcpy(s->equipas[0],equipa1);
strcpy(s->equipas[1],equipa2);
s->score[0] = score1;
s->score[1] = score2;
}
void a(char nome[],char team1[],char team2[],int score1,int score2)
{
int NL = line;
if (nome_in(nome) == 1)
printf("%d Jogo existente.",NL);
else if (team_not_in(team1,team2) == 0)
{
printf("%d Equipa existente.",NL);
}
else
{
jogo novo_jogo = (jogo) calloc(sizeof(jogo),sizeof(jogo));
cria_jogo(novo_jogo,nome,team1,team2,score1,score2);
if (size_until <= MAX_SIZE)
{
sistema_jog[size_until] = novo_jogo;
size_until++;
}
else
{
sistema_jog = (jogo*) realloc(system, sizeof(jogo)*size_until);
sistema_jog[size_until] = novo_jogo;
size_until++;
}
}
}
I am not surprised that you are confused.
As Christian Gibbons, Barmar and user12986714 said jogo must be your jogostruct and not a pointer to jogo. I supposed you changed, at some stage, } jogo; to }* jogo; because of compilation errors. But, it was not the original problem and after you are confused.
Let me explain shortly, try this basic code :
#include<stdlib.h>
#include<stdio.h>
#include <string.h>
#define MAX_CHARS 1024 /* max characters of a word */
#define MAX_SIZE 5
int line = 1; /* counts the number of lines of the stdin */
static int size = MAX_SIZE;
int i = 0; /*ident of the variable jogo*/
int size_until = 0;
typedef struct jogo
{
int ident;/*idp of a product*/
char nome[MAX_CHARS]; /* string that describes a team eg. Barcelona */
char *equipas[2];
int score[2];
}* jogo;
typedef struct jogo2
{
int ident;/*idp of a product*/
char nome[MAX_CHARS]; /* string that describes a team eg. Barcelona */
char *equipas[2];
int score[2];
} jogo2;
int main() {
printf("sizeof jogo %d\n",sizeof(jogo));
printf("sizeof jogo2 %d\n",sizeof(jogo2));
return 0;
}
As you could see jogo has a pointer size and jogo2 has the size of your struct.
More, there are various problems in your code. Everything is briefly commented directly in the code. Do not hesitate to ask questions.
#include<stdlib.h>
#include<stdio.h>
#include <string.h>
#define MAX_CHARS 1024
#define MAX_SIZE 5
int line = 1;
// static int size = MAX_SIZE; // Not useful. It is the same than MAX_SIZE
// int i = 0; this variable is not really used
int size_until = 0;
typedef struct jogo
{
// int ident; Never used
char nome[MAX_CHARS];
char equipas[2][1024]; // equipas is an array of two strings. If you use char *equipas[2], you will have to alloc memory for each string
int score[2];
} jogo; // * has been removed
jogo **sistema_jog; //sistema_jog is an array of pointer to jogo struct. You allocate it after.
// you could also have an array of jogo struct but it would need more modifications in your code.
// I suppose the confusion is here. To train, you could try to do : jogo * sistema_jog and to modify what it is needed in your code.
void a(char nome[],char team1[],char team2[],int score1,int score2);
int team_not_in(char team1[],char team2[]);
int nome_in(char nome[]);
void cria_jogo(jogo* s,char nome[],char equipa1[],char equipa2[],int score1,int score2); // *: s is a pointer to jogo struct. See comment on sistema_jog declaration
int main() {
char c; char nome_jg[MAX_CHARS]; char eq1[MAX_CHARS]; char eq2[MAX_CHARS]; int pont1; int pont2;
sistema_jog = (jogo**) calloc(MAX_SIZE,sizeof(jogo*)); // Each element of sistema_jog is a pointer to a jogo struct
while ((c = getchar())!= 'x') {
switch (c)
{
case 'a':
{
scanf("%1023[^:\n]:%1023[^:\n]:%1023[^:\n]:%d:%d",nome_jg,eq1,eq2,&pont1,&pont2); // be carefull, see % and 1023 in the third field of your code
// i++; not used elsewhere
a(nome_jg,eq1,eq2,pont1,pont2);
break;
}
}
}
// Only to check
for (int i=0; i<size_until;i++)
printf ("%s:%s:%s:%d:%d\n",
sistema_jog[i]->nome,
sistema_jog[i]->equipas[0],
sistema_jog[i]->equipas[1],
sistema_jog[i]->score[0],
sistema_jog[i]->score[1]);
return 0;
}
int nome_in(char nome[])
{
int i;
for(i=0; i < size_until; i++) // size_until : You have to check only elements that exist either you have less or more elements than size (static int = MAX_SIZE)
{
if (strcmp(sistema_jog[i]->nome,nome) == 0)
return 1;
}
return 0;
}
int team_not_in(char team1[],char team2[])
{
int i;
for (i=0;i<size_until;i++) // size_until : Idem as above
{
if((strcmp(sistema_jog[i]->equipas[0],team1) != 0) || (strcmp(sistema_jog[i]->equipas[1],team2) != 0))
return 1;
}
return 0;
}
void cria_jogo(jogo* s,char nome[],char equipa1[],char equipa2[],int score1,int score2) // * : s is a pointer to jogo struct
{
strcpy(s->nome,nome);
strcpy(s->equipas[0],equipa1);
strcpy(s->equipas[1],equipa2);
s->score[0] = score1;
s->score[1] = score2;
}
void a(char nome[],char team1[],char team2[],int score1,int score2)
{
int NL = line;
if (nome_in(nome) == 1)
printf("%d Jogo existente.",NL);
/* else if (team_not_in(team1,team2) == 0)
{
printf("%d Equipa existente.",NL);
} */ // I do not understand the objective of this test. So, I commented it. But it is not the question
else
{
jogo* novo_jogo = (jogo*) malloc(sizeof(jogo));
cria_jogo(novo_jogo,nome,team1,team2,score1,score2);
if (size_until < MAX_SIZE) // = has been removed. Index of array goes from 0 to size of array-1
{
sistema_jog[size_until] = novo_jogo;
size_until++;
}
else
{
sistema_jog = (jogo**) realloc(sistema_jog, sizeof(jogo**)*(size_until+1)); // *: see comment on sistema_jog declaration, +1: array index goes from 0 to size-1
// Remark : It is not efficient to realloc one by one. It would better to realloc MAX_SIZE by MAX_SIZE. You could try to do it
sistema_jog[size_until] = novo_jogo;
size_until++;
}
}
}

C: Segmentation Fault 11 strcpy pointer Array

The code compiles with no errors, but I get a segmentation Fault Error (11), I'm guessing the problem is when I use the strcpy() function in line 82 ,something goes wrong, why im not getting any compile errors and how can I fix it, are the char array pointers well implemented?. I can not modiffy the current structs of the code.
#include "stdio.h"
#include "stdlib.h"
#include "string.h"
typedef struct
{
int n_uea;
char **nombre;
double *calificacion;
} UEA;
typedef struct
{
int n_pais;
char *nombre[50];
} PAIS;
typedef struct
{
char nombre[50];
UEA uea;
PAIS *pais;
} ALUMNO;
void AllocPais(PAIS *p, int np){
p = (PAIS*) malloc(sizeof(PAIS));
p = &p[0];
p->n_pais = np;
for (int i = 0; i < np; i++) {
p->nombre[i] = (char*) malloc(sizeof(char)*50);
}
}
void AllocUEA(UEA *u , int nu){
u->n_uea = nu;
u->nombre = (char **) malloc(sizeof(char*)*nu);
for (int i = 0; i < nu; i++) {
u->nombre[i] =(char*) malloc(sizeof(char)*50);
}
u->calificacion = (double*) malloc(sizeof(double) * nu);
}
void AllocAlumnoMemory(ALUMNO *a, int np, int nu){
AllocPais(a->pais,np);
AllocUEA(&(a->uea),nu);
}
int main(int argc, char const *argv[]) {
ALUMNO* arreglo;
int entradas;
printf("%s\n","Ingrese el numero de Entradas");
scanf("%d",&entradas);
arreglo = malloc(sizeof(ALUMNO)*entradas);
for (int i = 0; i < entradas; i++) {
char separator[10];
char name[20];
int numUea , numPaises;
printf("%s\n","Se espera separador");
scanf("%s",separator);
printf("%s\n","Ingrese el nombre");
scanf("%s",name);
strcpy(arreglo[i].nombre,name);
printf("%s\n","Ingrese el numero de UEA");
scanf("%d",&numUea);
AllocUEA(&arreglo[i].uea,numUea);
for (int a = 0; a < numUea; a++) {
char name [15];
double cal;
scanf("%s %lf", name, &cal);
strcpy(arreglo[i].uea.nombre[a],name);
arreglo[i].uea.calificacion[a] = cal;
}
printf("%s\n","Ingrese Numero de paises");
scanf("%d",&numPaises);
PAIS nuvp;
arreglo[i].pais = &nuvp;
AllocPais(arreglo[i].pais,numPaises);
for (int b = 0; b < numPaises; b++) {
char names [15];
scanf("%s",names);
strcpy(arreglo[i].pais->nombre[b],names);
}
}
return 0;
}
Please note down below points and try them:
Avoid using strcpy/strcat etc. they do not protect against buffer overruns.
Use strlcpy/strlcat instead.
When using strncpy, make sure to NULL terminate the string buffer.

How to use STRUCT with FIFO

I'm learning "FIFO" in C this is my first code trying to pass an struct by argument to FIFO function but it's not working as expected... And I can't figure why. Someone could please give me hand an explain what am I doing wrong?
I wrote my code in portuguese if it's hard to you guys understand let me know I'll translate to english.
#define TAMANHO 3
#include <stdio.h>
#include <stdlib.h>
#include <locale.h>
typedef struct
{
char Nome[20];
} pretendentes;
pretendentes // nome da estrutura
pessoas[10]; // vetor de estrutura
int main(void)
{
setlocale(LC_ALL, "");
cadastroPretendentes(pessoas);
qstore(pessoas);
}
void qstore(pretendentes *Pessoas)
{
int pfinal = 0;
int pinicial = 0;
if(pinicial == TAMANHO)
{
printf("A fila está cheia.");
return;
}
pessoas[pinicial] = Pessoas.Nome;
pinicial++;
}
void cadastroPretendentes(pretendentes *Pessoas)
{
int i;
for(i = 0; i < TAMANHO; i++)
{
printf("Insira o nome do pretendente %d: ", i+1);
scanf("%s", (*(Pessoas + i)).nome);
}
}
assume that pessoas is fifo memory.
In cadastroPretendentes(), you are getting names and store into fifo memory and in qstore(), you are writing pessoas[0] with pessoas[0].
if qstore is called another 2 times, 1st and 2nd elements in array will be replaced with pessoas[0].
In this code, qstore is not required as cadastroPretendentes() gets name and stores in pessoas (fifo memory)

Resources