edit: fixed thanks
edit: fixed thanks
Last edited by typhonius; 02-08-2009 at 06:33 AM.
This line will overflow your buffer if the user types more than 39 characters:
You can use this to be safer:Code:scanf("%s", fname);
Are you asking what's wrong with the code you have now or what else you need to write to make it work?Code:fgets( fname, sizeof( fname ), stdin );
You're printing parts of the elements array even though you haven't written anything to the elements array...
"I am probably the laziest programmer on the planet, a fact with which anyone who has ever seen my code will agree." - esbo, 11/15/2008
"the internet is a scary place to be thats why i dont use it much." - billet, 03/17/2010
Thanks for the tip on the buffer. I'd read a tutorial on it and had tried to implement it in this assignment however I think I got some parameters muddled up!
Anyway...
I assumed I had put things into the elements array and now I look back over it I realise that you are of course, correct.
I had tried to put things into the array by using
but I don't think this would workCode:puts(elements[lcount]);
so could I assign the data to an array by stating
Code:int abundance_sorter() { FILE *infile; char fname[40]; char line[100]; char elements[20][50]; int lcount = 1; /* Read in the filename */ printf("\nEnter the name the file you wish to open: "); fgets( fname, sizeof( fname ), stdin ); /* Open the file. If NULL is returned there was an error */ if((infile = fopen(fname, "r")) == NULL) { printf("Error Opening File.\n"); exit(1); } while(fgets(line, sizeof(line), infile) != NULL ) { /* Get each line from the infile */ printf("Line %d: %s", lcount, line); scanf("%c", &elements[lcount]); lcount++; //puts(elements[lcount]); /* print the line number and data */ } printf("\nFile reading finished"); printf("\n%d this is it", elements[2][5]); //printf("\n the value is %s", elements[2][1]); fclose(infile); /* Close the file */ }
Edit: I've just inserted the
and it misses out the step where I should type in the filename and instead jumps to this output. :/Code:fgets( fname, sizeof( fname ), stdin );
Enter the name the file you wish to open: Error Opening File.
Last edited by typhonius; 02-07-2009 at 11:29 PM.
I wouldn't mix numbers with letters. You can do it, by changing the numbers to their char designations and such but it just muddies the waters of the logic, a great deal.
Basically, I know of two ways to do what you want to do:
1) use a struct - it groups letters and numbers into one "thing". For handling multiple fields (3 or more), in a record, (the one "thing"), it's the only way to fly.
2) if you have just two parts (fields) to each record, you can use parallel arrays. One for the element names, and one for their abundance number.
This is a simple assignment. Beware of making a "piano" (aka Rube Goldberg), out of it. Three functions should be fine: one for input, one for sorting, and one for output.
I think I would prefer to do no. 2 as we've not been taught structs just yet. I know about arrays but am unsure as to how I could implement a parallel array. If I start from where the file is read line by line to the program... where could I go from here as surely sorting it into an array will affect both the name and the abundance. ie, it will all get mixed up.
If you have a link to an example piece of code I would be most grateful, or if you can explain it in slightly greater depth I would also be most grateful.
Thank you
unfortunately not :/
Edit: Just got it working... at least I think so
does this look correct?
Code:char line[100]; char elements[20][50]; int lcount = 1; char fname[0]; /* Read in the filename */ printf("\nEnter the name the file you wish to open: "); scanf("%s", fname); fgets( fname, sizeof( fname ), stdin );
Last edited by typhonius; 02-08-2009 at 12:00 AM.
Ok. Let me bang out some code, for an example of parallel arrays, and I'll include fgets(), so you can see a good example (although there should be examples in the forum FAQ and on the board.
Back after bit.
You know to really debug what you have I'd probably need to see your whole program so I could run it and check for compiler warnings, etc.
Code:#include <stdio.h> #include <stdlib.h> #include <math.h> #include <string.h> #include <ctype.h> #include "abundance_sorter.h" #include "element_info.h" int decision; int main(){ while(1) { printf("This program has the ability to do four tasks. " "\n\nPlease pick the corresponding number related" " to the task you wish to be done.\n\n" "1. Sort elements stored on file by either name or abundance.\n" "2. Find maxima from data on wavelengths and absorbances.\n" "3. Root Finding\n" "4. Element Database\n"); scanf("%i", &decision); if (decision == 1) { printf("You have selected option 1"); abundance_sorter(); break; } if (decision == 2) { printf("You have selected option 2"); break; } if (decision == 3) { printf("You have selected option 3"); break; } if (decision == 4) { printf("You have selected option 4"); element_info(); break; } else { printf("Invalid Number\n"); continue; } return 0; } }
That is the main file and this is abundance_sorter.h
The code in comments is what has been tried yet proved detrimental to the program... ie, only outputting one line from the entire file etc.
Code:int abundance_sorter() { FILE *infile; char line[100]; char elements[20][50]; int lcount = 1; char fname[0]; /* Read in the filename */ printf("\nEnter the name the file you wish to open: "); scanf("%s", fname); fgets( fname, sizeof( fname ), stdin ); /* Open the file. If NULL is returned there was an error */ if((infile = fopen(fname, "r")) == NULL) { printf("Error Opening File.\n"); exit(1); } { while(fgets(line, sizeof(line), infile) != NULL ) { /* Get each line from the infile */ printf("Line %d: %s", lcount, line); //scanf("%s", &elements[lcount]); lcount++; //puts(elements[lcount]); /* print the line number and data */ } } printf("\nFile reading finished"); printf("\n%c this is it", elements[2][1]); //printf("\n the value is %s", elements[2][1]); fclose(infile); /* Close the file */ }
this is part 4, or element_info.h
And think... I have to fill in parts 2 and 3 :OCode:int element_info() { FILE *fp; char infofilename[127], repeat[9], element[127], symbol[127]; int melt, answer; printf("\n\n[Please enter the filename:]\n\n"); scanf("%s", infofilename); /* Try opening the file.*/ fp = fopen(infofilename, "a"); /* If file exists, append data to end of file, else create new file...*/ printf("Your file %s was created\n\n" "Now please enter the data you want stored" "\nElement: ", infofilename); scanf("%s", &element); fprintf(fp, "%s ", &element); printf("Symbol: "); scanf("%s", &symbol); fprintf(fp, "%s ", &symbol); printf("Melting Point: "); scanf("%d", &melt); fprintf(fp, "%d\n\n", melt); while(1) { printf("Would you like to enter more data?\n1. Yes\n2. No\n\n"); scanf("%i", &answer); if(answer == 1) { printf("Please enter the data you want stored" "\nElement: "); scanf("%s", &element); fprintf(fp, "%s ", &element); printf("Symbol: "); scanf("%s", &symbol); fprintf(fp, "%s ", &symbol); printf("Melting Point: "); scanf("%d", &melt); fprintf(fp, "%d\n\n", melt); continue; } if(answer == 2) { printf("Thank you for exploiting me today"); break; } else { printf("Invalid Number"); continue; } } fclose(fp); return 0; }
and my elements.txt file is
Code:Carbon 18 Calcium 1.5 Phosphorus 1.2 Hydrogen 10 Nitrogen 3 Chlorine 0.3 Sodium 0.1 Potassium 0.5 Sulfur 0.4 Oxygen 65 Magnesium 0.05
If you have to manage this much data for each element, then we need to upgrade you to structs, right away.
Forget parallel arrays for more than 2 fields in a record.
I thought I'd code up a little sample, but I believe I'll just tweak a bit of what you have.
choose one thing - do not use bothCode:scanf("%s", fname); fgets( fname, sizeof( fname ), stdin );
also note that fgets leaves the \n char in the buffer - youneed to remove it for example
Code:char* p = strchr(fname, '\n'); if(p) *p = '\0';
All problems in computer science can be solved by another level of indirection,
except for the problem of too many layers of indirection.
– David J. Wheeler
"I am probably the laziest programmer on the planet, a fact with which anyone who has ever seen my code will agree." - esbo, 11/15/2008
"the internet is a scary place to be thats why i dont use it much." - billet, 03/17/2010
Yeah, fname[0] was the problem. Also, I'd drop "abundance_sorter.h", and "element_info.h".
They're not needed, and don't add to the clarity of the program.
It now compiles, but is flawed in logic. I haven't run it yet, however.Code:#include <stdio.h> #include <stdlib.h> #include <math.h> #include <string.h> #include <ctype.h> //#include "abundance_sorter.h" //#include "element_info.h" #define MAX 30 //int decision; struct element { char name[40]; int abun; //you can add wavelength or other data members here, easily. }; int main(void) { int i, decision; struct element ele[MAX]; while(1) { printf("This program has the ability to do four tasks. " "\n\nPlease pick the corresponding number related" " to the task you wish to be done.\n\n" "1. Sort elements stored on file by either name or abundance.\n" "2. Find maxima from data on wavelengths and absorbances.\n" "3. Root Finding\n" "4. Element Database\n"); scanf("%i", &decision); if (decision == 1) { printf("You have selected option 1"); abundance_sorter(); break; } if (decision == 2) { printf("You have selected option 2"); break; } if (decision == 3) { printf("You have selected option 3"); break; } if (decision == 4) { printf("You have selected option 4"); element_info(); break; } else { printf("Invalid Number\n"); continue; } } return 0; } /* That is the main file and this is abundance_sorter.h The code in comments is what has been tried yet proved detrimental to the program... ie, only outputting one line from the entire file etc. Code: */ int abundance_sorter() { FILE *infile; char line[100]; char elements[20][50]; int lcount = 1; char fname[30]; /* Read in the filename */ printf("\nEnter the name the file you wish to open: "); scanf("%s", fname); fgets( fname, sizeof( fname ), stdin ); len = strlen(fname); //removes the filename newline char fname[--len] = '\0'; /* Open the file. If NULL is returned there was an error */ if((infile = fopen(fname, "r")) == NULL) { printf("Error Opening File.\n"); exit(1); } { while(fgets(line, sizeof(line), infile) != NULL ) { /* Get each line from the infile */ printf("Line %d: %s", lcount, line); //scanf("%s", &elements[lcount]); lcount++; //puts(elements[lcount]); /* print the line number and data */ } } printf("\nFile reading finished"); printf("\n%c this is it", elements[2][1]); //printf("\n the value is %s", elements[2][1]); fclose(infile); /* Close the file */ return 0; // } //this is part 4, or element_info.h //Code: int element_info() { FILE *fp; char infofilename[127], repeat[9], element[127], symbol[127]; int melt, answer; printf("\n\n[Please enter the filename:]\n\n"); scanf("%s", infofilename); /* Try opening the file.*/ fp = fopen(infofilename, "a"); /* If file exists, append data to end of file, else create new file...*/ printf("Your file %s was created\n\n" "Now please enter the data you want stored" "\nElement: ", infofilename); scanf("%s", &element); fprintf(fp, "%s ", &element); printf("Symbol: "); scanf("%s", &symbol); fprintf(fp, "%s ", &symbol); printf("Melting Point: "); scanf("%d", &melt); fprintf(fp, "%d\n\n", melt); while(1) { printf("Would you like to enter more data?\n1. Yes\n2. No\n\n"); scanf("%i", &answer); if(answer == 1) { printf("Please enter the data you want stored" "\nElement: "); scanf("%s", &element); fprintf(fp, "%s ", &element); printf("Symbol: "); scanf("%s", &symbol); fprintf(fp, "%s ", &symbol); printf("Melting Point: "); scanf("%d", &melt); fprintf(fp, "%d\n\n", melt); continue; } if(answer == 2) { printf("Thank you for exploiting me today"); break; } else { printf("Invalid Number"); continue; } } fclose(fp); return 0; }
Last edited by Adak; 02-08-2009 at 01:12 AM.
your action selector could be improved
could be written asCode:if (decision == 1) { ... } if (decision == 2) { ... } if (decision == 3) { ... } if (decision == 4) { ... }
to avoid checking conditions father after the correct match was foundCode:if (decision == 1) { ... } else if (decision == 2) { ... } else if (decision == 3) { ... } else if (decision == 4) { ... }
or using switch statement
All problems in computer science can be solved by another level of indirection,
except for the problem of too many layers of indirection.
– David J. Wheeler