Thread: File input question

  1. #1
    Registered User
    Join Date
    Jun 2004
    Posts
    93

    File input question

    I am currently making a function to input some information from a file. The input consists of names and grades. After various attempts, test runs, and a couple of crazy ideas, nothing has really worked.

    I don't know if the names will be in the context of First, Middle, Last, or if there will be a middle name missing.

    This presents a problem, because when the middle name is missing, the string that should take the middle name input takes something else instead.

    So when I input this, I get the grades for the last name, first names for grade, or something to that effect.

    Here's my code, and I will bold the part that I am working on.

    Code:
    // Don't forget to +1 MAX_LETTERS
    #include <stdio.h>
    #include <ctype.h>
    
    #define MAX_SCORE  100
    #define MIN_SCORE  0
    #define TOTAL_ASSIGNMENT_MAX_SCORE 300
    #define MAX_STUDENTS 150
    #define MAX_LETTERS 30
    
    void menu (void);
    float take_score (char first_names[][MAX_LETTERS], 
    				  char middle_names[][MAX_LETTERS], 
    				  char last_names[][MAX_LETTERS], 
    				  int student_num);
    
    float final_score_calc (float student_grades[][3], int x);
    char letter_grade (float final_scores[], int y);
    float G_P_A (char grades[], int y);
    void info_display (void);
    
    void print_scores (char first_names[][MAX_LETTERS], 
    				   char middle_names[][MAX_LETTERS], 
    				   char last_names[][MAX_LETTERS], 
    				   float final_scores[],
    				   char grades[], float GPAs[], 
    				   int student_num);
    
    float high_score_calc (float final_scores[], int student_num);
    float low_score_calc (float final_scores[], int student_num);
    
    void grade_list (float student_grades[][3],
    				 char first_names[][MAX_LETTERS], 
    				 char middle_names[][MAX_LETTERS],
    				 char last_names[][MAX_LETTERS],
    				 int x, int y);
    
    void Load ( int *p );
    
    // Global Variables
    
    	char grades[MAX_STUDENTS];
    	char first_names    [MAX_STUDENTS][MAX_LETTERS];
    	char middle_names   [MAX_STUDENTS][MAX_LETTERS];
    	char last_names     [MAX_STUDENTS][MAX_LETTERS];
    	float student_grades[MAX_STUDENTS][3];
    	float GPAs[MAX_STUDENTS];
    	float final_scores[MAX_STUDENTS];
    	char input_name[50];
    
    	FILE *input_ptr; // Input file's pointer
    
    int main () {
    
    	
    
    
    
    menu();
    return 0;
    
    }
    
    void menu (void) {
    
    	char c;
    	float total_final_score = 0, average_final_score = 0, high_score = 0, low_score = 0 ;
    	float A_Percentage = 0, B_Percentage = 0, C_Percentage = 0, D_Percentage = 0, F_Percentage= 0;
    	int student_counter = 0, ACounter = 0, BCounter = 0, CCounter = 0, DCounter = 0, FCounter = 0, 
    		total_Grade_Count = 0;
    	int student_num = -1; // Start at -1 so it does not equal 1 and the array later skips the 0 element
    	int low_range, high_range;
    	int i = 0, j = 0;
    	float sum = 0;
    	
    
    	do{
    
    
    		printf("A/a  - Add a student's record\n");
    		printf("I/i - load students record from an input file\n");
    		printf("O/o - Save students record to an output file\n");
    		printf("L/l - display a list of students score\n");
    		printf("F/f - Find a student's record from the spreadsheet and display his/her record\n");
    		printf("S/s - Reorder the student's record based on final scores\n"); 
    		printf("D/d - Display current statistical results\n");
    		printf("Q/q - Quit\n");
    		printf("\nPlease enter a key for one of the above options:");
    
    		c=getchar();
    		c=toupper(c);	
    		
    		switch (c) {		
    
    			
            
    		case 'A': 
    				  
    				  student_num++;  
    						 
    				  final_scores[student_num] = take_score(first_names, middle_names, last_names, student_num);
    
    				  grades[student_num] = letter_grade(final_scores, student_num);
    
    				  GPAs[student_num] = G_P_A(grades, student_num);
    
    				  print_scores(first_names, middle_names, last_names, final_scores, grades, GPAs, student_num);
    
    				  
    				  break;
    
    		case 'D':
    				  
    			      //Going through grade array for letter grade count
    
    				  for ( ; i <= student_num; i++ ) 
    
    				  {
    						
    						switch (grades[i]) 
    
    						{		 
    						
    								 case 'A': ACounter++;
    												break;
    
    								 case 'B': BCounter++;
    												break;
    
    								 case 'C': CCounter++;
    												break;
    			
    								 case 'D': DCounter++;
    												break;
    
    								 case 'F': FCounter++;
    												break;
    						
    						}
    
    				  }
    
    				  total_Grade_Count = ACounter + BCounter + CCounter + DCounter + FCounter;
    
    				  if (ACounter == 0)
    					  A_Percentage = 0;
    
    				  else
    					  A_Percentage = (( float ) ACounter / total_Grade_Count) * 100;
    
    				  if (BCounter == 0)
    					  B_Percentage = 0;
    
    				  else
    					  B_Percentage = (( float ) BCounter / total_Grade_Count) * 100;
    
    				  if (CCounter == 0)
    					  C_Percentage = 0;
    
    				  else
    					  C_Percentage = (( float ) CCounter / total_Grade_Count) * 100;
    
    				  if (DCounter == 0)
    					  D_Percentage = 0;
    
    				  else
    					  D_Percentage = (( float ) DCounter / total_Grade_Count) * 100;
    
    				  if (FCounter == 0)
    					  F_Percentage = 0;
    
    				  else
    					  F_Percentage = (( float ) FCounter / total_Grade_Count) * 100;
    
    				  /*B_Percentage = (( float ) BCounter / total_Grade_Count) * 100;
    				  C_Percentage = (( float ) CCounter / total_Grade_Count) * 100;	
    				  D_Percentage = (( float ) DCounter / total_Grade_Count) * 100;
    				  F_Percentage = (( float ) FCounter / total_Grade_Count) * 100;*/
    
    				  
    				  //Gets the average final score, switch statement is there in case of no score being entered or only
    				  //one score being entered.
    
    				  	switch (student_num) 
    
    					{
    
    						case -1: average_final_score = 0;
    								 break;
    
    						case 0:  average_final_score = final_scores[student_num];
    								 break;
    
    						default:
    
    								 for ( ; j <= student_num; j++ ) 
    									 sum += final_scores[j];	
    								
    								 average_final_score = (sum / (student_num + 1));
    								 break;
    					}
    
    				  //High Score
    
    				  high_score = high_score_calc (final_scores, student_num);
    
    				  //Low Score
    
    				  low_score = low_score_calc(final_scores, student_num);
    
    				  //Prints Statistical Results
    
    				   printf("\nStatistical result of your class:\n\n");
    				   printf("\n\tTotal Students Number:\t%d", student_num+1);
    				   printf("\n\tAverage score:\t%.2f",average_final_score);
    				   printf("\n\tHighest score:\t%.2f",high_score);
    				   printf("\n\tLowest score:\t%.2f",low_score);
    				   printf("\n\tTotal A grade: %d, percentage   %.2f%%", ACounter, A_Percentage);
    				   printf("\n\tTotal B grade: %d, percentage   %.2f%%", BCounter, B_Percentage);
    				   printf("\n\tTotal C grade: %d, percentage   %.2f%%", CCounter, C_Percentage);
    			       printf("\n\tTotal D grade: %d, percentage   %.2f%%", DCounter, D_Percentage);
    				   printf("\n\tTotal F grade: %d, percentage   %.2f%%\n\n", FCounter, F_Percentage);
    				  
    				   break;
    
    		case 'I':
    					
    				   Load(&student_num);
    
    				   break;
    
    		case 'L':
    
    				   printf("\nPlease enter range of index number of record you wish to display:\n");
    				   scanf("%d %d", &low_range, &high_range);
    				   grade_list(student_grades, first_names, middle_names, last_names, low_range, high_range);
    
    				   break;
    
    
    		}
    
    		getchar ();
    
    	}while (c != 'Q' );
    	
    		printf("\nBye!\n\n");
    
    }	
    
    float final_score_calc (float student_grades[MAX_STUDENTS][3], int student_num)
    
    {
    
    	 float final_score;
    
    	 final_score = (student_grades[student_num][0]) / 3.0 * 0.3 + (student_grades[student_num][1]) * 0.3 + (student_grades[student_num][2]) * 0.4;
    
    	 return final_score;
    
     }
    
    float take_score (char first_names[][MAX_LETTERS], 
    				  char middle_names[][MAX_LETTERS], 
    				  char last_names[][MAX_LETTERS], 
    				  int student_num) {
    
    
    
    	float final_score;
    
    	//float student_grades[MAX_STUDENTS][3];
    	
    
    	int j = 0, k= 0;
    
    		printf("\nindex %d> Enter a student's name (first middle last), total assignment, midterm and final exam scores:", student_num + 1);
    						
    		scanf("%s %s %s", first_names[student_num], middle_names[student_num], last_names[student_num]);
    
    		scanf("%f %f %f", &student_grades[student_num][j], &student_grades[student_num][j+1], &student_grades[student_num][j+2]);
    
      while (student_grades[student_num][j] > TOTAL_ASSIGNMENT_MAX_SCORE || student_grades[student_num][j] < MIN_SCORE)
    
      {
       printf("\nPlease re-enter total assignment score (0~300) :");
       scanf("%f", &student_grades[student_num][j]);
      }
    
    
      while (student_grades[student_num][j+1] > MAX_SCORE || student_grades[student_num][j+1] < MIN_SCORE)
    
      {
       printf("\nPlease re-enter midterm score (0~100) :");
       scanf("%f", &student_grades[student_num][j + 1]);
      }
    
      while (student_grades[student_num][j+2] > MAX_SCORE || student_grades[student_num][j+2] <MIN_SCORE)
    
      {
       printf("\nPlease re-enter final exam score (0~100) :");
       scanf("%f", &student_grades[student_num][j+2]);
      }
     
      final_score = final_score_calc (student_grades, student_num);
    
      return final_score;
    
     }
    
    char letter_grade (float final_scores[], int student_num) {
    
    	//float final_scores[MAX_STUDENTS];
    	
    	char grade;
    
    	if (final_scores[student_num] >= 90)
    		grade='A';
    
    	else if (final_scores[student_num] < 90 && final_scores[student_num] >= 80)
    		grade='B';
    
    	else if (final_scores[student_num] < 80 && final_scores[student_num] >= 70)
    		grade='C';
    
    	else if (final_scores[student_num] < 70 && final_scores[student_num] >= 60)
    		grade='D';
    
    	else if (final_scores[student_num] < 60)
    		grade='F';
    
    	return grade;
    
    }
    
    float G_P_A (char grades[], int student_num) {
    
    	switch ( grades[student_num]) {
    
    			case 'A': GPAs[student_num] = 4; 
    					  break;
    
    		    case 'B': GPAs[student_num] = 3; 
    					  break;
    
    			case 'C': GPAs[student_num] = 2; 
    					  break;
    			
    		    case 'D': GPAs[student_num] = 1; 
    					  break;
    
    		    case 'F': GPAs[student_num] = 0; 
    					  break;
    
     }
    
    	return GPAs[student_num];
    
    }
    
    void print_scores (char first_names[][MAX_LETTERS], 
    				   char middle_names[][MAX_LETTERS], 
    				   char last_names[][MAX_LETTERS], 
    				   float final_scores[],
    				   char grades[], float GPAs[],
    				   int student_num) {
    
    	printf("\nindex %d> %s %s %s's final_score:   %.2f  letter grade:%c  GPA:%f\n\n", student_num + 1, first_names[student_num], 
    		                                                       middle_names[student_num],last_names[student_num], final_scores[student_num],
    															   grades[student_num], GPAs[student_num]);
    																		  
    
    }
    
    float high_score_calc (float final_scores[], int student_num) {
    
    	int i;
    	float high_score;
    
    	switch (student_num) 
    
    	{
    
    	case -1: high_score = 0;
    			 break;
    
    	case 0: high_score = final_scores[student_num];
    			break;
    
    	default:
    
    		for ( i = 0; i < student_num; i++ ) {
    
    				if ( final_scores[i] > final_scores[i+1] )
    					high_score = final_scores[i];
    
    				else
    					high_score = final_scores[i+1];
    		}	
    
    		break;
    	}
    
    	return high_score;
    
    }
    
    
    float low_score_calc (float final_scores[], int student_num) {
    
    	int i;
    	float low_score;
    	
    	switch (student_num) 
    
    	{
    
    	case -1: low_score = 0;
    			 break;
    
    	case 0:  low_score = final_scores[student_num];
    			 break;
    
    	default: for ( i = 0; i < student_num; i++ )
    				 if ( final_scores[i] > final_scores[i+1] )
    					 low_score = final_scores[i+1];
    				 
    				 else 
    					 low_score = final_scores[i];
    	}
    
    	return low_score;
    
    }
    
    
    
    
    
    
    
    void grade_list (float student_grades[][3], 
    				 char first_names[][MAX_LETTERS], 
    				 char middle_names[][MAX_LETTERS],
    				 char last_names[][MAX_LETTERS],
    				 int x, int y) {
    
    	printf("\nIndex Name                Assign  Mid Final_Exam Final_Score LG  GPA\n");
    	
    	for ( ; x <= y;){
    
    		printf("%-6d", x);
    		printf("%-6s, %-5s, %-6s", last_names[x-1], first_names[x-1], middle_names[x-1]);
    		printf("%-7.0f %-4.0f %-11.0f",student_grades[x-1][0], student_grades[x-1][1], student_grades[x-1][2]);
    		printf("%-11.2f", final_scores[x-1]);
    		printf("%-5c", grades[x-1]);
    		printf("%.0f", GPAs[x-1]);
    				 
    		x++;
    
    		printf("%c", '\n');
    
    	}
    		
    		printf("%c", '\n');
    }
    
    
    void Load ( int *student_numptr ) 
    
    {
    
    	int i, j, k, file_counter;
    	char c, d, e;
    
    	printf("\nPlease enter input file name: ");
    				   scanf("%s", input_name);
    
    				   if ((input_ptr = fopen(input_name, "r")) == NULL )
    					   printf("\nThe file could not be opened.\n");
    
    				   else 
    					   
    					   file_counter = 0;
    
    					   while ( !feof(input_ptr)) {
    
    					   (*student_numptr)++;
    
    					   i = 0;
    					   j = 0;
    					   k = 0;
    
    					   do{
    
    						   c = (fgetc(input_ptr));
    						   first_names[*student_numptr][i] = c;
    						   i++;
    
    					   }while(!isspace(c));
    
    					   do{
    
    						   d = (fgetc(input_ptr));
    						   middle_names[*student_numptr][j] = d;
    						   j++;
    
    					   }while(!isspace(d));
    
    					   do{
    
    						   e = (fgetc(input_ptr));
    						   last_names[*student_numptr][k] = e;
    						   k++;
    
    					   }while(!isspace(e));
    						   
    
    
    					   fscanf(input_ptr, /*"%s "%s %s*/" %f %f %f", /*&first_names[*student_numptr], &middle_names[*student_numptr], 
    						   &last_names[*student_numptr],*/ &student_grades[*student_numptr][0], &student_grades[*student_numptr][1], 
    						   &student_grades[*student_numptr][2]);
    							
    					   final_scores[*student_numptr] = final_score_calc (student_grades, *student_numptr);
    					   grades[*student_numptr] = letter_grade (final_scores, *student_numptr);
    					   GPAs[*student_numptr] = G_P_A(grades, *student_numptr);
    
    
    					   
    					   file_counter++;
    
    					   }
    						
    					   printf("\n%d Students' record have been successfully added from %s.\n\n", file_counter, input_name);
    					   fclose(input_ptr);
    
    
    }
    
    I have commented out the way I used to do it, becuase it would mess up if there was no middle name.

    The way I am doing it now with fgetc's isn't working very well, as you can see.

    If you start the prog, press I on the menu, and input the file input.txt. There are only 5 names, but it will say 7 were inputted successfully because of the error. Then press L and you can see the list and it's problems.

    Sorry for the lengthy post and explanation, but it was needed so you could understand the problem.

    Any ideas, or tips are greatly appreciated, as this is making no sense to me. Any tips on my algorithm are also appreciated, I still have to change the getchar()'s to fgetc's, but I am working my way there.

    Thanks.

    P.S. I have attatched the input file here if you want to use it, but any file should work as long as it follows that schema.
    Last edited by Beast(); 07-06-2004 at 09:43 PM.

  2. #2
    i dont know Vicious's Avatar
    Join Date
    May 2002
    Posts
    1,200
    Just make a loop to read in the file...
    Make a variable array to hold the 3 names....
    Make a local variable to hold the data at hand....
    In crease the Name array once every loop no matter what and only assign the local variable to the name array if it does not equal a blank space.

    See what im getting at?

  3. #3
    Registered User
    Join Date
    Jun 2004
    Posts
    93
    That's pretty much what I did bro, I don't know why it's not working right.

    I got the loop, the variable array to hold the three, the local variable, the array increases, and I assign the local variable to the name array.

    But something goes wrong.

    If you go to the list, it happens about every third time, something is wrong there.

  4. #4
    Goscinny or Uderzo?
    Join Date
    Jun 2004
    Posts
    33
    Use fgets to read the input in line by line.

    Use strtok() to break the string into tokens (this will break it down into words if you use a space as the delimiter) (http://www.rt.com/man/strtok.3.html)

    If, for example, you know there should always be three grades after each persons name, then you could determine how many of the words are the names by assigning all of the tokens to temporary variables within a loop. Use the loop counter to determine how many words you have. Subtract the number of grades from the number of words giving you the number of names to be assigned (e.g. if only two words left over, don't assign a middle name or assign it as ""). Assign the various temporary variables to firstname, middlename etc. based on the results of this.

    Hope this is what you had in mind.

    p.s. Be sure to read what the link mentions about a BUG: just consider it as a warning though. Ignore the bit about "never use this".
    Last edited by Tankndozer; 07-07-2004 at 09:56 AM.

  5. #5
    End Of Line Hammer's Avatar
    Join Date
    Apr 2002
    Posts
    6,231
    >>while (!feof(input_ptr))
    Read this FAQ entry
    http://faq.cprogramming.com/cgi-bin/...&id=1043284351

    >>c = (fgetc(input_ptr));
    fgetc returns an int, so c must be an int, not a char. Read this FAQ entry
    http://faq.cprogramming.com/cgi-bin/...&id=1043284351

    You'd do much better by reading a whole line into memory (with fgets()), then parsing it there (as previously mentioned). Here's an example of the reading part, I'll leave the parsing as an excerise for you

    Code:
     #include <stdio.h>
     
     
     int main(void)
     {
       FILE *fp;
       char line[BUFSIZ];
       int counter;
       
       if ((fp = fopen("input.txt", "r")) == NULL)
       {
         perror ("input.txt");
         return 0;
       }
       
       for (counter = 1; fgets(line, sizeof(line), fp); counter++)
       {
         printf ("line %d is >%s", counter, line);
       }
       
       return(0);
     }
    When all else fails, read the instructions.
    If you're posting code, use code tags: [code] /* insert code here */ [/code]

  6. #6
    Registered User
    Join Date
    Jun 2004
    Posts
    93
    Thanks guys for the replies.

    That token idea sounds good, and is what I'm using now to parse the information. The fgets() function is definitely a better idea as well. And man, I was reading those tutorials, and was thinking "Whoever made these is pretty knowledgable," haha only to find out you're the one that made them. Pretty damn good job man.

    Anyway, I am able to use the fgets compounded with the strtok(), but I am not too sure on how to save my information to pass it into my array later on.

    Code:
    void Load ( int *student_numptr ) 
    
    {
    
    	char line[130];
    	char *delimiters = " ";
    	char *token;
    	char *firstname;
    	int i = 1;
    
    	printf("\nPlease enter input file name: ");
    				   scanf("%s", input_name);
    
    				   if ((input_ptr = fopen(input_name, "r")) == NULL )
    					   printf("\nThe file could not be opened.\n");
    
    				   else 
    					   
    		while ((fgets(line, sizeof(line), input_ptr) != NULL)		   
    
    					   {
    							
    						
    							if ( !feof(input_ptr))
    						
    							{
    								token = strtok ( line, delimiters);
    								firstname = token;
    
    								while (token != NULL)
    
    								{
    
    									token = strtok(NULL, delimiters);
    								//	tokens[i] = token;
    									i++;
    
    								}
    							}
    						
    							/*if ( i == 4 )
    							{
    								first_names[*student_numptr] = tokens[0];
    								last_names[*student_numptr] = tokens[1];
    						
    							}
    
    							if ( i == 5 )
    							{
    								first_names[*student_numptr] = tokens[0];
    								middle_names[*student_numptr] = tokens[1];
    								last_names[*student_numptr] = tokens[2];
    							
    							}
    
    							i = 1;
    							(*student_numptr)++;
    							*/
    
    						}
    
    					   fclose(input_ptr);
    
    }
    is what I have thus far. It keeps telling me left operand must be l-value when I try to assign it to the array, or that I have an error in indirection.

    I know that strtok() returns a pointer, so I can see why it might be causing an error....but what can I do about it?

    If anyone has a tip, please chime in, I'm going to be trying to figure this out.

    Thanks again Hammer and Tankndozer.
    Last edited by Beast(); 07-08-2004 at 12:20 AM.

  7. #7
    Registered User
    Join Date
    Jun 2004
    Posts
    93
    I realize now why I can't put a pointer's value into an array, because I can't change an array's address.

    But still have no clue as to how I would remove the information from strtok, and put it into my array.

  8. #8
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    I guess you should have paid attention in class eh? Dumbass. strcpy

    Quzah.
    Hope is the first step on the road to disappointment.

  9. #9
    Registered User
    Join Date
    Jun 2004
    Posts
    93
    Quote Originally Posted by quzah
    I guess you should have paid attention in class eh? Dumbass. strcpy

    Quzah.
    I was too busy being an irresponsible douche .

  10. #10
    Registered User
    Join Date
    Jun 2004
    Posts
    93
    Well, strcpy work's fine, and I now understand why I need to use it since I can't change the base address in an assignment statement.

    However there is still a problem that I am trying to figure out.

    Given the nature of strtok(), it replaces the delimiter with a null character. So when I am trying to use strcpy() to copy strings, the first character it encounters is the null character.

    This is my current code:

    Code:
    void Load ( int *student_numptr ) 
    
    {
    
    	char line[130];
    	char *delimiters = " ";
    	char *token;
    	char name[6][30];
    	double grade1, grade2, grade3;
    	
    	
    	int i = 0;
    
    	printf("\nPlease enter input file name: ");
    				   scanf("%s", input_name);
    
    				   if ((input_ptr = fopen(input_name, "r")) == NULL )
    					   printf("\nThe file could not be opened.\n");
    
    				   else 
    					   
    					   while ((fgets(line, sizeof(line), input_ptr) != NULL))
    					   {
    						
    							if ( !feof(input_ptr))
    						
    							{	
    								
    
    								token = strtok (line, delimiters);
    
    								printf("%s", token);
    							    strcpy(name[i], token);
    
    								while (token != NULL)
    
    								{
    
    									i++;
    
    									token = strtok(NULL, delimiters);
    
    									printf("%s", token);
    									//strcpy(name[i], token);
    
    								}
    							}
    						
    							/*if ( i == 4 )
    
    							{
    								strcpy(first_names[*student_numptr], name[0]);
    								strcpy(last_names[*student_numptr], name[1]);
    								//grade1 = atof(name[2]);
    								//grade2 = atof(name[3]);
    								//grade3 = atof(name[4]);
    								//student_grades[*student_numptr][0] = grade1;
    								//student_grades[*student_numptr][1] = grade2;
    								//student_grades[*student_numptr][2] = grade3;
    
    							}
    
    							if ( i == 5 )
    
    							{
    								strcpy(first_names[*student_numptr], name[0]);
    								strcpy(middle_names[*student_numptr], name[1]);
    								strcpy(last_names[*student_numptr], name[2]);
    								//grade1 = atof(name[3]);
    								//grade2 = atof(name[4]);
    								//grade3 = atof(name[5]);
    								//student_grades[*student_numptr][0] = grade1;
    								//student_grades[*student_numptr][1] = grade2;
    								//student_grades[*student_numptr][2] = grade3;
    								
    							}
    */
    							i = 0;
    							(*student_numptr)++;
    							
    
    						}
    
    					   
    
    					   fclose(input_ptr);
    
    }
    The comments are there because I was trying to figure out where the program messed up. The printf's are there because I wanted to know what token was.

    After reading that, I realized the problem with the null character. The first call of strcpy is fine because the null character is not present...but the following ones mess up.

    I am currently looking for a way to shift that null character to the end of the string, or trying to manipulate string functions in a way to make it skip the initial null character.
    Last edited by Beast(); 07-08-2004 at 12:21 AM.

  11. #11
    Registered User
    Join Date
    Jun 2004
    Posts
    93
    By the way thanks guys for the help so far, it's come a long way since my crappy isspace() stuff.

  12. #12
    Goscinny or Uderzo?
    Join Date
    Jun 2004
    Posts
    33
    First off: why are you using the !feof() call? You're already reading in the next line from your file in the while statement. There is no call to your file within that section of code, so the !feof call doesn't help. If there was no input, the while loop would never be entered.

    Secondly: what NULL character are you talking about?! It would help if we could see the output you were getting that led you to whatever conclusion you've come to- at the moment I don't know what you're talking about!
    Last edited by Tankndozer; 07-08-2004 at 02:52 AM.

  13. #13
    Registered User
    Join Date
    Jun 2004
    Posts
    93
    Quote Originally Posted by Tankndozer
    First off: why are you using the !feof() call? You're already reading in the next line from your file in the while statement. There is no call to your file within that section of code, so the !feof call doesn't help. If there was no input, the while loop would never be entered.

    Secondly: what NULL character are you talking about?! It would help if we could see the output you were getting that led you to whatever conclusion you've come to- at the moment I don't know what you're talking about!
    Ah ye thanks, I forgot to remove the !feof().

    The problem is that token holds the string, but with a null before it. Strtok() turns the delimiter into a NULL and then continues parsing the information until another delimiter is reached.

    The first call is fine because it's between (line, delimiters) in:

    Code:
    token = strtok (line, delimiters);
    
    								printf("%s", token);
    							    strcpy(name[i], token);
    But the following strings contain a NULL before they print their information.

    Code:
    while (token != NULL)
    
    								{
    
    									i++;
    
    									token = strtok(NULL, delimiters);
    
    									printf("%s", token);
    									//strcpy(name[i], token);
    
    								}
    The output, if I print out token each time, turns out to be something like this:

    I
    (null)AM
    (null)HUNGRY

    if the input file was I AM HUNGRY.

    I will fix the !feof() as soon as I get back.

    Thanks man. I tried a bunch of crap to get rid of that (null) but nothing I have tried works. There is another function which points past the null, but it doesn't work on my compiler and it is not portable at all. It's strsep() I believe.

    The only way I can think of fixing this problem with strtok() is to actually change strtok(), I'm lost as to what else to do.

    Thanks again.

  14. #14
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    Code:
    #include <stdio.h>
    #include <string.h>
    int main( void )
    {
        char array[] = "This is a test of the strtok system. This is only a test.";
        char *tok;
    
        tok = strtok( array, " " );
        while( tok != NULL )
        {
            printf("\"%s\"\n", tok );
            tok = strtok( NULL, " " );
        }
        return 0;
    }
    First figure out how to use strtok corretly, and understand what's going on, then get it working in your bigger program. Most problems can be solved the same way.

    For a learning experience, modify the above program, once you understand it, to copy each token into an array, and print it instead of the token itself.

    Quzah.
    Hope is the first step on the road to disappointment.

  15. #15
    Registered User
    Join Date
    Jun 2004
    Posts
    93
    Thanks man, I am going to have more fun with tokens than a 12 year old at an arcade.

    I see that program produces no (null), so I'm also going to check out why mine is doing so.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. gcc link external library
    By spank in forum C Programming
    Replies: 6
    Last Post: 08-08-2007, 03:44 PM
  2. Inventory records
    By jsbeckton in forum C Programming
    Replies: 23
    Last Post: 06-28-2007, 04:14 AM
  3. Basic text file encoder
    By Abda92 in forum C Programming
    Replies: 15
    Last Post: 05-22-2007, 01:19 PM
  4. Beginner Text File Input Question
    By Ruggles in forum C++ Programming
    Replies: 2
    Last Post: 11-12-2006, 02:18 PM
  5. System
    By drdroid in forum C++ Programming
    Replies: 3
    Last Post: 06-28-2002, 10:12 PM