Merge File without copies

D

Defected

Thanks all for help,

I have tried this code but it's don't work.

--------------------------------------------------------------------
Structure

typedef struct{
int atomic_number;
char name[MAX];
char symbol[MAX];
double weight;
}chemical_t;
-----------------------------------------------------------------------

void merge(FILE *element_1, FILE *element_2, FILE *element){

chemical_t chemical;
chemical_t chemical_1;
chemical_t chemical_2;

element_1 = fopen("text.txt", "r");
element_2 = fopen("text1.txt", "r");
element = fopen("text.bin", "wb");


fscanf(element_1,"%d%s%s%lf",&chemical_1.atomic_number,
chemical_1.name,
chemical_1.symbol,
&chemical_1.weight);
fscanf(element_2,"%d%s%s%lf",&chemical_2.atomic_number,,
chemical_2.name,
chemical_2.symbol,
&chemical_2.weight);

while(!feof(element_1)){
if(chemical_1.atomic_number < chemical_2.atomic_number){
fwrite(&chemical_1, sizeof(chimico_t), 1, element);
fscanf(element_1,"%d%s%s%lf",&chemical_1.atomic_number,
chemical_1.name,
chemical_1.symbol,
&chemical_1.weight);
}

else{
while(!feof(element_2)){
fwrite(&chemical_2, sizeof(chimico_t), 1, element);
fscanf(element_2,"%d%s%s%lf",&chemical_2.atomic_number,,
chemical_2.name,
chemical_2.symbol,
&chemical_2.weight);
}
}
}



fclose(element_1);
fclose(element_2);
fclose(element);


}
---------------------------------------------------------------------------------------------
My program must make this:

I have need to write a void function that will merge the contents of two
text file containing chemical elements sorted by atomic number and will
produce a sorted file of binary records. The funcion's parameters will
be three file pointers.
Each text file line contain for example:

11 Sodium Na 22.99
20 Calcium Ca 40.08

The function can assume that one file does not have two copies of the
same element and that the binary output files should have this same
property.
When one of the input files is exhausted, do not forget to copy the
remaining elements of the other input file to the result file.

Tanks and best regards

Sorry for my English
 
F

Flash Gordon

Defected wrote, On 25/01/07 18:52:
Thanks all for help,

I have tried this code but it's don't work.

--------------------------------------------------------------------
Structure

typedef struct{
int atomic_number;
char name[MAX];
char symbol[MAX];
double weight;
}chemical_t;
-----------------------------------------------------------------------

This obviously is not a complete compilable example since if it was you
would not have a line of dashes like the above unless it was in a
comment or a string literal, and it is neither. If you want help you
should post a minimum complete compilable program that shows the
problem. Compilable is only option when you problem is that you do not
understand why it doe snot compile.
void merge(FILE *element_1, FILE *element_2, FILE *element){

chemical_t chemical;
chemical_t chemical_1;
chemical_t chemical_2;

element_1 = fopen("text.txt", "r");
element_2 = fopen("text1.txt", "r");
element = fopen("text.bin", "wb");

What if any of these failed? Where are all the includes this requires?
fscanf(element_1,"%d%s%s%lf",&chemical_1.atomic_number,
chemical_1.name,
chemical_1.symbol,
&chemical_1.weight);

Using the %s format specifier in *scanf without a length specifier is
just asking for a buffer overflow. Never do that.

*Always* check the return value of *scanf functions so you do now know
if a problem has been encountered.
fscanf(element_2,"%d%s%s%lf",&chemical_2.atomic_number,,
chemical_2.name,
chemical_2.symbol,
&chemical_2.weight);

while(!feof(element_1)){
if(chemical_1.atomic_number < chemical_2.atomic_number){
fwrite(&chemical_1, sizeof(chimico_t), 1, element);
fscanf(element_1,"%d%s%s%lf",&chemical_1.atomic_number,
chemical_1.name,
chemical_1.symbol,
&chemical_1.weight);
}

else{

As soon as you go in to this branch you read all of element_2. This is
obviously not what you want to do.
while(!feof(element_2)){
fwrite(&chemical_2, sizeof(chimico_t), 1, element);
fscanf(element_2,"%d%s%s%lf",&chemical_2.atomic_number,,
chemical_2.name,
chemical_2.symbol,
&chemical_2.weight);
}
}
}



fclose(element_1);
fclose(element_2);
fclose(element);


}

Sorry for my English

Your English is not a problem. It is not your first language so we do
not expect perfection. The problem is not providing your complete program.
 
C

CBFalconer

user923005 said:
If ever there was an application that was screaming for a database,
this is it.

See my sig. below. Without the quotations your answer will make no
sense to many.

Having seen the original, all I can say is 'It depends'.

--
If you want to post a followup via groups.google.com, ensure
you quote enough for the article to make sense. Google is only
an interface to Usenet; it's not Usenet itself. Don't assume
your readers can, or ever will, see any previous articles.
More details at: <http://cfaj.freeshell.org/google/>
 
U

user923005

sense to many.

Having seen the original, all I can say is 'It depends'.

Here is a simple way to accomplish the desired task...

1. Import the following data into a database into a table called
Elements:
SYMBOL,NAME,ATOMICNUMBER,ATOMICMASS
Ac,Actinium,89,227
Ag,Silver,47,107.8682
Al,Aluminum,13,26.9815386
Am,Americium,95,243
Ar,Argon,18,39.948
As,Arsenic,33,74.9216
At,Astatine,85,210
Au,Gold,79,196.966569
B,Boron,5,10.811
Ba,Barium,56,137.327
Be,Beryllium,4,9.012182
Bh,Bohrium,107,264
Bi,Bismuth,83,208.9804
Bk,Berkelium,97,247
Br,Bromine,35,79.904
C,Carbon,6,12.0107
Ca,Calcium,20,40.078
Cd,Cadmium,48,112.411
Ce,Cerium,58,140.116
Cf,Californium,98,251
Cl,Chlorine,17,35.453
Cm,Curium,96,247
Co,Cobalt,27,58.933195
Cr,Chromium,24,51.9961
Cs,Cesium,55,132.9054519
Cu,Copper,29,63.546
Db,Dubnium,105,262
Ds,Darmstadtium,110,271
Dy,Dysprosium,66,162.5
Er,Erbium,68,167.259
Es,Einsteinium,99,252
Eu,Europium,63,151.964
F,Fluorine,9,18.9984032
Fe,Iron,26,55.845
Fm,Fermium,100,257
Fr,Francium,87,223
Ga,Gallium,31,69.723
Gd,Gadolinium,64,157.25
Ge,Germanium,32,72.64
H,Hydrogen,1,1.00794
He,Helium,2,4.002602
Hf,Hafnium,72,178.49
Hg,Mercury,80,200.59
Ho,Holmium,67,164.93
Hs,Hassium,108,277
I,Iodine,53,126.904
In,Indium,49,114.818
Ir,Iridium,77,192.217
K,Potassium,19,39.0983
Kr,Krypton,36,83.798
La,Lanthanum,57,138.90547
Li,Lithium,3,6.941
Lr,Lawrencium,103,262
Lu,Lutetium,71,174.967
Md,Mendelevium,101,258
Mg,Magnesium,12,24.305
Mn,Manganese,25,54.938045
Mo,Molybdenum,42,95.94
Mt,Meitnerium,109,268
N,Nitrogen,7,14.0067
Na,Sodium,11,22.98976928
Nb,Niobium,41,92.906
Nd,Neodymium,60,144.242
Ne,Neon,10,20.1797
Ni,Nickel,28,58.6934
No,Nobelium,102,259
Np,Neptunium,93,237
O,Oxygen,8,15.9994
Os,Osmium,76,190.23
P,Phosphorus,15,30.973762
Pa,Protactinium,91,231.03588
Pb,Lead,82,207.2
Pd,Palladium,46,106.42
Pm,Promethium,61,145
Po,Polonium,84,210
Pr,Praseodymium,59,140.90765
Pt,Platinum,78,195.084
Pu,Plutonium,94,244
Ra,Radium,88,226
Rb,Rubidium,37,85.4678
Re,Rhenium,75,186.207
Rf,Rutherfordium,104,261
Rg,Roentgenium,111,272
Rh,Rhodium,45,102.905
Rn,Radon,86,220
Ru,Ruthenium,44,101.07
S,Sulfur,16,32.065
Sb,Antimony,51,121.76
Sc,Scandium,21,44.955912
Se,Selenium,34,78.96
Sg,Seaborgium,106,266
Si,Silicon,14,28.0855
Sm,Samarium,62,150.36
Sn,Tin,50,118.71
Sr,Strontium,38,87.62
Ta,Tantalum,73,180.94788
Tb,Terbium,65,158.92535
Tc,Technetium,43,98
Te,Tellurium,52,127.6
Th,Thorium,90,232.03806
Ti,Titanium,22,47.867
Tl,Thallium,81,204.3833
Tm,Thulium,69,168.93421
U,Uranium,92,238.02891
Uub,Ununbium,112,285
Uuh,Ununhexium,116,292
Uuo,Ununoctium,118,294
Uup,Ununpentium,115,288
Uuq,Ununquadium,114,289
Uut,Ununtrium,113,284
V,Vanadium,23,50.9415
W,Tungsten,74,183.84
Xe,Xenon,54,131.293
Y,Yttrium,39,88.90585
Yb,Ytterbium,70,173.04
Zn,Zinc,30,65.409
Zr,Zirconium,40,91.224

2. You only need a list of the atomic numbers or the symbol. Given
either of those lists, throw an error if any of the value presented are
not already in the list.
3. Create symbol tables called symbolmerge, symbolinputone,
symbolinputtwo, and symbolerrors. They only have one field : symbol
4. Create atomic number tables called atomicnumbermerge,
atomicnumberinputone, atomicnumberinputtwo, and atomicnumbererrors.
They only have one field : atomicnumber
5. Then you would create two procedures along the lines of:

-- lazy, quick hack of stored procedures to merge two lists of chemical
elements
CREATE PROCEDURE MergeAtomicNumber AS
begin
delete from atomicnumbererrors
insert into atomicnumbererrors select atomicnumber from
atomicnumberinputone where atomicnumberinputone.atomicnumber not
in(select atomicnumber from elements)
insert into atomicnumbererrors select atomicnumber from
atomicnumberinputtwo where atomicnumberinputtwo.atomicnumber not
in(select atomicnumber from elements)
delete from atomicnumberinputone where atomicnumber in (select
atomicnumber from atomicnumbererrors)
delete from atomicnumberinputtwo where atomicnumber in (select
atomicnumber from atomicnumbererrors)
insert into atomicnumbermerge select atomicnumber from
atomicnumberinputone UNION select atomicnumber from
atomicnumberinputtwo
end

CREATE PROCEDURE MergeSymbol AS
begin
delete from symbolerrors
insert into symbolerrors select symbol from symbolinputone where
symbolinputone.symbol not in(select symbol from elements)
insert into symbolerrors select symbol from symbolinputtwo where
symbolinputtwo.symbol not in(select symbol from elements)
delete from symbolinputone where symbol in (select symbol from
symbolerrors)
delete from symbolinputtwo where symbol in (select symbol from
symbolerrors)
insert into symbolmerge select symbol from symbolinputone UNION select
symbol from symbolinputtwo
end

6. Then, if you have two lists of atomic numbers or chemical sybols,
put them into the tables and execute the relevant procedure.
7. Create a view of Elements joined against the corresponding merge
table to show the desired output.

Schema would be along the lines of:

DROP TABLE ATOMICNUMBERERRORS
go

CREATE TABLE ATOMICNUMBERERRORS (
ATOMICNUMBER smallint NOT NULL
)
go


ALTER TABLE ATOMICNUMBERERRORS
ADD PRIMARY KEY (ATOMICNUMBER)
go


DROP TABLE ATOMICNUMBERINPUTONE
go

CREATE TABLE ATOMICNUMBERINPUTONE (
ATOMICNUMBER smallint NOT NULL
)
go


ALTER TABLE ATOMICNUMBERINPUTONE
ADD PRIMARY KEY (ATOMICNUMBER)
go


DROP TABLE ATOMICNUMBERINPUTTWO
go

CREATE TABLE ATOMICNUMBERINPUTTWO (
ATOMICNUMBER smallint NOT NULL
)
go


ALTER TABLE ATOMICNUMBERINPUTTWO
ADD PRIMARY KEY (ATOMICNUMBER)
go


DROP TABLE ATOMICNUMBERMERGE
go

CREATE TABLE ATOMICNUMBERMERGE (
ATOMICNUMBER smallint NOT NULL
)
go


ALTER TABLE ATOMICNUMBERMERGE
ADD PRIMARY KEY (ATOMICNUMBER)
go


DROP TABLE SYMBOLMERGE
go

CREATE TABLE SYMBOLMERGE (
SYMBOL nvarchar(3) NOT NULL
)
go


ALTER TABLE SYMBOLMERGE
ADD PRIMARY KEY (SYMBOL)
go


DROP TABLE ELEMENTS
go

CREATE TABLE ELEMENTS (
SYMBOL nvarchar(3) NOT NULL,
NAME nvarchar(20) NULL,
ATOMICNUMBER smallint NULL,
ATOMICMASS float NULL
)
go

CREATE UNIQUE INDEX U2O8MQN3GAB75A_0 ON ELEMENTS
(
ATOMICNUMBER
)
go

CREATE UNIQUE INDEX U2O8MQN3GAB75A_2 ON ELEMENTS
(
NAME
)
go


ALTER TABLE ELEMENTS
ADD PRIMARY KEY (SYMBOL)
go


DROP TABLE SYMBOLERRORS
go

CREATE TABLE SYMBOLERRORS (
SYMBOL nvarchar(3) NOT NULL
)
go


ALTER TABLE SYMBOLERRORS
ADD PRIMARY KEY (SYMBOL)
go


DROP TABLE SYMBOLINPUTONE
go

CREATE TABLE SYMBOLINPUTONE (
SYMBOL nvarchar(3) NOT NULL
)
go


ALTER TABLE SYMBOLINPUTONE
ADD PRIMARY KEY (SYMBOL)
go


DROP TABLE SYMBOLINPUTTWO
go

CREATE TABLE SYMBOLINPUTTWO (
SYMBOL nvarchar(3) NOT NULL
)
go


ALTER TABLE SYMBOLINPUTTWO
ADD PRIMARY KEY (SYMBOL)
go


ALTER TABLE SYMBOLMERGE
ADD FOREIGN KEY (SYMBOL)
REFERENCES ELEMENTS
go

It could be done a lot better, but this would be very flexible and easy
to modify.
 
F

Flash Gordon

user923005 wrote, On 26/01/07 05:16:
Here is a simple way to accomplish the desired task...

1. Import the following data into a database into a table called
Elements:
SYMBOL,NAME,ATOMICNUMBER,ATOMICMASS
Ac,Actinium,89,227

Not exactly a C solution which is what the OP wanted. Also a lot more
work than is required to solve the OPs problem.

2. You only need a list of the atomic numbers or the symbol. Given
either of those lists, throw an error if any of the value presented are
not already in the list.

The OP needs to process the files his teacher told him to process, not
some alternative files suggested by you.
3. Create symbol tables called symbolmerge, symbolinputone,
symbolinputtwo, and symbolerrors. They only have one field : symbol

<snip>

Even your create table statements are longer than the entire program to
solve the OPs problem correctly as others have already suggested.

Read line from file 1
Read line from file 2
While we got data from at least one file
If no line from file 2
Or line from file 1 should be before line from file to then
line to output is line from file 1
Else
line to output is line from file 2
If line to output is different from last line output
Output line to output

Job done including removing duplicate lines and handling EOF. Note that
the original problem statement said the files were already sorted so you
do not need to sort them.

Also note that the OP will probably get a very poor grade for writing
the program in a language other than the one he is meant to be using.
 
M

mark_bluemel

Defected said:
Thanks all for help,

I have tried this code but it's don't work. [snip]
while(!feof(element_1)){
if(chemical_1.atomic_number < chemical_2.atomic_number){
fwrite(&chemical_1, sizeof(chimico_t), 1, element);
fscanf(element_1,"%d%s%s%lf",&chemical_1.atomic_number,
chemical_1.name,
chemical_1.symbol,
&chemical_1.weight);
}

else{
while(!feof(element_2)){
fwrite(&chemical_2, sizeof(chimico_t), 1, element);
fscanf(element_2,"%d%s%s%lf",&chemical_2.atomic_number,,
chemical_2.name,
chemical_2.symbol,
&chemical_2.weight);
}
}
}

So as soon as you have an entry in your second file which sorts before
the current entry in your first file, you write the whole of the second
file to your output? That doesn't seem sensible.

I've already outlined the basis of merging two already sorted files -
nested loops is probably not an appropriate approach. Let me try again,
in pseudo-code. Unless I've totally misunderstood your requirement,
it's fairly trivial.

read file1 into element1
read file2 into element2

while(you_have_some_data_from_at_least_one_file)
if (element1 < element2)
write element1 to output
read file1 into element1
else if (element1 = element2)
write (either element1 or element2) to output
read file1 into element1
read file2 into element2
else /* element1 > element2 */
write element2 to output
read file2 into element2
end if
end while

That's it, apart from opening and closing the files, error handling and
working out what happens at end of file - a simple sentinel approach
(setting atomic_number to an unreasonable value at end of file) would
probably work in your case.
 
U

user923005

user923005 wrote, On 26/01/07 05:16:



work than is required to solve the OPs problem.

The op's original problem has a flawed spec. The entire solution took
me less than 1/2 hour to write, debug and test.
If you change the element names to Chinese, it still works. If a
problem in the input occurs, it still works (and diagnoses the error)
some alternative files suggested by you.


Even your create table statements are longer than the entire program to
solve the OPs problem correctly as others have already suggested.

Read line from file 1
Read line from file 2
While we got data from at least one file
If no line from file 2
Or line from file 1 should be before line from file to then
line to output is line from file 1
Else
line to output is line from file 2
If line to output is different from last line output
Output line to output

Job done including removing duplicate lines and handling EOF. Note that
the original problem statement said the files were already sorted so you
do not need to sort them.

It is a mistake to assume that inputs are error free. You should at
least detect out of sort, or the solution is a bad one.
Also note that the OP will probably get a very poor grade for writing
the program in a language other than the one he is meant to be using.

That is what is wrong with the educational system. A bad design
(fundamentally flawed in many ways) cannot be corrected.
I taught C in college. If I thought the student knew how to code a C
solution and presented this one instead, I would give him full credit.
Of course, I would never have posed such an ill-formed problem in the
first place.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,770
Messages
2,569,583
Members
45,074
Latest member
StanleyFra

Latest Threads

Top