Thread: Manipulating a read-in file in C

  1. #1
    Registered User
    Join Date
    Mar 2011
    Posts
    42

    Manipulating a read-in file in C

    Hi guys,

    This is the first time I have worked with files, up until now I have just worked with compiling functions to the command screen. I have a project where I need to read-in a text file, multiple each variable by a certain percentage and output a file with the results.
    The input file looks something like:

    Mike 90,80,75,100,100

    Each value then needs to be multiplied by a certain weighted percentage and the output file would then return a letter grade, like:

    Mike B

    There can be many lines of people/scores....

    Here is the code I have so far, and is where I am stuck. I have read in the file, now I am trying to figure out what to do next. I figured this part out by reading my book, and it was pretty clear how to do this part, but I am not sure how to proceed. I know I need to do something with the string to get it multiplied, but I am not sure how:

    Code:
    #include <stdio.h>
    
    
    int main(void)
    
    {
    	int ch;
    	FILE * fp;
    	fp = fopen("C:\\Documents and Settings\\name\\Desktop\\Final_Input.txt", "r");
    	ch = getc (fp);
    	while (ch != EOF)
    	{
    		putchar(ch);
    		ch= getc(fp);
    	}
    
    }
    Any help would be appreciated. Thanks

  2. #2
    Banned
    Join Date
    Aug 2010
    Location
    Ontario Canada
    Posts
    9,547
    Since each line of the file is a data set of it's own, you probably want to read the file line by line using something like fgets() into a string buffer and then burst out the values using sscanf() or such to get at the information. You can then do your calculations write that line to your new file and move on to the next...

  3. #3
    Registered User
    Join Date
    Mar 2011
    Posts
    42
    Forgive my ignorance Tater, but are you referring to replacing part of my existing code, fopen() with fgets()? Or are you referring to the next step in the process below what I already have. I am confused. Thanks

    EDIT: fopen() and fgets() are 2 totally differnet things, nevermind. I'll figure it out eventually..
    Last edited by JoshD75; 04-23-2011 at 12:18 PM.

  4. #4
    Banned
    Join Date
    Aug 2010
    Location
    Ontario Canada
    Posts
    9,547
    You need to rethink your approach to the problem...
    Look at your file... it is line based... that is the data on each line is a complete data set of it's own. i.e. "Mike 90,80,75,100,100" contains all the information you need to process that line. Therefore you do not want to read the file in character by character as your first code would. It may echo the file to the screen very nicely but it doesn't give you meaningful access to the information in the file... for that you need some kind of structured input routine.

    As it turns out C libraries provide several ways of doing this... you can use fscanf() to read in a complete line at a time, so long as each line has the same number of parameters on it... (A name and 5 numbers per your example). If some lines have more or less than 5 numbers you will need to use a slightly different strategy in which case you can use fgets() to read a line from the file into a string variable and then extract the values from there using other library functions such as strtok(), atoi(), sscanf() etc.

    fopen() is for opening files... fgets() is one of many ways you can read a file's contents... so yes they're different things.

    Look these various functions up in your C libary documentation.

    Here's a tutorial on files that may help you... C Tutorial - Chapter 10
    Last edited by CommonTater; 04-23-2011 at 12:40 PM.

  5. #5
    Registered User
    Join Date
    Mar 2011
    Posts
    42
    Thank you for breaking it down like that Tater, that makes sense. I am going to give this a shot, hopefully get some workable code from it and post back here to see how I did. Thanks again

  6. #6
    Banned
    Join Date
    Aug 2010
    Location
    Ontario Canada
    Posts
    9,547
    Quote Originally Posted by JoshD75 View Post
    Thank you for breaking it down like that Tater, that makes sense. I am going to give this a shot, hopefully get some workable code from it and post back here to see how I did. Thanks again
    Good stuff...

    One hint: If the file is consistently a name and 5 numbers per line... I'd go with scanf()...

  7. #7
    Registered User
    Join Date
    Mar 2011
    Posts
    42
    Hi again,

    I couldn't figure out how to do it your way Tater, so I decided to try to read-in the file by character rather than line. I am getting 1 error and 14 warnings with this, and I am not sure how to proceed from here. I have commented the error towards the bottom of the code. The 14 warnings are mostly conversion warnings (int to float) (double to float).....Here is the code, I hope I didn't make this more complicated than it needs to be. Any ideas?.....


    *EDIT* I figured out the Error part, but that still leaves me with the 14 warnings. I should probably clean this up....

    Code:
    #include <stdio.h>
    
    
    int main(void)
    {
    	int ch;
    	int track=1;
    	FILE * fp;
    	char name[999];
    	char quiz1[3];
    	char quiz2[3];
    	char quiz3[3];
    	char quiz4[3];
    	char midterm[3];
    	char finalproject[3];
    	float q1;
    	float q2;
    	float q3;
    	float q4;
    	float mid;
    	float final;
    	float total_grade=0;
    	int index=0;
    	fp = fopen("C:\\Documents and Settings\\xxxx\\Desktop\\Final_Input.txt", "r");
    	ch = getc (fp);
    	name[index]=ch;
    	index++;
    	while (ch != EOF)
    	{
    		//putchar(ch);
    		ch= getc(fp);
    		if(track==1)
    		{
    			if(ch==',')
    			{
    				name[index]='\0';
    				track++;
    				index=0;
    			}
    		else
    			{
    				name[index]=ch;
    				index++;
    			}
    		}
    		else if(track==2)
    		{
    			if(ch==',')
    			{
    				quiz1[index]='\0';
    				q1=atoi(quiz1);
    				total_grade=total_grade+q1*.10;
    				track++;
    				index=0;
    			}
    			else
    			{
    				quiz1[index]=ch;
    				index++;
    			}
    		}
    		else if(track==3)
    		{
    			if(ch==',')
    			{
    				quiz2[index]='\0';
    				q2=atoi(quiz2);
    				total_grade=total_grade+q2*.10;
    				track++;
    				index=0;
    			}
    			else
    			{
    				quiz2[index]=ch;
    				index++;
    			}
    		}
    		else if(track==4)
    		{
    			if(ch==',')
    			{
    				quiz3[index]='\0';
    				q3=atoi(quiz3);
    				total_grade=total_grade+q3*.10;
    				track++;
    				index=0;
    			}
    			else
    			{
    				quiz3[index]=ch;
    				index++;
    			}
    		}
    		else if(track==5)
    		{
    			if(ch==',')
    			{
    				quiz4[index]='\0';
    				q4=atoi(quiz4);
    				total_grade=total_grade+q4*.10;
    				track++;
    				index=0;
    			}
    			else
    			{
    				quiz4[index]=ch;
    				index++;
    			}
    		}
    		else if(track==6)
    		{
    			if(ch==',')
    			{
    				midterm[index]='\0';
    				mid=atoi(midterm);
    				total_grade=total_grade+mid*.25;
    				track++;
    				index=0;
    			}
    			else
    			{
    				midterm[index]=ch;
    				index++;
    			}
    		}
    		else if(track==7)
    		{
    			if(ch==',')
    			{
    				finalproject[index]='\0';
    				final=atoi(finalproject);
    				total_grade=total_grade+final*.35;
    				track++;
    				index=0;
    			}
    			else
    			{
    				final[index]=ch;  //subscript requires array or pointer type
    				index++;
    			}
    		}
    	}
    	//printf("%.2f",total_grade);
    }
    Last edited by JoshD75; 04-27-2011 at 08:23 PM.

  8. #8
    Banned
    Join Date
    Aug 2010
    Location
    Ontario Canada
    Posts
    9,547
    Ok... using this as your example,
    Mike 90,80,75,100,100
    Look at this line... what do you see?
    I see a string and 5 integers, separated by commas.
    So what we need is some kind of formatted read utility that can fetch this from a file for us...
    That would be fscanf() ... (Yes, look it up!)

    With me so far?

    Now... we need to
    1) open your input file,
    2) open your output file,
    3) read one line from the input file with scanf()
    4) Calculate the average
    5) Write it to the output file
    6) check for end of input file
    7) if not end of file loop back to #3
    8) close the input file
    9) close the output file


    Write that and lets see how you make out...
    Seriously... we're talking about less than 30 lines of code here....
    how hard can it be?
    Last edited by CommonTater; 04-27-2011 at 09:04 PM.

  9. #9
    Registered User
    Join Date
    Mar 2011
    Posts
    42
    Sorry Tater, I know I am making this way more difficult than it needs to be. I am just lost. Your outline makes sense, one question though...how do I account for the weighted averages? It is not just averaging the line as a whole, each score is weighted.

    Thanks

  10. #10
    Banned
    Join Date
    Aug 2010
    Location
    Ontario Canada
    Posts
    9,547
    Get this part working first... seriously... nothing else is even worth thinking about until you have it correctly reading the file.

    So here's the task... get it to read one line of the file data into variables in your program and get it to print them to the screen.

    Nothing else matters until that is working.


    Think in small blobs. In programming things don't happen as some grand unified thing, they happen in little tiny steps. Do all the little steps and the big ones will take care of themselves...

  11. #11
    Registered User
    Join Date
    Mar 2011
    Posts
    42
    Ok, I think I am getting somewhat closer and getting the general concept of fscanf(). Here is my latest attempt, I am getting 0 errors but 5 warnings. Warnings such as firstname isn't intialized, last name isn't intialized and "incompatible types - from 'FILE *' to 'const char *'. Also, nothing prints to the screen. The console opens but I get nothing...

    Am I close? Thanks again...


    *EDIT* I realized I needed to turn firstname, lastname into arrays. Not a single char. So now it prints, but it is printing weird symbols, not what is on the file...


    Code:
    #include <stdio.h>
    #include <string.h>
    
    int main()
    {
      
      char firstname [50];
      char lastname [50];
      float q1,q2,q3,q4,mid,final;
      FILE *fp;
      char my_filename_input[] = "C:\\Documents and Settings\\xxxx\\Desktop\\Final_Input.txt";
      fp=fopen (my_filename_input, "r");
      fscanf (fp, "%s, %s, %f, %f, %f, %f, %f\n",firstname,lastname,&q1, &q2, &q3,&q4,&mid,&final);
      printf (fp, "%s %s %f %f %f %f %f", firstname,lastname,q1, q2, q3,q4,mid,final);
      
    }
    Last edited by JoshD75; 04-28-2011 at 11:53 AM.

  12. #12
    Registered User
    Join Date
    Sep 2008
    Location
    Toronto, Canada
    Posts
    1,834
    You are reading in seven items according to the format string. There are eight variables though.

  13. #13
    Banned
    Join Date
    Aug 2010
    Location
    Ontario Canada
    Posts
    9,547
    Can you give me a sample of the exact file... 10 or 20 lines?

    Also, are you sure the grade scores need to be floats... if the scoring runs the typical 0 - 100 ints would work better.

    Your scanf is very close and your printf almost works...
    Code:
      fscanf (fp, "%s %s %f,%f,%f,%f,%f",firstname,lastname,&q1, &q2, &q3,&q4,&mid,&final);
      printf ("%s %s %f %f %f %f %f", firstname,lastname,q1, q2, q3,q4,mid,final);
    Note... this is one case where spacing does matter...
    Last edited by CommonTater; 04-28-2011 at 12:32 PM.

  14. #14
    Banned
    Join Date
    Aug 2010
    Location
    Ontario Canada
    Posts
    9,547
    Quote Originally Posted by nonoob View Post
    You are reading in seven items according to the format string. There are eight variables though.
    It would also help if he didn't keep changing the requirements... this is the first time I've seen a last name mentioned...

  15. #15
    Registered User
    Join Date
    Mar 2011
    Posts
    42
    Sorry Tater,

    I changed to firstname/lastname because of "John Doe" for example. I didn't think "name" was correct (to account for second word/spaces)

    Here are 3 lines...note they all have the same amout of scores (weighted in order,
    .10, .10, .10, .10; .25, .35)

    John Doe,80,90,70,100,90,95
    John Doe 2,90,80,90,90,95,100
    Jane Doe,100,90,80,100,100,90

    I may have mistakingly made them float, the actual averages (results) need to be float for the output file. But maybe these can be integers?

    Thanks again

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. manipulating fgetc while reading a file
    By agentsmith in forum C Programming
    Replies: 1
    Last Post: 04-10-2008, 01:52 PM
  2. NOOB: Need a little help opening file and manipulating data
    By liquidcourage1 in forum C++ Programming
    Replies: 7
    Last Post: 02-26-2006, 10:27 PM
  3. How can I know the actual bytes read in a file read
    By pliang in forum C++ Programming
    Replies: 1
    Last Post: 06-08-2005, 04:23 PM
  4. Manipulating Text File?
    By Silverdream in forum C Programming
    Replies: 1
    Last Post: 03-22-2002, 06:44 PM