locked
Read lines of text file one by one with metro apps

    Question

  • Hello

    Iam new to developing metro style apps.

    Im trying to develop a C++ app that reads a text file. It reads a single line of text and then displays it in a listbox one line at a time.

    But i fail to understand how to read a single line. My app is reading the entire file at once.

    The code is as follows:

    void metro::MainPage::ReadButton_Click(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e)
    {
     

    StorageFolder^ documentsFolder = KnownFolders::DocumentsLibrary;
        auto fileOperation = documentsFolder->GetFileAsync("sample.txt");
        MainPage^ page = this;
        fileOperation->Completed = ref new AsyncOperationCompletedHandler<StorageFile^>([page](IAsyncOperation<StorageFile^>^ operation)
        {
            if (operation->Status == AsyncStatus::Completed)
            {
                // Get the returned file and attempt to open it for a read operation
                StorageFile^ storagefileSample = operation->GetResults();
                auto openOperation = storagefileSample->OpenAsync(FileAccessMode::Read);
                openOperation->Completed = ref new AsyncOperationCompletedHandler<IRandomAccessStream^>([page](IAsyncOperation<IRandomAccessStream^>^ operation)
                {
                    if (operation->Status == AsyncStatus::Completed)
                    {
                        // Create a DataReader to read the opened file's contents
                        IRandomAccessStream^ stream = operation->GetResults();
                        DataReader^ dataReader = ref new DataReader(stream->GetInputStreamAt(0));

                        // Load in the full stream size
                        auto readOperation = dataReader->LoadAsync(stream->Size);
                        readOperation->Completed = ref new AsyncOperationCompletedHandler<unsigned int>([page, dataReader](IAsyncOperation<unsigned int>^ operation)
                        {
                            // Read the loaded string and display it in the output textblock
                            page->TextBlock->Text = dataReader->ReadString(operation->GetResults());
                        });
                        readOperation->Start();
                    }
                });
                openOperation->Start();
            }
            else
            {
                page->TextBlock->Text = "The file sample.txt does not exist.";
            }
        });
        fileOperation->Start();
    }

    Please help.

    Thanks.

    Wednesday, February 15, 2012 6:52 AM

Answers

  • Hi ashi1812,

    There is no direct line-by-line reading mode. You will have to read the lines in and break them at the newline yourself.

    --Rob

    Thursday, February 16, 2012 1:10 AM
    Owner

All replies

  • Hi ashi1812,

    There is no direct line-by-line reading mode. You will have to read the lines in and break them at the newline yourself.

    --Rob

    Thursday, February 16, 2012 1:10 AM
    Owner
  • How can I do that exactly?

    Regards, Ashi

    Thursday, February 16, 2012 10:40 AM
  • Hi Ashi,

    If your not too familiar with C++ string manipulation, you may find C# has some simple ways to accomplish this task as well. Here's a snippet that you can add into to the C++ File Access sample to accomplish your task. You need the #includes as well.

    #include <windows.h>
    #include <wchar.h>
    
    //paste this into the section containing the line that updates
    // the TextBlock: page->TextBlock->Text = dataReader->ReadString(operation->GetResults());
     
    //Get the Platform::String
    auto s = dataReader->ReadString(operation->GetResults());
    //Get the wchar_t
    auto s2 = s->Data();
    					 				 
    //Make a copy of the string to avoid overwriting the original 
    size_t nlen;
    nlen = (wcslen(s2))+1;
    wchar_t* tokenIn = new wchar_t[nlen];
    wcscpy_s(tokenIn,nlen,s2); 
    wchar_t* tokenOut = NULL;
    wchar_t delim[] = L"\r\n";
    //get the first 'line' up to a CRLF
    tokenIn = wcstok_s( tokenIn, delim, &tokenOut );
    //Loop to read each subsequent line
    while ( tokenIn != NULL )
    {
    	OutputDebugString( tokenIn );
    	tokenIn = wcstok_s( NULL, delim, &tokenOut);
    	OutputDebugString( L"-\n-" );
    }
    delete [] tokenIn;</wchar.h></windows.h>

    Thanks,

    -David


    Friday, February 17, 2012 11:54 PM
    Moderator
  • Hey David,

    Thanks for your reply but the code snippet that you have told me to add is still giving errors:

    1 . errno_t wcscpy_s(wchar_t *,rsize_t,const wchar_t *)' : cannot convert parameter 3 from 'int' to 'const wchar_t * in the line :

    wcscpy_s(tokenIn,nlen,s2);

    2. 'wcslen' : cannot convert parameter 1 from 'int' to 'const wchar_t * in the line:

    nlen = (wcslen(s2))+1;

    3. 'Platform::String::Data': function call missing argument list; use '&Platform::String::Data' to create a pointer to member in the line :

    auto ws = _str->Data;

    4. 's2': cannot be used before it is initialized in the line :

    wcscpy_s(tokenIn,nlen,s2);

    Kindly help me with the solution.


    Regards, Ashi


    • Edited by ashi1812 Tuesday, February 21, 2012 5:56 AM
    Tuesday, February 21, 2012 5:52 AM
  • Hi all,

    I've worked upon the solution by using wstrings.

    And it's working fine now.

    Thanks a lot for your help. :)


    Regards, Ashi

    Tuesday, February 21, 2012 6:41 AM