Reading strings between “;” in a .txt file in C
Reading strings between “;” in a .txt file in C
Update: thanks, everyone! You were very helpful, thanks a lot, everyone!
I have to read data from a .txt file and put them inside a B-tree. The problem is: I am having trouble to read the data from the file. Each data between the ";" must be stored in a different variable, so that I can show it when the user. The idiom is Portuguese but I hope you can understand it.
UPDATE - The code so far:
#include <stdio.h>
#include <stdlib.h>
#include <strings.h>
struct veiculos
{
int lote;
char placa[50];
char uf[10];
char motor[50];
int renavam;
char chassi[100];
int ano;
char marca[100];
char proprietario[100];
char financeira[100];
float valor;
};
typedef struct veiculos veiculos;
int main()
{
veiculos a[100];
char ch[100];
int i=0,x=0,caractere;
FILE *fp = fopen("ListadeVeiculosLeilao.txt","r");
for(i=0; i<100; i++)
{
fscanf(fp, " %[^;];", ch);
a[i].lote = atoi(ch);
fscanf(fp, " %[^;];", a[i].placa);
fscanf(fp, " %[^;];", a[i].uf);
fscanf(fp, " %[^;];", a[i].motor);
fscanf(fp, " %[^;];", ch);
a[i].renavam = atoi(ch);
fscanf(fp, " %[^;];", a[i].chassi);
fscanf(fp, " %[^;];", ch);
a[i].ano = atoi(ch);
fscanf(fp, " %[^;];", a[i].marca);
fscanf(fp, " %[^;];", a[i].proprietario);
fscanf(fp, " %[^;];", a[i].financeira);
fscanf(fp, " %[^n]n", ch);
a[i].valor = atof(ch);
for(x=0;x<strlen(a[i].marca);x++){
caractere = a[i].marca[x];
if(caractere==10)a[i].marca[x]=' ';
}
for(x=0;x<strlen(a[i].proprietario);x++){
caractere = a[i].proprietario[x];
if(caractere==10)a[i].proprietario[x]=' ';
}
for(x=0;x<strlen(a[i].financeira);x++){
caractere = a[i].financeira[x];
if(caractere==10)a[i].financeira[x]=' ';
}
}
for(i=1; i<82; i++)
{
printf("%dn",a[i].lote);
printf("%sn",a[i].placa);
printf("%sn",a[i].uf);
printf("%sn",a[i].motor);
printf("%dn",a[i].renavam);
printf("%sn",a[i].chassi);
printf("%dn",a[i].ano);
printf("%sn",a[i].marca);
printf("%sn",a[i].proprietario);
printf("%sn",a[i].financeira);
printf("%.2fnn",a[i].valor);
printf("--------------------nn");
}
fclose(fp);
return 0;
}
And here is the file:
Lote; Placa; UF; Motor; Renavam; Chassi; Ano; Marca/ Modelo;
Proprietário; Financeira; Valor
0001; LJG6509; DF; BA042893; 00300896778; 7SK182224; 1974;
VW/BRASILIA; GONCALO JOSE DE FRANCA; MARCAL DE ASSIS BRASIL; 3000.00
0002; HBR7108; DF; 9BD17206G83400203; 00954371330; 178F1011*8002263*;
2008; FIAT/SIENA FIRE FLEX; ANTONIO AUGUSTO ALVES DOS SANTOS; AYMORE
FINANCIAMENTOS;3450.00
0003; JJB0059; DF; 9BD17201B53124230; 00838026320; 178E9011*6128825*;
2004; FIAT/SIENA ELX FLEX; JOAO ALBERTO SANTOS SOBRINHO; BANCO
BRADESCO FINANCIAMENTOS S.A. ; 3450.00
0004; JGG0484; DF; 93HGD17404Z120657; 00824912748; L13A4-H113508;
2004; HONDA/FIT LX; FERNANDO EVARISTO DOS SANTOS; BANCO FINASA SA;
3030.00
0005; LJQ8142; RJ; LB8ABK60592; 00304920886; SUPRIMIDO; 1983; FORD/DEL
REY; JOSE SIQUEIRA; AYMORE LEASING; 3150.00
0006; JDQ0675; DF; 9BG5TC11UFC158987; 00293715343; 5JH20PA48199; 1985;
GM/CHEVETTE; RODRIGO DE CASTRO PAULA; AYMORE FINANCIAMENTOS; 3530.00
0007; JGQ8447; DF; 9BFZF10B678103244; 00889829691; CAJA78103244; 2006;
FORD/FIESTA; ANDREA CRISTINA CHAVES MACHADO; BANCO ITAUCARD SA;
3100.00
0008; JDS8539; GO; BA170068; 00001269992; SUPRIMIDO; 1975;
VW/BRASILIA; SAMUEL SOARES SARAFIM; BV FINANCEIRA SA CFI; 2850.00
0009; JFT5423; DF; 9BGSD19401C189366; 00751983616; CJ0039685; 2000;
GM/CORSA SUPER; ELOI NUNES DE SOUSA; PANAMERICANO; 3550.00
0010; JJD1340; DF; 9BD178237T0079169; 00663876648; 4777947; 1996;
FIAT/PALIO EL; LEANDRO DANTAS LIMA; BANCO PANAMERICANO SA; 3450.00
0011; KDR1120; DF; 9BGLK19BRRB315479; 00627287034; C20NE31014740L;
1994; GM/VECTRA GLS; MAURICIO DE LIMA SILVA; HSBC BANK BRASIL S/A BM;
2480.00
0012; KAW6325; GO; LB4DPA78820; 00112493793; SUPRIMIDO; 1975;
FORD/CORCEL; LEVINO MACHADO DA COSTA; BANCO PANAMERICANO SA; 1880.00
0013; JEQ3930; DF; BS012252; 00000121967; BH136193; 1970; VW/FUSCA
1500; SILVANA APARECIDA DA SILVA; UNIBANCO - UNIAO DE BANCOS
BRASILEIROS S.A.; 1850.00
0014; HYS6690; CE; 9BGRD48X04G134684; 00818350288; 7V0009127; 2003;
GM/CELTA 5 PORTAS; SIMONE QUINTINO MENDES DA VITORIA; BANCO GMAC;
3500.00
0015; JGA2435; DF; 9BGSC68Z01B167794; 00759527709; SUPRIMIDO; 2001;
GM/CORSA WIND; CLEUSA DO ROSARIO A SIQUEIRA; AYMORE FINANCIAMENTOS;
3100.00
0301; JHH8778; DF; 8BCLDRFJ48G521910; 00939636573; SUPRIMIDO; 2007;
I/CITROEN C4 PALLAS20GLM; CRISTIANE MONTEIRO LIMA PAIVA; CAIXA
ECONÔMICA FEDERAL; 2000.00
0302; JKJ5612; DF; 9BWAA05W5DP091431; 00500162247; CCP396671; 2012;
VW/GOL 1.0 ECOMOTION GIV; ANTONIO ALVES DE OLIVEIRA; BANCO
PANAMERICANO SA; 2500.00
0303; JHY8370; DF; 8AGCN48X0BR142232; 00253254264; U55060355; 2010;
I/CHEVROLET AGILE LTZ; N.A PIZZARIA RESTAURANTE E SERVICOS DE B; BB
ADMNISTRADORA DE CONSC SA; 3500.00
0304; LNN3808; DF; 93UMA48L714010797; 00766868516; AKL734422; 2001;
AUDI/A3 1.6; ALEX ANTONIO DA SILVA; BANCO BRADESCO SA; 2000.00
0305; LOM1229; DF; 9BMMF33E43A047599; 00797678336; 16696030636876;
2003; M.BENZ/A 160; JOSE BATISTA VIEIRA; BANCO BRADESCO SA; 2000.00
0306; JIS7553; DF; 8AP17206LB2201591; 00322387884; 310A10110162774;
2011; I/FIAT SIENA FIRE FLEX; JULIO CESAR GARCIA FILHO; BV FINANCEIRA
SA CFI; 2500.00
0307; JIC8524; DF; 9BD135316A2122152; 00146989040; X8*0463078*; 2009;
FIAT/IDEA ADVENTURE FLEX; FRANCIVALDO SOARES JACOBINA; BANCO BRADESCO
FINANCIAMENTOS S.A.; 2500.00
0308; JIC0333; DF; 9BWAA05U5AP099734; 00193353180; CCN417375; 2010;
VW/GOL 1.0; MARISA VIANA PEREIRA; BANCO ITAU CFI; 2000.00
0309; JJH5857; DF; LJ12FKR10C4271258; 00451856970; HFC4EB13DB3468084;
2011; I/JAC J3 TURIN; ABRAAO ALVES COSTA; BANCO PANAMERICANO SA;
2000.00
0310; JGN4857; DF; 9BD15822764731812; 00860177602; 146E1011*6513692*;
2005; FIAT/UNO MILLE FIRE FLEX; JORGE LUIZ SCHUMCHER; BANCO
PANAMERICANO SA; 2000.00
0311; HAB5748; DF; 9BD17103232203526; 00785472452; 5504789; 2002;
FIAT/PALIO FIRE; EDITE ROSADIAS DE SOUZA; BANCO PANAMERICANO SA;
2000.00
0312; JIV8133; DF; 93YLSR6RHBJ754270; 00325257922; D4DH760Q151276;
2011; RENAULT/LOGAN AUT 1016V; ELZI PEREIRA DA SILVA; CIA CFI RCI
BRASIL; 2500.00
0313; JIB6665; DF; 9BFZK03P19B023479; 00966756134; QFRA9023479; 2008;
153308-FORD/KA 1.6FLEX; CARLEONE SILVA COSTA; BANCO PANAMERICANO SA;
2500.00
0314; CRE3624; DF; WVWGC63B9WE454295; 00715180053; ACK086808; 1998;
I/VW PASSAT V6; PUMA LOCADORA E TURISMO LTDA ME; BANCO PANAMERICANO
SA; 2000.00
0315; JJH2574; DF; 9BWAA05W9BP046926; 00269279202; CCP225918; 2010;
VW/GOL 1.0 GIV; ELIANE NASCIMENTO DA SILVA.; BANCO ITAUCARD SA;
2000.00
0316; JHA6732; DF; 9BD17164LA5376665; 00127823654; 310A1011*8648527*;
2009; FIAT/PALIO FIRE ECONOMY; JOSE GONCALVES VIEIRA; BANCO
PANAMERICANO SA; 2000.00
0317; JHF5499; DF; 9BD15822A96191255; 00986553212; 146E1011*8501060*;
2008; FIAT/UNO MILLE ECONOMY; FRANCISCO JOSE ENIO DA SILVA; BANCO FIAT
S/A; 2000.00
0318; JIC5460; DF; 9BD110585A1527407; 00253104670; 310A3011*8723769*;
2010; FIAT/LINEA HLX 1.9 DUAL; ANDERSON JOSE BORGES; BV FINANCEIRA SA
CFI; 2500.00
0319; JKK6367; DF; 9BFZF55A0D8486830; 00538849410; SM9AD8486830; 2013;
FORD/FIESTA FLEX; ERINALDO RIBEIRO DE SOUZA; BANCO ITAUCARD SA;
2000.00
0320; DVD7522; DF; 9BWKB05Z174037965; 00898975522; BPA126696; 2006;
VW/CROSSFOX; BRAS CANDIDO BORBA; BANCO PANAMERICANO SA; 2000.00
0321; DKF6896; DF; 9BWKA05Z754019406; 00834445921; BJE025796; 2004;
VW/FOX 1.0; LUCILENE SILVA ALVES TEIXEIRA; REAL LEASING SA
ARRENDAMENTO MERCANTIL; 2000.00
0322; JJC7064; DF; LJ12EKP12E4601216; 00534448585; HFC4EB13DD3415663;
2013; I/JAC J2 1.4; CECILIO LOPES SALES; AYMORE FINANCIAMENTOS;
2500.00
0323; HPW0298; DF; 94DCMGD225J565003; 00847531090; 40704191102; 2004;
NISSAN/FRONTIER 4X2 SE; EDIMAURA PAES DE SOUSA; BANCO ITAUCARD SA;
3000.00
0325; JJJ3627; DF; LSCBB13D8CG800943; 00457564725; JL466Q4B64F019260;
2011; I/CHANGAN CHANA SC13D; FRANCINALDO MOTA; BRB CREDITO
FINANCIAMENTO E INVESTIMENTO S A; 1500.00
0326; JHR0456; DF; 8AD3DRFJ47G049541; 00926565281; 10LH4P1516969;
2006; I/PEUGEOT 307SD 20S M FL; ELMO ELIAS SANTOS NASCIMENTO; AYMORE
FINANCIAMENTOS; 2500.00
0327; JHL7740; DF; 9BWAA05U5AT154996; 00178301620; CCN377037; 2009;
VW/GOL 1.0; CARLOS ALBERTO DA CUNHA SIMOES; AYMORE FINANCIAMENTOS;
2000.00
0328; JHF6749; DF; 9BD17206G93476865; 00986960845; 178F1011*8498738*;
2008; FIAT/SIENA FIRE FLEX; GILSON FARIAS DE ANDRADE; BB LEASING SA
ARREND. MERCANTIL; 2000.00
0329; JHS9868; DF; 9BWAB05Z294059634; 00982925719; CCR036280; 2008;
VW/CROSSFOX; VIVIANE FERNANDES DA SILVA; BANCO BMC S/A - FINASA;
2500.00
0330; JGS6557; DF; 93HFA16307Z108363; 00890983810; R18A1-7Z108367;
2006; HONDA/CIVIC LXS; EURANIO SOARES SANTOS; ITAU UNIBANCO S.A.;
3000.00
0331; JIO0289; DF; LVVDB12B0BD167850; 00333102118; SQR473FAFBC01664;
2011; I/CHERY FACE 1.3; WM COMERCIO E INDUSTRIA DE VIDROS LTDA; AYMORE
FINANCIAMENTOS; 2000.00
0332; JKJ5719; DF; 9BD372110D4034781; 00539312398; 310A10111459900;
2013; FIAT/SIENA EL 1.0 FLEX; JURACY SILVA DE ALMEIDA; BANCO
PANAMERICANO SA; 2500.00
0333; JGU6486; DF; 9BD11985461031944; 00871362902; 5M*0173519*; 2005;
FIAT/DOBLO ADVENTURE; PAULO AUGUSTO DE SAO JOSE ; BANCO BRADESCO
FINANCIAMENTOS S.A.; 2000.00
0334; JJK0638; DF; 4S4WXFLU5BS029612; 00459571680; U394686; 2010;
I/SUBARU TRIBECA; ESPOBRAS CONSTRUCAO E INCORPORACAO LTDA; BRADESCO
LEASING S.A. - ARRENDAMENTO MERCANTIL; 3500.00
0335; JKJ8367; DF; 9BD15822AD6830581; 00538014156; 146E10111480325;
2013; FIAT/UNO MILLE ECONOMY; RICARDO DOS SANTOS; BANCO PANAMERICANO
SA; 2000.00
0336; JGB3807; DF; 9BD17140212078216; 00762552905; 5127709; 2001;
FIAT/PALIO EX; HELIO DA SILVA COUTINHO; BANCO ITAUCARD SA; 2000.00
0337; JDV8492; DF; 9BFZF20B558295288; 00846940000; CAJA58295288; 2005;
FORD/FIESTA SEDAN; JOAQUIM JUARES DA SILVA; BANCO PECUNIA S/A; 2000.00
0338; JHN0991; DF; 8BCLDRFJWAG528812; 00199523363; 10TWAA0037624;
2009; I/CITROEN C4 PALLAS20EAF; PAULO HENRIQUE CARVALHO DE MELO ME;
CAIXA ECONÔMICA FEDERAL; 3000.00
0339; JGZ5695; DF; 9BWCA05W66T164423; 00885894626; BNW097198; 2006;
VW/GOL 1.0; PATRICIA DE JESUS OLIVEIRA; BANCO PANAMERICANO SA; 1500.00
0340; JHN2980; DF; 9BWDB09N5AP014145; 00172998115; BPA214436; 2009;
VW/POLO SEDAN 1.6; VALDEIR ALVES NOGUEIRA; BANCO ITAUCARD SA; 2000.00
0341; JHM0175; DF; 9BD17206G73324431; 00919759297; 178F1011*7552450*;
2007; FIAT/SIENA FIRE FLEX; ELAINE MARIA FERREIRA LIRA; BANCO
PANAMERICANO SA; 2000.00
0342; JIK9533; DF; 9BWAA05U9BT161869; 00259555479; CCN661628; 2010;
VW/GOL 1.0; MARIA DOS REIS DAMASCENO DA CRUZ; BV FINANCEIRA SA CFI;
2000.00
0343; JIS7029; DF; 9BD15802AC6641487; 00363467912; 146E10110537174;
2011; FIAT/UNO MILLE ECONOMY; CLERISTON APOLINARIO DE ALCANTARA; BANCO
FIAT S/A; 2000.00
0344; JHZ8910; DF; 9BGRM69X0BG201219; 00256126208; NAC034829; 2010;
GM/PRISMA MAXX; TEMISTOCLES FERREIRA MENEZES; BV LEASING ARRENDAMENTO
MERCANTIL SA; 2000.00
0345; HCU7682; DF; 8AD3CRFN16G012508; 00889092001; 10LH2X1388201;
2005; I/PEUGEOT 307 20 FELINE; ADRIANA DOMINGOS DE OLIVEIRA; BANCO
PANAMERICANO SA; 2000.00
0347; JHB2412; DF; 9BGSA19109B248600; 00128377208; S80006976; 2009;
GM/CLASSIC LIFE; SEBASTIAO JORGE DOS SANTOS; BFB LEASING S.A.
ARRENDAMENTO MERCANTIL; 2500.00
0349; JHL9804; DF; 9BWGF07X18P023201; 00959668322; BTJ052200; 2008;
VW/KOMBI; VAGNER BARBOSA DAMASCENO; SOROCRED - CREDITO, FINANC. E
INVESTIMENTO S/A; 2500.00
0350; JIF4985; DF; 9BD17164G85232345; 00967203520; 178F1011*8169351*;
2008; FIAT/PALIO FIRE FLEX; MARCIEL MENDES DOS SANTOS; CAIXA ECONÔMICA
FEDERAL; 2500.00
0351; JGU7099; DF; 9BWCA05W46T197050; 00894987666; BNW124850; 2006;
VW/GOL 1.0 COPA; LEONARDO FERRAZ DE QUEIROZ; BANCO ITAUCARD SA;
2000.00
0352; JIB9378; DF; 9BFZF54A798415312; 00164380370; SM9A98415312; 2009;
FORD/FIESTA SEDAN FLEX; FLORA MECUPRE COELHO DA MOTA CABRAL; BANCO
PANAMERICANO SA; 2000.00
0353; JHB6982; DF; 9BD19250R93087919; 00126902100; Q7*0414787*; 2009;
FIAT/STILO SPORTING FLEX; WESLEY HOLANDA DA SILVA; AYMORE
FINANCIAMENTOS; 2000.00
0354; JHS1582; DF; 9BWAA05U3AT230876; 00200075160; CCN462504; 2010;
VW/GOL 1.0; FABIANO SILVA DOS SANTOS; BANCO BRADESCO FINANCIAMENTOS
S.A.; 2500.00
0356; JKE9912; DF; 9BWAB05U0DT078699; 00469748125; CCRN38259; 2012;
VW/GOL 1.6; PONTO COM SOLUCOES EM TEC DA INF LTDA ME; BANCO SANTANDER
BRASIL S/A; 2500.00
0357; JEM7016; DF; 9BWKA05Z544018334; 00828846650; BJE012286; 2004;
VW/FOX 1.0; JOSEANNE MARIA DA SILVA LUZIA; HSBC BANK BRASIL S/A BM;
2000.00
0358; JFU9161; DF; 9362AN6A96B016806; 00873961633; 10DBTX0000451;
2005; PEUGEOT/206 16 HOLID FX; CLEY FERREIRA DE MACEDO; BB LEASING SA
ARREND. MERCANTIL; 2000.00
0359; JHO8032; DF; 9BFZF54P4A8034381; 00198371420; QF9AA8034381; 2010;
FORD/FIESTA SEDAN1.6FLEX; MARTA APARECIDA RODRIGUES RIBEIRO; BANCO
ITAU BBA SA; 2500.00
0360; JIK3300; DF; 8AP372111C6010504; 00341484245; 310A20110222639;
2011; I/FIAT SIENA EL FLEX; SERGIO BARBOSA DANTAS; BV FINANCEIRA SA
CFI; 2000.00
0362; JHC2944; DF; 93HGD17607Z203068; 00919454690; L13A4-7Z203064;
2007; HONDA/FIT LXL; LUIS FELIPE DA COSTA SILVA; BANCO PANAMERICANO
SA; 3500.00
0363; HAN9315; DF; 9BD19240T53030666; 00838707220; 7Z*0092586*; 2004;
FIAT/STILO; MARCELO BARRAMACHER TOCANTINS; BANCO PANAMERICANO SA;
2000.00
0364; JHI3665; DF; 9BD17106G72863905; 00900855312; 178F1011*7280491*;
2006; FIAT/PALIO FIRE FLEX; ILDEMAR DA COSTA; BANCO PANAMERICANO SA;
1500.00
0365; JIB7544; DF; 9BWAA05Z494144655; 00148089003; CCN151413; 2009;
VW/FOX 1.0; ADEILDE DE SOUZA CHAVES; BANCO BRADESCO FINANCIAMENTOS
S.A.; 2500.00
0366; JKN0585; DF; 9BFZF55A4E8041900; 00569311802; SM9AE8041900; 2013;
FORD/FIESTA FLEX; FERNANDO DOS SANTOS; BANCO PANAMERICANO SA; 2000.00
0367; KGZ8961; DF; 9BFZF55P9A8027280; 00197091482; QF9AA8027280; 2010;
FORD/FIESTA 1.6 FLEX; MANOEL DOS REIS VIANA DE SOUSA; BANCO SANTANDER
BRASIL S/A; 2000.00
0368; JHZ6417; DF; 9BD17164LA5464946; 00154185191; 310A1011*8923435*;
2009; FIAT/PALIO FIRE ECONOMY; AHISTIR MARA SILVA; BV FINANCEIRA SA
CFI; 2000.00
0369; JHY3246; DF; 9BWCA05W38T142835; 00945920482; BNW380552; 2007;
VW/GOL 1.0; JONATHAN BARBOSA SILVA; BV FINANCEIRA SA CFI; 3000.00
0370; JGR0169; DF; 8AFDZZFHA4J327237; 00813798485; 4J327237; 2003;
I/FORD FOCUS 1.6L HA;NICHOLLAS MARQUES DE QUEIROZ GONÇALVES; BANCO
ITAUCARD SA; 1500.00
0371; JHX2575; DF; 9BWCA05W28P074052; 00943512786; BNW362784; 2007;
VW/GOL 1.0; GERSON DA SILVA FERREIRA; BANCO PANAMERICANO SA; 3000.00
The data is fine — though it should be presented with one line for each line in the input file. Where's your code, though? What have you tried, and what happened? You're need a structure type to hold the elements for each line; you're need a dynamically allocated array of your structure type to hold the data as it arrives; you need to read lines; you need to parse those lines, making sure you copy data when necessary; you need to save the information and display it, etc.
– Jonathan Leffler
Jun 30 at 0:11
"I am having trouble to read the data from the file" and what trouble would that be?
– Ring Ø
Jun 30 at 0:15
It seems to work well. But it considers the "n" of some strings, so it prints it. ex: 314 CRE3624 DF WVWGC63B9WE454295 715180053 ACK086808 1998 I/VW PASSAT V6 PUMA LOCADORA E TURISMO LTDA ME BANCO PANAMERICANO SA 2000.00 Notice that the "SA" was printed in another line, but it was supposed to be printed in the same line, since it is part of the same string. How can i handle that?
– Thiago Ribeiro
Jun 30 at 1:03
I hope this data is test data, so those names aren't real!
– alk
Jun 30 at 10:03
3 Answers
3
Depending on the actual format of your data file, you may be making things harder (and more error prone) than things need to be. As @JonathanLeffler notes in his comment, your data file should (ideally) contain one account record per-line. Not as you have shown with line-breaks scattered throughout each record.
If you are faced with a file with scattered line-break (as well as whitespace surrounding your delimiters), you may be better served to reformat your data file.
While you have a number of answers discussing the field oriented input to handle scattered line-breaks, a common approach when each record is a single-line is to read the data file one-line at a time (a line oriented) approach. This allows you to read with either fgets
(or POSIX getline
).
fgets
getline
By reading a line at a time, you have to benefit of separately validating (1) the read of the line itself; and (2) the parse of your needed information from each line.
The approach is fairly simple. Read a line at a time into either a sufficiently sized fixed buffer, or let getline
dynamically allocate as much storage a is required. After reading each line into a buffer, you can parse the buffer into individual fields by (1) using a formatted parse with sscanf
; (2) using strtok
to access each field (empty fields are not allowed); (3) using strsep
similar to strtok
, but accounts for empty fields; and (4) you can always walk a pair of pointers down the buffer checking each character and handling the parse as required.
getline
sscanf
strtok
strsep
strtok
Here, since you are attempting with fscanf
, we will use sscanf
which is a close corollary. (you can both read and parse with a single call to fscanf
, but you lose the benefit of the separate validation of the read and parse -- this is up to you)
fscanf
sscanf
fscanf
When using sscanf
, you are parsing the information in the same manner as you were with fscanf
, except you are reading the information from your filled buffer, instead of from the file. Your choice of format string is critical, and should protect any array bounds you have by using the field width modifier.
sscanf
fscanf
(note: the whitespace surrounding each delimiter was odd and unclear whether this was intended or accidental. The read below assumes none, but will consume any leading whitespace while leaving it to you to trim any trailing whitespace between then end of the field and delimiter for character fields)
With that in mind, you could read and parse the information from your data file similar to the following:
char buf[MAXC] = ""; /* buffer to read line at a time */
size_t n = 0; /* line index */
/* use filename provided as 1st argument (stdin by default) */
FILE *fp = argc > 1 ? fopen (argv[1], "r") : stdin;
...
if (!fgets (buf, MAXC, fp)) { /* read/discard heading row */
fprintf (stderr, "error: failed to read 1st line.n");
return 1;
}
...
n++;
while (fgets (buf, MAXC, fp)) { /* read each line into buf */
veiculos tmp = { .lote = 0 }; /* temp struct to fill */
/* validate the return of sscanf to validate parse/conversions */
if (sscanf (buf, "%d; %49[^;]; %9[^;]; %49[^;]; %d; %99[^;]; %d; "
"%99[^;]; %99[^;]; %99[^;]; %f",
&tmp.lote, tmp.placa, tmp.uf, tmp.motor, &tmp.renavam,
tmp.chassi, &tmp.ano, tmp.marca, tmp.proprietario,
tmp.financeira, &tmp.valor) != 11) {
/* if less than 11 returned, failed read, handle error */
fprintf (stderr, "read-error: line %zu.n", n);
continue; /* get next line */
}
/* ==> add tmp to binary tree here <==
* (note: you will need to trim trailing whitespace from strings)
*/
printf ("line[%3zu]: %5d %10s %4s %24s ...n",
n, tmp.lote, tmp.placa, tmp.uf, tmp.motor);
n++;
}
Don't use magic numbers in your code. (e.g. [10] [50] [100]
, etc...) Instead, if you need constants for your code #define
them or use a global enum
to define them.
[10] [50] [100]
#define
enum
Always validate all inputs (especially user-input). A failure to check the return of your input functions is an invitation for Undefined Behavior and infinite loops as you have no way of detecting an input or matching failure or detecting EOF
. If you fail to detect any of those conditions and blindly continue to attempt to read from a stream in an error-state you will invoke Undefined Behavior.
EOF
Putting those pieces together, you could approach the read of your account information similar to the following (adding that information to your btree is left to you), e.g.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/* don't put 'magic numbers' in your code, if you need constants,
* #define them, or use an enum as below:
*/
enum { MAXU = 10, MAXP = 50, MAXI = 100, MAXC = 1024 };
typedef struct { /* typedef for struct */
int lote;
char placa[MAXP];
char uf[MAXU];
char motor[MAXP];
int renavam;
char chassi[MAXI];
int ano;
char marca[MAXI];
char proprietario[MAXI];
char financeira[MAXI];
float valor;
} veiculos;
int main (int argc, char **argv) {
char buf[MAXC] = ""; /* buffer to read line at a time */
size_t n = 0; /* line index */
/* use filename provided as 1st argument (stdin by default) */
FILE *fp = argc > 1 ? fopen (argv[1], "r") : stdin;
if (!fp) { /* validate file open for reading */
perror ("file open failed");
return 1;
}
if (!fgets (buf, MAXC, fp)) { /* read/discard heading row */
fprintf (stderr, "error: failed to read 1st line.n");
return 1;
}
printf ("header line strippednn");
n++;
while (fgets (buf, MAXC, fp)) { /* read each line into buf */
veiculos tmp = { .lote = 0 }; /* temp struct to fill */
/* validate the return of sscanf to validate parse/conversions */
if (sscanf (buf, "%d; %49[^;]; %9[^;]; %49[^;]; %d; %99[^;]; %d; "
"%99[^;]; %99[^;]; %99[^;]; %f",
&tmp.lote, tmp.placa, tmp.uf, tmp.motor, &tmp.renavam,
tmp.chassi, &tmp.ano, tmp.marca, tmp.proprietario,
tmp.financeira, &tmp.valor) != 11) {
/* if less than 11 returned, failed read, handle error */
fprintf (stderr, "read-error: line %zu.n", n);
continue; /* get next line */
}
/* ==> add tmp to binary tree here <==
* (note: you will need to trim trailing whitespace from strings)
*/
printf ("line[%3zu]: %5d %10s %4s %24s ...n",
n, tmp.lote, tmp.placa, tmp.uf, tmp.motor);
n++;
}
if (fp != stdin) fclose (fp); /* close file if not stdin */
return 0;
}
(note: the storage of strings in fixed length arrays (e.g. placa, chassis
, etc. is highly space-inefficient as you will be storing a majority of whitespace (or indeterminate values) in a number of cases. A better approach would be to allocate storage for each string based on the strlen
of each field (+1
for the nul-terminatng character)
placa, chassis
strlen
+1
Example Use/Output
Running the foregoing on your input file with 1-complete record per line would yield the following:
$ ./bin/readaccts dat/accounts.txt
header line stripped
line[ 1]: 1 LJG6509 DF BA042893 ...
line[ 2]: 2 HBR7108 DF 9BD17206G83400203 ...
line[ 3]: 3 JJB0059 DF 9BD17201B53124230 ...
line[ 4]: 4 JGG0484 DF 93HGD17404Z120657 ...
line[ 5]: 5 LJQ8142 RJ LB8ABK60592 ...
line[ 6]: 6 JDQ0675 DF 9BG5TC11UFC158987 ...
line[ 7]: 7 JGQ8447 DF 9BFZF10B678103244 ...
line[ 8]: 8 JDS8539 GO BA170068 ...
line[ 9]: 9 JFT5423 DF 9BGSD19401C189366 ...
line[ 10]: 10 JJD1340 DF 9BD178237T0079169 ...
line[ 11]: 11 KDR1120 DF 9BGLK19BRRB315479 ...
line[ 12]: 12 KAW6325 GO LB4DPA78820 ...
line[ 13]: 13 JEQ3930 DF BS012252 ...
line[ 14]: 14 HYS6690 CE 9BGRD48X04G134684 ...
line[ 15]: 15 JGA2435 DF 9BGSC68Z01B167794 ...
line[ 16]: 301 JHH8778 DF 8BCLDRFJ48G521910 ...
line[ 17]: 302 JKJ5612 DF 9BWAA05W5DP091431 ...
line[ 18]: 303 JHY8370 DF 8AGCN48X0BR142232 ...
line[ 19]: 304 LNN3808 DF 93UMA48L714010797 ...
line[ 20]: 305 LOM1229 DF 9BMMF33E43A047599 ...
<snip next 50 lines>
line[ 71]: 360 JIK3300 DF 8AP372111C6010504 ...
line[ 72]: 362 JHC2944 DF 93HGD17607Z203068 ...
line[ 73]: 363 HAN9315 DF 9BD19240T53030666 ...
line[ 74]: 364 JHI3665 DF 9BD17106G72863905 ...
line[ 75]: 365 JIB7544 DF 9BWAA05Z494144655 ...
line[ 76]: 366 JKN0585 DF 9BFZF55A4E8041900 ...
line[ 77]: 367 KGZ8961 DF 9BFZF55P9A8027280 ...
line[ 78]: 368 JHZ6417 DF 9BD17164LA5464946 ...
line[ 79]: 369 JHY3246 DF 9BWCA05W38T142835 ...
line[ 80]: 370 JGR0169 DF 8AFDZZFHA4J327237 ...
line[ 81]: 371 JHX2575 DF 9BWCA05W28P074052 ...
Look things over and let me know if you have further questions.
"Don't use magic numbers in your code" is good advice - yet
"%d; %49[^;]; %9[^;]; %49[^;]; %d; %99[^;]; %d; " "%99[^;]; %99[^;]; %99[^;]; %f"
will be tricky to implement it with its present 7 magic numbers.– chux
Jun 30 at 4:49
"%d; %49[^;]; %9[^;]; %49[^;]; %d; %99[^;]; %d; " "%99[^;]; %99[^;]; %99[^;]; %f"
@chux Well, we both know there is no way to specify field-width modifiers with a named constant or variable -- so, point made well made. Yes there are some instances where you can do nothing else but include hard-coded numbers -- the key is knowing the distinction between what is a magic number and what is a required value.
– David C. Rankin
Jun 30 at 5:26
Thank you for you help! I appreciate your effort and it was very helpful to me!
– Thiago Ribeiro
2 days ago
You can use the strchr
function to search for an instance of the ;
character, replace it with the null character (), then use
strcpy
to copy the "string." strchr
returns a pointer to the character found, so you can increment that pointer to get the next part of the string to search, and repeat until no results are found.
strchr
;
strcpy
strchr
Rough idea of the code:
// char * str points to your search string
char * loc = NULL;
while (loc = strchr(str, ';')) {
*loc = '';
// now str points to a string that looks like "........",
// so strcpy will copy up to the null character
// dest should clearly be a different location one each iteration.
// you'll probably use malloc to allocate new space each time.
strcpy(dest, str);
str = loc + 1; // or loc + 2 if there's always a space after the ';'
}
After this loop, you'll have the last part of the string left to copy, so you can just do it manually:
strcpy(dest, str); // again, you should update dest in each iteration as well.
Maybe this is what you need.
/* Split string
@content origin string content
@delim delimiter for splitting
@psize pointer pointing at the variable to store token size
@return tokens after splitting
*/
const char **split(char *content, const char *delim, int *psize)
{
char *token;
const char **tokens;
int capacity;
int size = 0;
token = strtok(content, delim);
if (!token)
{
return NULL;
}
// Initialize tokens
tokens = malloc(sizeof(char *) * 64);
if (!tokens)
{
exit(-1);
}
capacity = 64;
tokens[size++] = token;
while ((token = strtok(NULL, delim)))
{
if (size >= capacity)
{
tokens = realloc(tokens, sizeof(char *) * capacity * 2);
if (!tokens)
{
exit(-1);
}
capacity *= 2;
}
tokens[size++] = token;
}
*psize = size;
return tokens;
}
Note: The return value tokens
of this function is allocated by malloc()
, which needs to be freed.
tokens
malloc()
By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.
What have you tried so far?
– klutt
Jun 30 at 0:11