Efficiency of code used to read and write a delimited file

Please support our C++ advertiser: Programming Forums - DaniWeb Sister Site
Reply

Join Date: Dec 2008
Posts: 13
Reputation: 1bennyd is an unknown quantity at this point 
Solved Threads: 1
1bennyd 1bennyd is offline Offline
Newbie Poster

Efficiency of code used to read and write a delimited file

 
0
  #1
Jan 17th, 2009
Hi guys, I have written some C++ code to do three things:

1. Read data from a delimited file (user specifies type of delimiter used), and return data as a "2D array".
2. Print 2D array to console.
3. Write the 2D array to a tab delimited text file.

I have also had a go at introducing some error handling.

Since I am a bit of a newbie to C++, I just wanted to know if there were any improvements I could make to increase efficiency. Any help would be very appreciated.

  1. // Reads data from a delimited file.
  2. // Data is returned as a 2D array.
  3. // The 2D array is saved to file and printed to console.
  4.  
  5. #include <string>
  6. #include <vector>
  7. #include <iostream>
  8. #include <fstream>
  9. #include <sstream>
  10. #include <cmath>
  11. #include <cstdlib>
  12. using namespace std;
  13.  
  14. float** ReadTable(const char* FileName_Read, const char delimiter,
  15. int& RowNum, int& ColNum) {
  16.  
  17. string line;
  18. ifstream in(FileName_Read);
  19.  
  20. // Determine number of rows and columns in file.
  21. // Program halts if rows are not of same length.
  22. while(getline(in,line,'\n')) {
  23. string entry;
  24. int EntriesPerRow = 0; // Initialize counter.
  25. stringstream ss;
  26. ss << line;
  27. while (getline(ss,entry,delimiter)) {
  28. EntriesPerRow++;
  29. }
  30. if (RowNum == 0) {
  31. // Define number of columns in file as the number
  32. // of entries in the first row.
  33. ColNum = EntriesPerRow;
  34. } else {
  35. if (EntriesPerRow != ColNum) {
  36. cerr << "Row " << RowNum << " is not the same length "
  37. "as row 0." << endl;
  38. exit(0);
  39. }
  40. }
  41. RowNum++;
  42. }
  43.  
  44. // Declare arrays for storing and accessing
  45. // data from the file.
  46. float** pa2d = new float*[RowNum];
  47. float* parr = new float[RowNum*ColNum];
  48.  
  49. // Reposition to start of stream buffer.
  50. in.clear();
  51. in.seekg(0, ios::beg);
  52.  
  53. int k = 0; // Initialize counter
  54.  
  55. // Read each entry into 1D array.
  56. while(getline(in,line,'\n')) {
  57.  
  58. // Declarations.
  59. stringstream ss;
  60. ss << line;
  61. string entry;
  62.  
  63. while (getline(ss,entry,delimiter)) {
  64.  
  65. // Declarations.
  66. stringstream entry_ss;
  67. float entry_float;
  68. char entry_char;
  69.  
  70. // Insert data entry into stringstream.
  71. entry_ss << entry;
  72.  
  73. // Convert data entry to float.
  74. entry_ss >> entry_float;
  75.  
  76. if (!entry_ss) {
  77. // Check if stream is in error state.
  78. // Halt program if it is.
  79. float r = floor(k/ColNum); float c = k - (r*ColNum);
  80. // (Convert 1D array position to 2D array position.)
  81. cerr << "Bad input: Entry [" << r << "," << c
  82. << "] put stream into error state." << endl;
  83. exit(0);
  84. } else {
  85. if (entry_ss >> entry_char) {
  86. // The attempt to extract a character is a test
  87. // to see if there is anything left in the stream
  88. // after we extract a float. Program is halted if
  89. // if a non-numeric entry is found.
  90. float r = floor(k/ColNum); float c = k - (r*ColNum);
  91. // (Convert 1D array position to 2D array position.)
  92. cerr << "Bad input: Entry [" << r << "," << c
  93. << "] is not numeric." << endl;
  94. exit(0);
  95. } else {
  96. // Everything is OK, build array.
  97. parr[k] = entry_float;
  98. }
  99. }
  100. k++;
  101. }
  102. }
  103. in.close();
  104.  
  105. // Prepare 2D array to be returned.
  106. // Define pointer position at start of each row.
  107. for (int i = 0; i < RowNum; i++) {
  108. pa2d[i] = parr + (i*ColNum);
  109. }
  110.  
  111. return pa2d;
  112. }
  113.  
  114. void PrintMatrix(float** matrix, const int RowNum, const int ColNum) {
  115. // Print "matrix" to console.
  116. cout << '\n';
  117. for (int i=0; i < RowNum; i++) {
  118. for(int j=0; j < ColNum; j++) {
  119. cout << (j?"\t":"") << matrix[i][j];
  120. // Don't insert tab before first element of each row.
  121. }
  122. cout << '\n';
  123. }
  124. }
  125.  
  126. void WriteTable(const char* FileName_Write, float** matrix,
  127. const int RowNum, const int ColNum) {
  128. // Write "matrix" to delimited file.
  129. // Code is very similar to PrintMatrix
  130. ofstream out(FileName_Write);
  131. for (int i=0; i < RowNum; i++) {
  132. for(int j=0; j < ColNum; j++) {
  133. out << (j?"\t":"") << matrix[i][j];
  134. // Don't insert delimiter before first element of each row.
  135. }
  136. out << '\n';
  137. }
  138. out.close();
  139. }
  140.  
  141. int main() {
  142.  
  143. // Define filenames.
  144. const char* FileName_Read = "floats.txt";
  145. const char* FileName_Write = "write.txt";
  146.  
  147. // Initialize row and column counters.
  148. int RowNum = 0; int ColNum = 0;
  149.  
  150. // Define delimiter.
  151. const char delimiter = '\t';
  152.  
  153. // Perform reading of data file into 2D array.
  154. float** data = ReadTable(FileName_Read,delimiter,RowNum,ColNum);
  155.  
  156. // Print contents of 2D array to console.
  157. PrintMatrix(data,RowNum,ColNum);
  158.  
  159. // Write 2D array to delimited file.
  160. WriteTable(FileName_Write,data,RowNum,ColNum);
  161.  
  162. return(0);
  163.  
  164. }
A proud member of R-forum.org - A community that provides help to users of statistics and the R programming language.
Reply With Quote Quick reply to this message  
Join Date: Dec 2008
Posts: 14
Reputation: d0pedup is an unknown quantity at this point 
Solved Threads: 0
d0pedup d0pedup is offline Offline
Newbie Poster

Re: Efficiency of code used to read and write a delimited file

 
0
  #2
Jan 19th, 2009
I didn't read your code but from what i have gathered you want to create a Database like operation.
For varying width operations why don't you go for a solution on similar lines
<row>
<field1>
XXXXXXXXX
</field1>
<field2>
XXXX
</field2>
</row>
<field1>
...

keep in mind this is just a suggestion and i don't know if you have already implemented a solution on similar lines.
Last edited by d0pedup; Jan 19th, 2009 at 6:24 am.
Reply With Quote Quick reply to this message  
Reply

This thread is more than three months old.
Perhaps start a new thread instead?
Message:



Other Threads in the C++ Forum


Views: 1329 | Replies: 1
Thread Tools Search this Thread



Tag cloud for C++
About Us | Contact Us | Advertise | DaniWeb | Acceptable Use Policy | RSS Feed

©2003 - 2009 DaniWeb® LLC