Dynamic Array, Writing to CSV, Floating Point ?'s

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

Join Date: Apr 2004
Posts: 4,364
Reputation: Dave Sinkula has a brilliant future Dave Sinkula has a brilliant future Dave Sinkula has a brilliant future Dave Sinkula has a brilliant future Dave Sinkula has a brilliant future Dave Sinkula has a brilliant future Dave Sinkula has a brilliant future Dave Sinkula has a brilliant future Dave Sinkula has a brilliant future Dave Sinkula has a brilliant future Dave Sinkula has a brilliant future 
Solved Threads: 242
Team Colleague
Dave Sinkula's Avatar
Dave Sinkula Dave Sinkula is offline Offline
long time no c

Re: Dynamic Array, Writing to CSV, Floating Point ?'s

 
0
  #11
Aug 5th, 2005
Then vectors may be more suitable. But this is how I might have adapted things if I would have chosen C.
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3.  
  4. struct sRecord
  5. {
  6. int date, time;
  7. double price[4], volume;
  8. };
  9.  
  10. int main(void)
  11. {
  12. static const char filename[] = "file.csv";
  13. FILE *file = fopen(filename, "r");
  14. if ( file )
  15. {
  16. size_t i = 0, size = 100000;
  17. struct sRecord *array = malloc(size * sizeof *array);
  18. if ( array )
  19. {
  20. char line[128];
  21. while ( i < size && fgets(line, sizeof line, file) )
  22. {
  23. if ( sscanf(line, "%d,%d,%lf,%lf,%lf,%lf,%lf",
  24. &array[i].date, &array[i].time,
  25. &array[i].price[0], &array[i].price[1],
  26. &array[i].price[2], &array[i].price[3],
  27. &array[i].volume) == 7 )
  28. {
  29. ++i;
  30. }
  31. }
  32. fclose(file);
  33. /*
  34.   * [Modify contents]
  35.   */
  36. for ( size = i, i = 0; i < size; ++i )
  37. {
  38. printf("%d,%d,%g,%g,%g,%g,%g\n", array[i].date, array[i].time,
  39. array[i].price[0], array[i].price[1], array[i].price[2],
  40. array[i].price[3], array[i].volume);
  41. }
  42. free(array);
  43. }
  44. }
  45. else
  46. {
  47. perror(filename);
  48. }
  49. return 0;
  50. }
"One of the methods used by statists to destroy capitalism consists in establishing controls that tie a given industry hand and foot, making it unable to solve its problems, then declaring that freedom has failed and stronger controls are necessary." --Ayn Rand
Reply With Quote Quick reply to this message  
Join Date: Jul 2005
Posts: 1,688
Reputation: Lerner is a name known to all Lerner is a name known to all Lerner is a name known to all Lerner is a name known to all Lerner is a name known to all Lerner is a name known to all 
Solved Threads: 265
Lerner Lerner is offline Offline
Posting Virtuoso

Re: Dynamic Array, Writing to CSV, Floating Point ?'s

 
0
  #12
Aug 5th, 2005
I'll try to enter gently (into the conversation of others), but I believe the process could be demonstrated something like this using C++:

//variables to write to file
int date = 10;
char month[12] = "June";
float first = 1.011;
float second = 2005.2;

//using C++ style file I/O
ofstream fout("sample.txt");
fout << date << ',' << month << ',' << first << ',' << second;

sample.txt should now be in CSV format.

To read in from file would be:

ifstream fin("sample.txt");
//use different variables to confirm that things read back in correctly.
int date_;
char month_[12];
float first_;
float second_;
char dummy;

fin >> date_ >> dummy >> month_ >> dummy >> first_ >> dummy >> second_;

I agree with Dave Sinkula, that this sounds like a good project to use struct/class with and overload the << for the struct if you have that option available.

I don't have access to a compiler to confirm my code sample, sorry.
Reply With Quote Quick reply to this message  
Join Date: Apr 2004
Posts: 4,364
Reputation: Dave Sinkula has a brilliant future Dave Sinkula has a brilliant future Dave Sinkula has a brilliant future Dave Sinkula has a brilliant future Dave Sinkula has a brilliant future Dave Sinkula has a brilliant future Dave Sinkula has a brilliant future Dave Sinkula has a brilliant future Dave Sinkula has a brilliant future Dave Sinkula has a brilliant future Dave Sinkula has a brilliant future 
Solved Threads: 242
Team Colleague
Dave Sinkula's Avatar
Dave Sinkula Dave Sinkula is offline Offline
long time no c

Re: Dynamic Array, Writing to CSV, Floating Point ?'s

 
0
  #13
Aug 5th, 2005
In C++ I might write it something like this (for starters).
  1. #include <iostream>
  2. #include <fstream>
  3. #include <string>
  4. #include <vector>
  5. #include <algorithm>
  6. #include <iterator>
  7. #include <cstdio>
  8.  
  9. struct sRecord
  10. {
  11. int date, time;
  12. double price[4], volume;
  13. };
  14.  
  15. bool operator< (const struct sRecord &a, const struct sRecord &b)
  16. {
  17. return a.date < b.date;
  18. }
  19.  
  20. std::ostream& operator<< (std::ostream &o, struct sRecord &r)
  21. {
  22. o << r.date << "," << r.time << "," << r.price[0] << "," << r.price[1] << ","
  23. << r.price[2] << "," << r.price[3] << "," << r.volume;
  24. return o;
  25. }
  26.  
  27. int main(void)
  28. {
  29. std::vector<sRecord> record;
  30. const std::string filename("file.csv");
  31. std::ifstream file(filename.c_str());
  32. if ( file )
  33. {
  34. std::string line;
  35. while ( file >> line )
  36. {
  37. sRecord data;
  38. if ( std::sscanf(line.c_str(), "%d,%d,%lf,%lf,%lf,%lf,%lf",
  39. &data.date, &data.time, &data.price[0], &data.price[1],
  40. &data.price[2], &data.price[3], &data.volume) == 7 )
  41. {
  42. record.push_back(data);
  43. }
  44. }
  45. }
  46. /*
  47.   * [Modify contents]
  48.   */
  49. std::sort(record.begin(), record.end());
  50. std::copy(record.begin(), record.end(),
  51. std::ostream_iterator<sRecord>(std::cout, "\n"));
  52. return 0;
  53. }
[D'oh. Pokey on the C++ conversion.]
"One of the methods used by statists to destroy capitalism consists in establishing controls that tie a given industry hand and foot, making it unable to solve its problems, then declaring that freedom has failed and stronger controls are necessary." --Ayn Rand
Reply With Quote Quick reply to this message  
Join Date: Jun 2005
Posts: 12
Reputation: NolanVW is an unknown quantity at this point 
Solved Threads: 0
NolanVW NolanVW is offline Offline
Newbie Poster

Re: Dynamic Array, Writing to CSV, Floating Point ?'s

 
0
  #14
Aug 5th, 2005
Alright, just so you get an idea of where I'm at...I'm putting in red any of the lines that I don't understand. At this point I'm going to just sit here and study this code and try and get to the point where I can walk through it.

One question, the program isn't outputting anything? Is there something missing?


Originally Posted by Dave Sinkula
Then vectors may be more suitable. But this is how I might have adapted things if I would have chosen C.
#include <stdio.h>
#include <stdlib.h>

struct sRecord
{
   int    date, time;
   double price[4], volume;
};

int main(void)
{
   static const char filename[] = "file.csv";
   FILE *file = fopen(filename, "r");
   if ( file )
   {
      size_t i = 0, size = 100000;
      struct sRecord *array = malloc(size * sizeof *array);  
      if ( array )
      {
         char line[128];
         while ( i < size && fgets(line, sizeof line, file) )
         {
            if ( sscanf(line, "%d,%d,%lf,%lf,%lf,%lf,%lf",
                        &array[i].date, &array[i].time,
                        &array[i].price[0], &array[i].price[1],
                        &array[i].price[2], &array[i].price[3],
                        &array[i].volume) == 7 )
            {
               ++i;
            }
         }
         fclose(file);
         /*
          * [Modify contents]
          */
         for ( size = i, i = 0; i < size; ++i )
         {
            printf("%d,%d,%g,%g,%g,%g,%g\n", array[i].date, array[i].time,
                   array[i].price[0], array[i].price[1], array[i].price[2],
                   array[i].price[3], array[i].volume);
         }
         free(array);
      }
   }
   else
   {
      perror(filename);
   }
   return 0;
}
Reply With Quote Quick reply to this message  
Join Date: Apr 2004
Posts: 4,364
Reputation: Dave Sinkula has a brilliant future Dave Sinkula has a brilliant future Dave Sinkula has a brilliant future Dave Sinkula has a brilliant future Dave Sinkula has a brilliant future Dave Sinkula has a brilliant future Dave Sinkula has a brilliant future Dave Sinkula has a brilliant future Dave Sinkula has a brilliant future Dave Sinkula has a brilliant future Dave Sinkula has a brilliant future 
Solved Threads: 242
Team Colleague
Dave Sinkula's Avatar
Dave Sinkula Dave Sinkula is offline Offline
long time no c

Re: Dynamic Array, Writing to CSV, Floating Point ?'s

 
0
  #15
Aug 5th, 2005
Declare a pointer and attempt to allocate memory to contain an array of these structures, assigning the result of the attempt to the pointer:
  1. struct sRecord *array = malloc(size * sizeof *array);
A buffer into which to read a line of data:
  1. char line[128];
Read a line of data:
while ( i < size && fgets(line, sizeof line, file) )
Originally Posted by NolanVW
One question, the program isn't outputting anything? Is there something missing?
Sprinkle some debugging printfs around.
"One of the methods used by statists to destroy capitalism consists in establishing controls that tie a given industry hand and foot, making it unable to solve its problems, then declaring that freedom has failed and stronger controls are necessary." --Ayn Rand
Reply With Quote Quick reply to this message  
Join Date: Jul 2005
Posts: 1,688
Reputation: Lerner is a name known to all Lerner is a name known to all Lerner is a name known to all Lerner is a name known to all Lerner is a name known to all Lerner is a name known to all 
Solved Threads: 265
Lerner Lerner is offline Offline
Posting Virtuoso

Re: Dynamic Array, Writing to CSV, Floating Point ?'s

 
0
  #16
Aug 5th, 2005
Darn it, reading CSV files directly into numerical values using C++ is going to take more using >> directly. Using >> to read from a CSV will consider the comma to be part of a string, not a delimiter; and for numerical value it will fill the initial variable, but since commas are not valid in int/float/double variables, the input will stop and the fail bit of the input stream is likely to be flipped when the delimiting comma is found. This in turn will invalidate the input stream until it is cleared, which would be very cumbersome to do after each input into a numerical value. I should have realized that initially, sorry.

Instead I think it would be best to read each piece of information between delimiting commas into strings using get() or getline() using ',' as the terminating char (I'd probably use getline() so it would remove the terminating comma from the input buffer when it was encountered without an additional step like using get() would require). Then since the fields would be known in advance, I'd convert the necessary strings to int/double/float whatever after the read in. Messy, but doable.

Seems like the OP is leaning toward C style rather than C++ so it's probably moot, except as (imperfect initial) demonstration.

EDIT:
Are comma separated files routinely divided into lines or is everything data comma data comma data comma until EOF without newline separation, or is either way appropriate?

I don't use C style I/O routinely, so how will sscanf() handle the comma delimiters--remove them from the string so they don't muddle up things automatically or do users have to account for them?
Reply With Quote Quick reply to this message  
Join Date: Jun 2005
Posts: 12
Reputation: NolanVW is an unknown quantity at this point 
Solved Threads: 0
NolanVW NolanVW is offline Offline
Newbie Poster

Re: Dynamic Array, Writing to CSV, Floating Point ?'s

 
0
  #17
Aug 9th, 2005
Okay...so here's where it's at:

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3.  
  4. struct sRecord
  5. {
  6. int date, volume;
  7. char time;
  8. double price[4];
  9. };
  10.  
  11. int main(void)
  12. {
  13. static const char filename[] = "file.csv";
  14. FILE *file = fopen(filename, "r");
  15.  
  16. printf("file opened\n");
  17. system("pause");
  18.  
  19. if ( file )
  20. {
  21. size_t i = 0, size = 30;
  22. struct sRecord *array = malloc(size * sizeof *array);
  23.  
  24. printf("assigned memory to array address\n");
  25. system("pause");
  26.  
  27. if ( array )
  28. {
  29. char line[128];
  30.  
  31. printf("entering While loop\n");
  32. system("pause");
  33.  
  34. while ( i < size && fgets(line, sizeof line, file) )
  35. {
  36. if ( sscanf(line, "%d,%c,%lf,%lf,%lf,%lf,%ld",
  37. &array[i].date, &array[i].time,
  38. &array[i].price[0], &array[i].price[1],
  39. &array[i].price[2], &array[i].price[3],
  40. &array[i].volume) == 7 )
  41. {
  42. ++i;
  43. }
  44.  
  45. }
  46.  
  47. printf("leaving While loop\n");
  48. system("pause");
  49.  
  50. fclose(file);
  51.  
  52. printf("Closed File\n");
  53. system("pause");
  54.  
  55. /* Test first three rows of Array */
  56.  
  57. printf("%d,%c,%lf,%lf,%lf,%lf,%ld\n", array[0].date, array[0].time,
  58. array[0].price[0], array[0].price[1], array[0].price[2],
  59. array[0].price[3], array[0].volume);
  60.  
  61. printf("\n");
  62.  
  63. printf("%d,%c,%lf,%lf,%lf,%lf,%ld\n", array[1].date, array[1].time,
  64. array[1].price[0], array[1].price[1], array[1].price[2],
  65. array[1].price[3], array[1].volume);
  66.  
  67. printf("\n");
  68.  
  69. printf("%d,%c,%lf,%lf,%lf,%lf,%ld\n", array[2].date, array[2].time,
  70. array[2].price[0], array[2].price[1], array[2].price[2],
  71. array[2].price[3], array[2].volume);
  72.  
  73. printf("Test Row\n");
  74. system("pause");
  75.  
  76. /*
  77.   * [Modify contents]
  78.   */
  79.  
  80. for ( i = 0; i < size; ++i )
  81. {
  82. printf("%d,%c,%lf,%lf,%lf,%lf,%ld\n", array[i].date, array[i].time,
  83. array[i].price[0], array[i].price[1], array[i].price[2],
  84. array[i].price[3], array[i].volume);
  85. }
  86.  
  87. printf("File printed\n");
  88. system("pause");
  89.  
  90. free(array);
  91. }
  92. }
  93. else
  94. {
  95. perror(filename);
  96. }
  97.  
  98. system("pause");
  99.  
  100. return 0;
  101.  
  102. }


Here's the test data:

20041201,0:00,102.74,102.77,102.74,102.76,5
20041201,0:05,102.78,102.78,102.75,102.75,3
20041201,0:10,102.75,102.75,102.7,102.7,7
20041201,0:15,102.7,102.72,102.7,102.72,8
20041201,0:20,102.73,102.74,102.73,102.74,2
20041201,0:25,102.73,102.73,102.7,102.7,4
20041201,0:30,102.71,102.71,102.68,102.7,10
20041201,0:35,102.71,102.73,102.68,102.69,15
20041201,0:40,102.7,102.71,102.69,102.71,12
20041201,0:45,102.71,102.73,102.71,102.73,2
20041201,0:50,102.74,102.78,102.74,102.77,12
20041201,0:55,102.77,102.8,102.77,102.79,17


Here's the output:

file opened
Press any key to continue . . .
assigned memory to array address
Press any key to continue . . .
entering While loop
Press any key to continue . . .
leaving While loop
Press any key to continue . . .
Closed File
Press any key to continue . . .
20041201,0,0.000000,0.000000,0.000000,0.000000,3998072

0, ,0.000000,0.000000,0.000000,0.000000,0

0, ,0.000000,0.000000,0.000000,0.000000,0
Test Row
Press any key to continue . . .
20041201,0,0.000000,0.000000,0.000000,0.000000,3998072
0, ,0.000000,0.000000,0.000000,0.000000,0
0, ,0.000000,0.000000,0.000000,0.000000,0
0, ,0.000000,0.000000,0.000000,0.000000,0
0, ,0.000000,0.000000,0.000000,0.000000,0
0, ,0.000000,0.000000,0.000000,0.000000,0
0, ,0.000000,0.000000,0.000000,0.000000,0
0, ,0.000000,0.000000,0.000000,0.000000,0
0, ,0.000000,0.000000,0.000000,0.000000,0
0, ,0.000000,0.000000,0.000000,0.000000,0
0, ,0.000000,0.000000,0.000000,0.000000,0
0, ,0.000000,0.000000,0.000000,0.000000,0
0, ,0.000000,0.000000,0.000000,0.000000,0
0, ,0.000000,0.000000,0.000000,0.000000,0
0, ,0.000000,0.000000,0.000000,0.000000,0
0, ,0.000000,0.000000,0.000000,0.000000,0
0, ,0.000000,0.000000,0.000000,0.000000,0
0, ,0.000000,0.000000,0.000000,0.000000,0
0, ,0.000000,0.000000,0.000000,0.000000,0
0, ,0.000000,0.000000,0.000000,0.000000,0
0, ,0.000000,0.000000,0.000000,0.000000,0
0, ,0.000000,0.000000,0.000000,0.000000,0
0, ,0.000000,0.000000,0.000000,0.000000,0
0, ,0.000000,0.000000,0.000000,0.000000,0
0, ,0.000000,0.000000,0.000000,0.000000,0
0, ,0.000000,0.000000,0.000000,0.000000,0
0, ,0.000000,0.000000,0.000000,0.000000,0
0, ,0.000000,0.000000,0.000000,0.000000,0
0, ,0.000000,0.000000,0.000000,0.000000,0
0, ,0.000000,0.000000,0.000000,0.000000,0
File printed
Press any key to continue . . .

My Questions:

1) How is malloc supposed to provide the correct amount of memory if it doesn't even know what's stored in array[] yet? Doesn't array[] get filled in the loop below the allocation statement? So it won't know the size until then?

2) The program is only printing the correct first date in the list and then prints 0's for everything else...anyone see a reason?

Thanks for the help,

Nolan
Reply With Quote Quick reply to this message  
Join Date: Jun 2005
Posts: 12
Reputation: NolanVW is an unknown quantity at this point 
Solved Threads: 0
NolanVW NolanVW is offline Offline
Newbie Poster

Re: Dynamic Array, Writing to CSV, Floating Point ?'s

 
0
  #18
Aug 9th, 2005
and what the heck is the "3998072" from?
Reply With Quote Quick reply to this message  
Join Date: Apr 2004
Posts: 4,364
Reputation: Dave Sinkula has a brilliant future Dave Sinkula has a brilliant future Dave Sinkula has a brilliant future Dave Sinkula has a brilliant future Dave Sinkula has a brilliant future Dave Sinkula has a brilliant future Dave Sinkula has a brilliant future Dave Sinkula has a brilliant future Dave Sinkula has a brilliant future Dave Sinkula has a brilliant future Dave Sinkula has a brilliant future 
Solved Threads: 242
Team Colleague
Dave Sinkula's Avatar
Dave Sinkula Dave Sinkula is offline Offline
long time no c

Re: Dynamic Array, Writing to CSV, Floating Point ?'s

 
0
  #19
Aug 9th, 2005
Originally Posted by NolanVW
1) How is malloc supposed to provide the correct amount of memory if it doesn't even know what's stored in array[] yet?
This is one of the reasons I chose a vector instead.

Originally Posted by NolanVW
2) The program is only printing the correct first date in the list and then prints 0's for everything else...anyone see a reason?
You're really not checking to see if data was successfully read. For example, "0:00" is not a single character.

[edit]Maybe I'll edit again to highlight some of the differences.
#include <stdio.h>
#include <stdlib.h>

struct sRecord
{
   int    date, volume;
   char   time[8];
   double price[4];
};

int main(void)
{
   static const char filename[] = "file.csv";
   FILE *file = fopen(filename, "r");
   if ( file )
   {
      size_t i = 0, count, size = 30;
      struct sRecord *array = malloc(size * sizeof *array);
      if ( array )
      {
         char line[128];
         while ( i < size && fgets(line, sizeof line, file) )
         {
            if ( sscanf(line, "%d,%7[^,],%lf,%lf,%lf,%lf,%d",
                        &array[i].date, array[i].time,
                        &array[i].price[0], &array[i].price[1],
                        &array[i].price[2], &array[i].price[3],
                        &array[i].volume) == 7 )
            {
               ++i;
            }
         }
         fclose(file);
         /*
          * [Modify contents]
          */
         for ( count = i, i = 0; i < count; ++i )
         {
            printf("%d,%s,%f,%f,%f,%f,%d\n", array[i].date, array[i].time,
                   array[i].price[0], array[i].price[1], array[i].price[2],
                   array[i].price[3], array[i].volume);
         }
         free(array);
      }
   }
   else
   {
      perror(filename);
   }
   return 0;
}

/* file.csv
20041201,0:00,102.74,102.77,102.74,102.76,5
20041201,0:05,102.78,102.78,102.75,102.75,3
20041201,0:10,102.75,102.75,102.7,102.7,7
20041201,0:15,102.7,102.72,102.7,102.72,8
20041201,0:20,102.73,102.74,102.73,102.74,2
20041201,0:25,102.73,102.73,102.7,102.7,4
20041201,0:30,102.71,102.71,102.68,102.7,10
20041201,0:35,102.71,102.73,102.68,102.69,15
20041201,0:40,102.7,102.71,102.69,102.71,12
20041201,0:45,102.71,102.73,102.71,102.73,2
20041201,0:50,102.74,102.78,102.74,102.77,12
20041201,0:55,102.77,102.8,102.77,102.79,17
*/

/* my output
20041201,0:00,102.740000,102.770000,102.740000,102.760000,5
20041201,0:05,102.780000,102.780000,102.750000,102.750000,3
20041201,0:10,102.750000,102.750000,102.700000,102.700000,7
20041201,0:15,102.700000,102.720000,102.700000,102.720000,8
20041201,0:20,102.730000,102.740000,102.730000,102.740000,2
20041201,0:25,102.730000,102.730000,102.700000,102.700000,4
20041201,0:30,102.710000,102.710000,102.680000,102.700000,10
20041201,0:35,102.710000,102.730000,102.680000,102.690000,15
20041201,0:40,102.700000,102.710000,102.690000,102.710000,12
20041201,0:45,102.710000,102.730000,102.710000,102.730000,2
20041201,0:50,102.740000,102.780000,102.740000,102.770000,12
20041201,0:55,102.770000,102.800000,102.770000,102.790000,17
*/
[/edit]
"One of the methods used by statists to destroy capitalism consists in establishing controls that tie a given industry hand and foot, making it unable to solve its problems, then declaring that freedom has failed and stronger controls are necessary." --Ayn Rand
Reply With Quote Quick reply to this message  
Join Date: Jul 2005
Posts: 244
Reputation: Drowzee is an unknown quantity at this point 
Solved Threads: 5
Drowzee Drowzee is offline Offline
Posting Whiz in Training

Re: Dynamic Array, Writing to CSV, Floating Point ?'s

 
0
  #20
Aug 9th, 2005
C doesn't explicitly support vectors, right? Otherwise, why bother using malloc at all?
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
Thread Tools Search this Thread



About Us | Contact Us | Advertise | DaniWeb | Acceptable Use Policy | RSS Feed

©2003 - 2009 DaniWeb® LLC