Advertisement
Guest User

Sample demo to parse CSV text

a guest
Jun 23rd, 2010
1,664
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 7.15 KB | None | 0 0
  1. /*
  2. StudentRec.c a simple student record demo.
  3.  
  4. This program:
  5.  
  6. 1- Prints the current working directory.
  7. 2- Asks user to specify the file name containing the records of students.
  8. 3- Reads the record from the file.
  9. 4- Prints each record with statistics
  10.  
  11. Each line in the file is a none-empty comma-separated values containing a
  12. student name and three float numbers in the range [0.00, 100.0] indicating the
  13. result of three exams for each students. Example:
  14.  
  15. John Smith,71,68,92
  16. Paul Hunter,69,73,82
  17. Mary McDana,81,83,90
  18.  
  19. There are variuos constants in the program which could be altered to change the
  20. limits of the program. For example, MAX_STUDENT_RECS indicates the maximum number
  21. of strudent records which is defined to be 20. You may alter it to any desirable
  22. value from 1 to any positive valid int value.
  23.  
  24. Tested with Visual Studio .Net 2008 Standard C, Quincy 2005 and Dev C/C++ 4.9
  25.  
  26. */
  27.  
  28. #include <stdio.h>
  29. #include <stdlib.h>
  30. #include <direct.h>
  31. #include <string.h>
  32.  
  33. /*
  34. The size of buffers to hold directory path.
  35. (The maximum number of characters allowed for a directory (folder) path
  36. */
  37. #define  MAX_PATH_LENGTH    2048
  38.  
  39. /*
  40. The maximum length of file name.
  41. */
  42. #define  MAX_FILENAME_LENGTH    256
  43.  
  44. /*
  45. The maximum length of each record line.
  46. */
  47. #define  MAX_LINE_LENGTH    256
  48.  
  49. /*
  50. The maximum number of student records.
  51. */
  52. #define  MAX_STUDENT_RECS   20
  53.  
  54. /*
  55. A constant used as null character. The char representation, ' \ 0 '
  56. has an issue when published in a blog, causeing the code to produce
  57. compile error.
  58. */
  59. const char NULL_CHAR = (char) 0;
  60.  
  61. /*
  62. A struct record definition. Each student record will be saved in one
  63. variable of student_rec type. (Actually an array of this).
  64. */
  65. struct student_rec
  66. {
  67.     /* The name of student */
  68.    char   name [MAX_LINE_LENGTH];
  69.    float  exam1;    /* the result of exam1 */
  70.    float  exam2;    /* the result of exam2 */
  71.    float  exam3;    /* the result of exam3 */
  72. };
  73.  
  74. /*
  75. The array holding all the student records.
  76. */
  77. struct student_rec records [MAX_STUDENT_RECS];
  78.  
  79. /*
  80. The main program. We have not used the command-line arguments in this demo.
  81. */
  82. int main(int argc, char *argv[])
  83. {
  84.     /* A buffer to hold the current working directory. */
  85.    char buffer [MAX_PATH_LENGTH];
  86.  
  87.    /* The string to hold the filename of record file. */
  88.    char filename [MAX_FILENAME_LENGTH];
  89.  
  90.    /* The String to hold each record line in loop. */
  91.    char line [MAX_LINE_LENGTH];
  92.    
  93.    /* A string to hold the caption for record statistics. */
  94.    char stat [MAX_FILENAME_LENGTH];
  95.  
  96.    /* used to trim the new-line characters off the line. */
  97.    int len;
  98.  
  99.    /* The file interface to work with record file. */
  100.    FILE* fp;
  101.  
  102.    /* a pointer to tokenize each record field. */
  103.    char *pTok;
  104.  
  105.    /* The primary delimiter list to tokenize the fields of each record. */
  106.    const char *delim = ",";
  107.  
  108.    /* The alternative delimiter list to tokenize the fields of each record. */
  109.    /* (used for last token/field). */
  110.    const char *delimLast = "\r\n";
  111.  
  112.    /* variables to hold the sums of each exams results. */
  113.    float exam1, exam2, exam3;
  114.    
  115.    /* count : the total number of student records. */
  116.    /* n : misc for loop variable. */
  117.    int count, n;
  118.  
  119.  
  120.    /* gets the current working directory, and prints it. */
  121.   _getcwd(buffer, MAX_PATH_LENGTH);
  122.   printf ("Current Working Directory: %s\n", buffer);
  123.  
  124.   /* reads the file name from keyboard. */
  125.   printf ("Enter File name: ");
  126.   fgets(filename, MAX_FILENAME_LENGTH - 1, stdin);
  127.  
  128.     /* trims the appnded new-line at the end. */
  129.   len = strlen (filename);
  130.   if (filename [len - 1] == '\n')
  131.      filename [len - 1] = NULL_CHAR;
  132.      
  133.   /* echo back the read file name. */
  134.   printf ("Filename: %s\n", filename);
  135.  
  136.   /* opens the record file: */
  137.   if ((fp = fopen (filename, "r")) == NULL)
  138.   {
  139.       /* prints the error in std error device if failed. */
  140.      fprintf (stderr, "*** Cannot open file %s for input.\n", filename);
  141.      system ("PAUSE");
  142.      return 1;  /* exits with error status 1 */
  143.   }
  144.  
  145.   /* reads all the records up to a maximum number. */
  146.   for (count = 0; count < MAX_STUDENT_RECS; )
  147.   {
  148.       /* reads the next line; if no more lines, breaks. */
  149.      if (fgets (line, MAX_LINE_LENGTH - 1, fp) == NULL)
  150.         break;
  151.        
  152.      /* obtins the first token/field (name) */
  153.      pTok = strtok (line, delim);
  154.      
  155.      /* If no token, continues (reading next line) */
  156.      if (pTok == NULL || *pTok == NULL_CHAR || *pTok == '\n')
  157.         continue;
  158.        
  159.      /* if a record, copies the first field/token into name field of the
  160.         next student record */
  161.      /* element in array. */
  162.      strcpy (records [count].name, pTok);
  163.  
  164.      /* obtain the next token/field (exam1) */
  165.      pTok = strtok(NULL, delim);
  166.  
  167.      /* It shouldn't be a null or empty record. */
  168.      if (pTok == NULL || *pTok == NULL_CHAR || *pTok == '\n')
  169.      {
  170.          /* If it is, skips this line with a warning. */
  171.         fprintf (stderr, "*** Warning! Skipping invalid record; name : %s\n",
  172.             records [count].name);
  173.         continue;
  174.      }    
  175.      
  176.      /* converts exam1 to a float number and save it in record element. */
  177.      records [count].exam1 = atof (pTok);
  178.      
  179.      /* obtain the next token/field (exam2) */
  180.      pTok = strtok(NULL, delim);
  181.  
  182.      /* It shouldn't be a null or empty record. */
  183.      if (pTok == NULL || *pTok == NULL_CHAR || *pTok == '\n')
  184.      {
  185.          /* If it is, skips this line with a warning. */
  186.         fprintf (stderr, "*** Warning! Skipping invalid record; name : %s\n",
  187.             records [count].name);
  188.         continue;
  189.      }    
  190.      
  191.      /* converts exam2 to a float number and save it in record element. */
  192.      records [count].exam2 = atof (pTok);
  193.      
  194.      /* obtain the final token/field (exam3) */
  195.      pTok = strtok(NULL, delimLast);
  196.  
  197.      /* It shouldn't be a null or empty record. */
  198.      if (pTok == NULL || *pTok == NULL_CHAR || *pTok == '\n')
  199.      {
  200.          /* If it is, skips this line with a warning. */
  201.         fprintf (stderr, "*** Warning! Skipping invalid record; name : %s\n",
  202.             records [count].name);
  203.         continue;
  204.      }    
  205.      
  206.      /* converts exam3 to a float number and save it in record element. */
  207.      records [count].exam3 = atof (pTok);
  208.        
  209.      /* because all lines may not be a valid record,
  210.      we increment count here, not in for loop. */
  211.      count++;
  212.   }
  213.  
  214.   /* Now, displaying the records, and accumulating the results exam by
  215.   exam for all students: */
  216.  
  217.   /* Initially, all 0. */
  218.   exam1 = exam2 = exam3 = 0.0f;
  219.  
  220.     /* Displaying all records */
  221.   for (n = 0; n < count; n++)
  222.   {
  223.       printf ("%30s\t%6.2f\t%6.2f\t%6.2f\t%6.2f\n", records [n].name,
  224.           records [n].exam1, records [n].exam2, records [n].exam3,
  225.              (records [n].exam1 + records [n].exam2 + records [n].exam3) / 3.0f);
  226.              
  227.       /* summing up results. */
  228.       exam1 += records [n].exam1;
  229.       exam2 += records [n].exam2;
  230.       exam3 += records [n].exam3;
  231.   }
  232.  
  233.   /* prints the stat. */
  234.   sprintf(stat, "%d records, Average:", count);
  235.   printf ("%30s\t%6.2f\t%6.2f\t%6.2f\n", stat, exam1 / (float) count,
  236.       exam2 / (float) count, exam3 / (float) count);
  237.  
  238.    system ("PAUSE");
  239.    return 0; /* exist with status OK. */
  240. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement