How to Extract Atomic Numbers from a Text File into an Array in C?

  • Thread starter Thread starter TruthOasis
  • Start date Start date
  • Tags Tags
    Array File
Join the discussion
Ask a follow-up here, or get your own question answered by working scientists, mathematicians and engineers — people, not an autocomplete.
Real named experts · corrections over time · the nuance an AI answer skips
11 replies · 7K views
TruthOasis
Messages
7
Reaction score
0
Hi, I need help taking the atomic numbers from a list of elements and putting them in an array.
I have my data in a text file in the form:
Ac
227
Actinium
89

Al
26.981539
Aluminium
13

Am
243
Americium
95
etc.

This is what I am have so far:
FILE *fp;
char myStr[1000];
char atomicnumber[1000];
int i;
int j=0;

fp = fopen("elements.txt","r");
for (i=0;i<600;i++)
{
j++;
fgets(myStr,600,fp);
if ((i) % 3 ==5)
{
myStr=atomicnumber[j];
}

}
fclose(fp);
How would I get those numbers into an array like atomicnumber[1000]={89,13,95...} ?

Any help would be greatly appreciated.
 
Physics news on Phys.org
doesn't scanf() just take input from the user? How do I incorporate that into the program? Would i put in my for loop: scanf(%d,myStr) ?
 
The man page for scanf should also mention fscanf() to read form a FILE* and sscanf() to read from a string.

you would put something like
char abv[2];
float mass;
char name[32];
int number;
scanf("%s%f%s%d",abv,&mass,name,&number); // note the "&"

Try this first, then worry about readign them into arrays.
 
Ok, i tried to fix it but it isn't working correctly. I get a whole bunch of mess when I try to print the vector.
int main(void)
{
int i;
char elementSymbol[1000];
int atomicNumber[1000];
char elementName[1000];
float atomicMass[1000];

FILE *fp;

fp = fopen("elements.txt","r");
for (i=0;i<600;i++)
{
fscanf(fp,"%s\n%f\n%s\n%d",elementSymbol,&atomicMass,elementName,&atomicNumber);
printf("%s\n%f\n%s\n%d",elementSymbol,&atomicMass,elementName,&atomicNumber);

}
fclose(fp);
system("PAUSE");
return 0;
}
 
printf("%s\n%f\n%s\n%d",elementSymbol,&atomicMass, elementName,&atomicNumber);
The & means take the address of - so you are trying to print the address of atomicMass as a float instead of the value of atomicMass. You need the '&' on scanf because you are reading data - so you need the address to tell scanf where to put it.

Your arrays are also a little confused.
"char elementSymbol[1000];" - means an array of 1000 chars, or a string 999chars long
"int atomicNumber[1000];" - means an array of 1000 ints, for now just put atomicNumber and atomicMass.
 
when I set the size of my array, shouldn't i just make it a really big number so the amount of characters or numbers don't exceed that size, until I learn how to use dynamic allocation?
Also, I can't just forget about the abbreviation and name because when I use the fscanf function I need to use the \n to tell it to go from line to line.

this is what I have right now I'm not sure what else to do.
int i;
char elementSymbol[500][3];
int atomicNumber[1000];
char elementName[500][20];
float atomicMass[1000];

FILE *fp;

fp = fopen("elements.txt","r");
for (i=0;i<545;i++)
{
fscanf(fp,"%s\n%f\n%s\n%d",elementSymbol,&atomicMass,elementName,&atomicNumber);
printf("%s\n%f\n%s\n%d",elementSymbol,atomicMass,elementName,atomicNumber);

}
fclose(fp);
 
I meant don't worry about storing the array for now, just have variables for one entry:
Code:
char elementSymbol[3];
int atomicNumber;
char elementName[20];
float atomicMass;

But what you have is close - so carry on!
How do you know how many entries are in the file?
You are allocating space for 500 of them but reading 545 of them?
fscanf returns the numbe rof entries it matched, so you can use this to check if it worked.
You should also check the value of 'fp' after the open to make sure the open worked - otherwise it will crash at the first fscanf()
 
Cool! I took it out of the for loop and removed the and got the first 4 values. So the file is opening correctly.

fp = fopen("elements.txt","r");
fscanf(fp,"%s\n%f\n%s\n%d",elementSymbol,&atomicMass,elementName,&atomicNumber);
printf("%s\n%f\n%s\n%d\n",elementSymbol,atomicMass,elementName,atomicNumber);

display:
Ac
227.000000
Actinium
89
Press any key to continue . . .but now when I try to put it back in the for loop and put the after each variable so I go the the next component it doesn't cycle correctly

btw, I have most of the elements and I calculated I had 545 lines
 
You were very close - with the array index
Code:
for (i=0;i<545;i++)
{
fscanf(fp,"%s\n%f\n%s\n%d",elementSymbol[i],&atomicMass[i],elementName[i],&atomicNumber[i]);
printf("%s\n%f\n%s\n%d",elementSymbol[i],atomicMass[i],elementName[i],atomicNumber[i]);
}
The second dimension on the strings is sort of handled automatically - think of elementSymbol[500][3] as an array of 500 strings of length [3]

You probably want to check if fscanf returns 0 for end of file.
You might also need another '\n' at the end of fscanf to skip the blank line.

This isn't the most robust way of doing this - in reality you would read each line and decide what it was then convert it into the correct type.
fscanf() is very useful if all the parts of the record is on one line.
 
Hmmm.. when I try doing that I get an error: subscripted value is neither an array nor a pointer

this only happens when i add the to the atomic mass and atomic number.
Is this because i didn't initialize them correctly? Do I need to set up a pointer variable?
 
Nevermind I found the problem. Seems I was going way to far in my for loop like you thought. Got it all to work! Thanks for all your help!