I have the following code:
typedef struct RegDados{
char removido; // deve ser inicializado com '-'
int encadeamento; // deve ser inicializado com -1
int nroInscricao; // nao aceita valores repetidos nem nulos
double nota;
char data[10]; // checar tipo
char *cidade;
int sizecid;
char tagCampo4;
char *nomeEscola;
int sizesch;
char tagCampo5;
}RegDados;
char * strtokEvenEmpty(char * s, const char * seps){
static char * p = NULL;
if (s != NULL)
p = s;
else if (p == NULL)
return NULL;
else
s = p;
while (*p) {
if (strchr(seps, *p)) {
*p++ = 0;
return s;
}
p += 1;
}
return (*s) ? s : NULL;
}
const char * getfield(char* line, int num){
const char * tok;
for (tok = strtokEvenEmpty(line, ","); tok; tok = strtokEvenEmpty(NULL, ",\n")){
if (!--num)
return tok;
}
return NULL;
}
int main(){
FILE * stream = fopen("trabalho1.csv.csv", "r+");
FILE * ArqBin = fopen("test.bin","wb");
RegDados regdados[5000];
RegCab regcab;
int i = 0;
if(ArqBin == NULL) printf("Error");
if (stream != NULL) {
char line[1024];
while (fgets(line, 1024, stream)) {
regdados[i].nroInscricao = atoi(getfield(line, 1));
fwrite(®dados[i].nroInscricao, sizeof(int), 1, ArqBin);
regdados[i].nota = atof(getfield(line, 2));
fwrite(®dados[i].nota, sizeof(double), 1, ArqBin);
strcpy(regdados[i].data, getfield(line, 3));
fwrite(regdados[i].data, sizeof(char), 100, ArqBin);
regdados[i].cidade = getfield(line, 4);
fwrite(regdados[i].cidade, sizeof(char), 100, ArqBin);
regdados[i].nomeEscola = getfield(line, 5);
fwrite(regdados[i].nomeEscola, sizeof(char), 100, ArqBin);
i++;
}
fclose(stream);
fclose(ArqBin);
}
else{
printf("Error");
}
}
It already parses the fields of my file, but I can't write them on a binary file, because when I try to write, I get a lot of null fields, which doesn't happen when I don't write.
My CSV file looks like:
nroInscricao,nota,data,cidade,nomeEscola
13893,353.9,26/11/2016,,FRANCISCO RIBEIRO CARRIL
13595,472.2,,Salgueiro,ALFREDO GUEDES
13894,614.4,28/11/2016,Recife,JOAO DE MOURA GUIMARAES
13880,403.2,29/11/2016,Fortaleza,ANTONIO DIAS PASCHOAL PR
13881,373.7,,Sao Jose da Tapera,DONIZETTI TAVARES DE LIM
13882,394.8,01/12/2016,Sao Bernardo do Cam,JUSTINO GOMES DE CASTRO
How can I write the each field on a binary file?
when I try to write, I get a lot of null fields, which doesn't happen when I don't write.
this is normal, the internal representation of number can contains several 0, for instance doing :
fwrite(®dados[i].nroInscricao, sizeof(int), 1, ArqBin);
if regdados[i].nroInscricao values 7 and your int are on 32bits that will write 3 times 0 and 1 time 7 (the order depends if you are on little/big endian).
Of course it is the same with the strings you write with a fixed size, so the padding characters can have any value including 0 (there are not initialized)
Your way to extract the fields with getfield is expensive because you extract the first token, then to get the second you have to bypass the first token, then to get the third you have to bypass the 2 first tokens etc.
A better way is to do getfield(line, 1) then getfield(NULL, 1) to get the second token, then to do getfield(NULL, 1) to get the third etc, so in fact the second argument is always 1 and you can remove its management
You try to open trabalho1.csv.csv, probably you want to open trabalho1.csv
In
if(ArqBin == NULL) printf("Error");
if (stream != NULL) {
it is not enough to print error, you must not continue, can be
if(ArqBin == NULL)
printf("Error");
else if (stream != NULL) {
or better replace
FILE * stream = fopen("trabalho1.csv.csv", "r+");
FILE * ArqBin = fopen("test.bin","wb");
...
if(ArqBin == NULL) printf("Error");
if (stream != NULL) {
...
}
else{
printf("Error");
}
by something like
FILE * stream = fopen("trabalho1.csv.csv", "r+");
if (stream == NULL) {
fprintf(stderr, "cannot open input file rabalho1.csv.csv");
return -1;
}
FILE * ArqBin = fopen("test.bin","wb");
if (ArqBin == NULL) {
fprintf(stderr, "cannot open output file test.bin");
fclose(stream); /* really useful if you do not stop execution */
return -1;
}
...
I'm creating a program in C. I want this program to invert a txt file, avec geojson coordinates.
The program is running good, but when the txt file is too long, the programe crash....!
I think there is a problem with the memory but i don't find how to solucionate it.
Thanks in advance !
There my main.c :
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "pile.h"
#include "pile_function.h"
#define TAILLE_MAX 5000 // Tableau de taille 1000
int main(int argc, char *argv[]) {
FILE* fichier = NULL;
FILE* fichier_creer = NULL;
char chaine[TAILLE_MAX] = ""; // Chaîne vide de taille TAILLE_MAX
char concat[TAILLE_MAX] = "";
char final[TAILLE_MAX] = "";
const char s[2] = "]";
char *token = malloc(sizeof(*token));
Pile *tas;
if ((tas = (Pile *) malloc (sizeof (Pile))) == NULL)
return -1;
initialisation (tas);
fichier = fopen(argv[1], "r+");
if (fichier != NULL)
{
// On peut lire et écrire dans le fichier
printf("Ouverture du fichier\n");
fgets(chaine, TAILLE_MAX, fichier);
fichier_creer = fopen("Fichier_Inverser.txt", "a+");
if (fichier != NULL)
{
printf("Ouverture du fichier_creer\n");
/* get the first token */
token = strtok(chaine, s);
/* walk through other tokens */
while( token != NULL )
{
strcpy(concat, token);
strcat(concat, s);
empiler(tas, concat);
token = strtok(NULL, s);
memset (concat, 0, sizeof (concat));
}
while( tas->taille != 0 )
{
strcpy (final, depiler(tas));
fputs(final, fichier_creer);
}
printf("\nFichier mise a jour\n");
fclose(fichier_creer);
printf("\nFermeture du fichier du fichier_creer\n");
}
else
{
printf("Impossible d'ouvrir le fichier_creer");
}
fclose(fichier);
printf("Fermeture du fichier du fichier\n");
}
else
{
printf("Impossible d'ouvrir le fichier");
}
return EXIT_SUCCESS;
}
There is my pile.h :
typedef struct ElementListe{
char *donnee;
struct ElementListe *suivant;
} Element;
typedef struct ListeRepere{
Element *debut;
int taille;
} Pile;
/* initialisation */
void initialisation (Pile *tas);
/* EMPILER*/
int empiler (Pile *tas, char *donnee);
/* DEPILER*/
char *depiler (Pile *tas);
/* Affichage de élément en haut de la pile (LastInFirstOut) */
#define pile_donnee(tas) tas->debut->donnee
/* Affiche la pile */
void affiche (Pile *tas);
There is my pile_function.h:
void initialisation (Pile * tas){
tas->debut = NULL;
tas->taille = 0;
}
int empiler (Pile * tas, char *donnee){
Element *nouveau_element;
if ((nouveau_element = (Element *) malloc (sizeof (Element))) == NULL)
return -1;
if ((nouveau_element->donnee = (char *) malloc (50 * sizeof (char))) == NULL)
return -1;
strcpy (nouveau_element->donnee, donnee);
nouveau_element->suivant = tas->debut;
tas->debut = nouveau_element;
tas->taille++;
}
char *depiler(Pile *pile)
{
if (pile == NULL)
{
exit(EXIT_FAILURE);
}
char *chaine = malloc(sizeof(*chaine));
Element *elementDepile = pile->debut;
if (pile != NULL && pile->debut != NULL)
{
strcpy (chaine, elementDepile->donnee);
pile->debut = elementDepile->suivant;
free(elementDepile);
}
pile->taille--;
return chaine;
}
void affiche (Pile * tas){
Element *courant;
int i;
courant = tas->debut;
for(i=0;i<tas->taille;++i){
printf("%s\n", courant->donnee);
courant = courant->suivant;
}
}
There is for exemple a list of coordinate, it doesn't work :
[2.2528324,49.0413749],[2.2530099,49.0409694],[2.2529714,49.0409477],[2.2529531,49.040845],[2.2528231,49.040697],[2.2525572,49.0405152],[2.2521051,49.0402405],[2.2518017,49.0400133],[2.2515308,49.0397237],[2.2514333,49.0395455],[2.2514103,49.0394521],[2.2514134,49.0393256],[2.25172,49.0383752],[2.2517745,49.0380228],[2.2518929,49.0377766],[2.2520333,49.0375694],[2.2522566,49.0373093],[2.2523922,49.0372076],[2.2525084,49.036936],[2.2528797,49.0363597],[2.2529077,49.0362346],[2.2528555,49.0359416],[2.2527984,49.0358494],[2.2527631,49.0358471],[2.2494004,49.0368099],[2.2445056,49.0382113],[2.2438535,49.0351289],[2.2434025,49.0334159],[2.2433668,49.0333207],[2.2424539,49.0292753],[2.242455,49.0290301],[2.2425994,49.0285152],[2.2425996,49.0284322],[2.241938,49.0267597],[2.241008,49.0254301],[2.2405995,49.0251103],[2.2405338,49.0250148],[2.2404128,49.0247205],[2.2403438,49.0244781],[2.2403436,49.0243775],[2.239998,49.0235028],[2.2399302,49.0233991],[2.2398091,49.0233274],[2.2397032,49.0232808],[2.2395594,49.0232176],[2.2394263,49.0231172],[2.2393327,49.0230396],[2.2392098,49.0229535],[2.2387176,49.0225323],[2.238216,49.0221354],[2.237813,49.0218217],[2.2375089,49.0214585],[2.2373633,49.0215158],[2.2371741,49.0213435],[2.2364466,49.0204618],[2.2363631,49.0202973],[2.2359734,49.0197239],[2.2358766,49.0195764],[2.23573,49.0192646],[2.2356873,49.0192694],[2.235498,49.0189371],[2.2354933,49.0189123],[2.2352065,49.0184121],[2.23519,49.0184137],[2.2350145,49.0184304],[2.2348705,49.0184441],[2.2342795,49.0177464],[2.2340851,49.017802],[2.2338829,49.0175392],[2.2338473,49.017546],[2.2331775,49.0168764],[2.2327003,49.0163514],[2.2326684,49.0163499],[2.231627,49.0154023],[2.2312705,49.0150763],[2.2311292,49.0149744],[2.2302659,49.0144945],[2.2301856,49.0144539]
But with the same list but short , it works :
[2.2528324,49.0413749],[2.2530099,49.0409694],[2.2529714,49.0409477],[2.2529531,49.040845],[2.2528231,49.040697],[2.2525572,49.0405152],[2.2521051,49.0402405],[2.2518017,49.0400133],[2.2515308,49.0397237],[2.2514333,49.0395455],[2.2514103,49.0394521],[2.2514134,49.0393256],[2.25172,49.0383752],[2.2517745,49.0380228],[2.2518929,49.0377766],[2.2520333,49.0375694],[2.2522566,49.0373093],[2.2523922,49.0372076],[2.2525084,49.036936],[2.2528797,49.0363597]
I'm a begineer..so maybe i'm not doing it good.
Thanks you for your reply.
Jordan
char *chaine = malloc(sizeof(*chaine)); => Here sizeof(*chaine) == 1 because type is char * so pointed type is char and sizeof(char) == 1. You probably want char *chaine = (char *) malloc(strlen(elementDepile->donnee) * sizeof(char));
– Fefux
I'm trying to read a file like this:
nInp=20
nOut=1
NLaye=3
hid=30
er=0.001
epo=100
epoRep=100
pscpa=0
tip=Aggr
net=emi
numPrec=0.25
prec=NH3;NOX;PM10;SO2;VOC
rag=4
and I must read only the values after the =, and with the prec's values, I must separate every single value (delimited with ;) with a new line and then I write those into a new file like:
NH3
NOX
PM10
SO2
VOC
To read after equals symbolt there is no problems, but I can't to separate price.
This is my function:
void settaggiRete(char values[20][50]){
char line[50];
int i = 0, j = 0;
char str[10][20];
FILE *conf = fopen("conf.txt", "r");
if(conf == NULL){
printf("Impossibile apripre il file conf\n");
exit(EXIT_FAILURE);
}
//Ciclo sulle linee del file di configurazione
while(fgets(line, sizeof(line), configRete) != NULL){
// Leggo i valori contenuti dopo =
if(i==10){
char * str = values[10];
sscanf(line, "%*[^=]=%s", values[i]);
while ((token = strsep(line, ";")) != NULL){
str[j] = token;
j++;
}
}else{
sscanf(line, "%*[^=]=%s", values[i]);
}
i++;
}
fclose(configRete);
}
So How can I separate that values??
You can't assign to the array like this
str[j] = token;
try
strcpy(str[j], token);
althought that is dangerous to do, so you could
size_t length = strlen(token);
if (length >= sizeof(str[j]))
length = sizeof(str[j]) - 1;
memcpy(str[j], token, length);
str[j][length] = '\0';
notice that you are writing safe code at the expense of trimming the token, so a better approach is to use dynamic allocation.
You also, redeclared str inside the loop, so delete this line
char * str = values[10];
which is presumably wrong depending on how you declared values.
do separate at main.
like this :
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void settaggiRete(char values[20][50]){
char line[50];
int i = 0;
FILE *conf = fopen("conf.txt", "r");
if(conf == NULL){
printf("Impossibile apripre il file conf\n");
exit(EXIT_FAILURE);
}
while(fgets(line, sizeof(line), conf) != NULL){
sscanf(line, "%*[^=]=%49s", values[i++]);
}
fclose(conf);
}
int main(void){
char values[20][50] = {{0}};
char *value11[25];
int i, v11 = 0;
settaggiRete(values);
for(i=0;i<20;i++){
if(!*values[i])
break;
if(i==11){
char *token, *p = values[11];
int j = 0;
while(token = strsep(&p, ";")){
value11[v11++] = token;
}
for(j = 0; j < v11; ++j){
printf("values[11][%d]=%s\n", j, value11[j]);
}
} else {
printf("values[%d]=%s\n", i, values[i]);
}
}
return 0;
}