Thread: Data not seeming to go to array

  1. #1
    Registered User
    Join Date
    Feb 2009
    Posts
    21

    Data not seeming to go to array

    edit: fixed thanks
    Last edited by typhonius; 02-08-2009 at 06:33 AM.

  2. #2
    and the hat of sweating
    Join Date
    Aug 2007
    Location
    Toronto, ON
    Posts
    3,545
    This line will overflow your buffer if the user types more than 39 characters:
    Code:
    scanf("%s", fname);
    You can use this to be safer:
    Code:
    fgets( fname, sizeof( fname ), stdin );
    Are you asking what's wrong with the code you have now or what else you need to write to make it work?
    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

  3. #3
    Registered User
    Join Date
    Feb 2009
    Posts
    21
    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
    Code:
    puts(elements[lcount]);
    but I don't think this would work

    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
    Code:
      fgets( fname, sizeof( fname ), stdin );
    and it misses out the step where I should type in the filename and instead jumps to this output. :/

    Enter the name the file you wish to open: Error Opening File.
    Last edited by typhonius; 02-07-2009 at 11:29 PM.

  4. #4
    Registered User
    Join Date
    Sep 2006
    Posts
    8,868
    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.

  5. #5
    Registered User
    Join Date
    Feb 2009
    Posts
    21
    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

  6. #6
    Registered User
    Join Date
    Sep 2006
    Posts
    8,868
    Quote Originally Posted by typhonius View Post
    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
    Ok. sure. Have you got fgets() reading the file name working ok, now?

  7. #7
    Registered User
    Join Date
    Feb 2009
    Posts
    21
    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.

  8. #8
    Registered User
    Join Date
    Sep 2006
    Posts
    8,868
    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.

  9. #9
    Registered User
    Join Date
    Feb 2009
    Posts
    21
    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

    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;
    }
    And think... I have to fill in parts 2 and 3 :O

  10. #10
    Registered User
    Join Date
    Feb 2009
    Posts
    21
    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

  11. #11
    Registered User
    Join Date
    Sep 2006
    Posts
    8,868
    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.

  12. #12
    Hurry Slowly vart's Avatar
    Join Date
    Oct 2006
    Location
    Rishon LeZion, Israel
    Posts
    6,788
    Code:
      scanf("%s", fname);
      fgets( fname, sizeof( fname ), stdin );
    choose one thing - do not use both

    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

  13. #13
    and the hat of sweating
    Join Date
    Aug 2007
    Location
    Toronto, ON
    Posts
    3,545
    Quote Originally Posted by typhonius View Post
    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
    Code:
    puts(elements[lcount]);
    but I don't think this would work
    No, puts() just prints the string you pass to it.
    Try something like strcpy() or sscanf()

    Quote Originally Posted by typhonius
    Edit: Just got it working... at least I think so

    does this look correct?


    Code:
    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 );
    Why are you creating an fname array that stores 0 characters? You need to give it a valid size.
    "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

  14. #14
    Registered User
    Join Date
    Sep 2006
    Posts
    8,868
    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.



    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;
    }
    It now compiles, but is flawed in logic. I haven't run it yet, however.
    Last edited by Adak; 02-08-2009 at 01:12 AM.

  15. #15
    Hurry Slowly vart's Avatar
    Join Date
    Oct 2006
    Location
    Rishon LeZion, Israel
    Posts
    6,788
    your action selector could be improved
    Code:
    if (decision == 1)
    {
     ...
    }
    if (decision == 2)
    {
     ...
    }
    if (decision == 3)
    {
       ...
    }
    if (decision == 4)
    {
     ...
    }
    could be written as
    Code:
    if (decision == 1)
    {
     ...
    }
    else if (decision == 2)
    {
     ...
    }
    else if (decision == 3)
    {
       ...
    }
    else if (decision == 4)
    {
     ...
    }
    to avoid checking conditions father after the correct match was found
    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

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Pick data from file store in array
    By swgh in forum C Programming
    Replies: 1
    Last Post: 07-10-2009, 09:57 AM
  2. Replies: 48
    Last Post: 09-26-2008, 03:45 AM
  3. Dynamic Array substitution in composite data variable
    By DavidDobson in forum C Programming
    Replies: 2
    Last Post: 08-12-2008, 04:29 AM
  4. Replies: 2
    Last Post: 07-11-2008, 07:39 AM
  5. Template Array Class
    By hpy_gilmore8 in forum C++ Programming
    Replies: 15
    Last Post: 04-11-2004, 11:15 PM