943,553 Members | Top Members by Rank

Ad:
  • C++ Discussion Thread
  • Unsolved
  • Views: 2299
  • C++ RSS
Jan 17th, 2009
0

Efficiency of code used to read and write a delimited file

Expand Post »
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.

cpp Syntax (Toggle Plain Text)
  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. }
Reputation Points: 12
Solved Threads: 1
Newbie Poster
1bennyd is offline Offline
13 posts
since Dec 2008
Jan 19th, 2009
0

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

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.
Reputation Points: 10
Solved Threads: 0
Newbie Poster
d0pedup is offline Offline
14 posts
since Dec 2008

This thread is more than three months old

No one has posted to this discussion for at least three months. Please let old threads die and do not reply to them unless you feel you have something new and valuable to contribute that absolutely must be added to make the discussion complete. Otherwise, please start a new thread in this forum instead.
Message:
Previous Thread in C++ Forum Timeline: doubt in mfc....very urgent!!!!!!!
Next Thread in C++ Forum Timeline: Help decoding line of typedef/struct combo





About Us | Contact Us | Advertise | Acceptable Use Policy
Forum Index | Build Custom RSS Feed


Follow us on Twitter


© 2011 DaniWeb® LLC