Support Board
Date/Time: Wed, 27 Nov 2024 22:35:52 +0000
[Programming Help] - Read & parse CSV
View Count: 2073
[2020-01-06 13:14:36] |
User462086 - Posts: 196 |
Hi, in order to read a CSV file from disk then parse out certain fields from each line I've been trying to get 'sc.ReadFile' to work but can't seem to figure it out (code below with comments compiles fine). Stack Overflow has tons of examples for C++ but most utilize 3rd party libraries. In the past I've used 'fgets' in AmiBroker's C-based scripting language. 1) What's the best way to accomplish this in Sierra Chart? 2) If 'sc.ReadFile' is the best way, how do I get the file's text from the 'Buffer' (pointer) Many thanks!! Edit: using version 2028 #include "sierrachart.h" SCDLLName("Test_ReadFile") // support function DWORD GetFileSize(const SCString& PathAndFileName){ HANDLE File = CreateFile ( PathAndFileName , GENERIC_READ , FILE_SHARE_READ | FILE_SHARE_WRITE , NULL , OPEN_EXISTING , 0 , NULL ); if (File == INVALID_HANDLE_VALUE) return INVALID_FILE_SIZE; DWORD FileSize = ::GetFileSize(File, NULL); CloseHandle(File); return FileSize; } // main SCSFExport scsf_Test_ReadFile(SCStudyInterfaceRef sc){ SCString DebugMessage; // int/bool %d; float %f, %g, %e; string %s // DebugMessage.Format("caption : %d",var); // sc.AddMessageToLog(DebugMessage, 0); SCInputRef FullPath = sc.Input[0]; if (sc.SetDefaults){ sc.GraphName = "Test_ReadFile"; sc.AutoLoop = 0; FullPath.Name = "Full Path to Text File"; FullPath.SetPathAndFileName(""); return; } int FileHandle; bool FileOpened = sc.OpenFile ( FullPath.GetPathAndFileName() , n_ACSIL::FILE_MODE_OPEN_EXISTING_FOR_SEQUENTIAL_READING , FileHandle ); if (FileOpened==false) return; DWORD BytesToRead = GetFileSize(FullPath.GetPathAndFileName()); if (BytesToRead==INVALID_FILE_SIZE) return; DebugMessage.Format( "BytesToRead : %d", BytesToRead ); sc.AddMessageToLog( DebugMessage, 0 ); char* Buffer; unsigned int* p_BytesRead; bool FileRead = sc.ReadFile ( FileHandle , Buffer , BytesToRead , p_BytesRead ); if (FileRead==false) return; // <- this executes = something is wrong with my 'sc.ReadFile' call DebugMessage.Format( "Buffer : %s", Buffer ); // <- when the line above is removed this returns "(null)" sc.AddMessageToLog( DebugMessage, 0 ); sc.CloseFile(FileHandle); } Date Time Of Last Edit: 2020-01-06 13:20:20
|
[2020-01-06 14:16:14] |
User462086 - Posts: 196 |
FWIW, this seems to be working as expected. Any comments/improvements welcome. #include "sierrachart.h" SCDLLName("Test_ReadFile") SCSFExport scsf_Test_ReadFile(SCStudyInterfaceRef sc){ SCString DebugMessage; // int/bool %d; float %f, %g, %e; string %s // DebugMessage.Format("caption : %d",var); // sc.AddMessageToLog(DebugMessage, 0); SCInputRef FullPath = sc.Input[0]; if (sc.SetDefaults){ sc.GraphName = "Test_ReadFile"; sc.AutoLoop = 0; FullPath.Name = "Full Path to Text File"; FullPath.SetPathAndFileName(""); return; } std::ifstream input(FullPath.GetPathAndFileName()); for( std::string line; getline(input,line); ){ DebugMessage.Format( "line : %s", line.c_str() ); sc.AddMessageToLog( DebugMessage, 0 ); } } |
[2020-01-06 17:37:28] |
User907968 - Posts: 823 |
In the first post: char* Buffer;
No memory is allocated to Buffer, you have simply declared Buffer as pointer to char.You can use this function to check problem with sc.OpenFile: sc.GetLastFileErrorCode() Also, you could also use functions from SCString class for handling data that is read in: ACSIL Programming Concepts: Working with SCString, Text Strings and Setting ACSIL Structure Member Name Strings e.g. SCString::ParseLines() SCString::Tokenize() Maybe some of this is helpful, or maybe you looked at these already. |
[2020-01-06 23:37:48] |
Sierra Chart Engineering - Posts: 104368 |
We have updated the documentation in regards to this. You have to allocate the Buffer and provide its size. Refer to the updated ACSIL documentation for this function.
Sierra Chart Support - Engineering Level Your definitive source for support. Other responses are from users. Try to keep your questions brief and to the point. Be aware of support policy: https://www.sierrachart.com/index.php?l=PostingInformation.php#GeneralInformation For the most reliable, advanced, and zero cost futures order routing, *change* to the Teton service: Sierra Chart Teton Futures Order Routing |
[2023-06-26 09:30:12] |
Zorin - Posts: 19 |
We have updated the documentation in regards to this
With all the utmost respect, both functions you've recommend to use - SCString::ParseLines() and SCString::Tokenize()- are very poorly documented and have no any basic examples - for example, for working with files, basic read. The single example which I could find was from the study RequestValuesFromServerAndDraw.cpp - practically, no any comments there and it's heavily relying on using pointers (most people who are not familiar with C / C++ concepts would be rather using arrays - simpler to read & understand). Please update the relevant documentation providing a couple of appropriate (easy enough for "copy-paste") examples so people don't have to re-invent the wheel every time when trying to read & parse something from the file. |
[2023-06-26 10:08:55] |
Sierra_Chart Engineering - Posts: 17198 |
Why is it you are using these functions? You can use the C++ standard library string class and functions. You do not have to rely upon anything Sierra Chart is providing.
Sierra Chart Support - Engineering Level Your definitive source for support. Other responses are from users. Try to keep your questions brief and to the point. Be aware of support policy: https://www.sierrachart.com/index.php?l=PostingInformation.php#GeneralInformation For the most reliable, advanced, and zero cost futures order routing, use the Teton service: Sierra Chart Teton Futures Order Routing |
[2023-06-26 10:08:55] |
Sierra_Chart Engineering - Posts: 17198 |
Why is it you are using these functions? You can use the C++ standard library string class and functions. You do not have to rely upon anything Sierra Chart is providing.
Sierra Chart Support - Engineering Level Your definitive source for support. Other responses are from users. Try to keep your questions brief and to the point. Be aware of support policy: https://www.sierrachart.com/index.php?l=PostingInformation.php#GeneralInformation For the most reliable, advanced, and zero cost futures order routing, use the Teton service: Sierra Chart Teton Futures Order Routing |
[2023-06-26 10:28:08] |
Zorin - Posts: 19 |
... you are using these functions? You can use the C++ standard library ..
Because it's your site, your functions, and they're described in SCSstring section, and code would look better and easier to read . PS just trying to help my son - he was trying to do everything by the book & couldn't work it out. |
[2023-06-27 08:07:08] |
User462086 - Posts: 196 |
I couldn't work it out either, so started using the various forms of 'fstream' instead. Referencing the code in the first post, replacing char* Buffer;
with char Buffer[BytesToRead];
results in 'Buffer' being filled with the contents of a file. |
To post a message in this thread, you need to log in with your Sierra Chart account: