Maxon Developers Maxon Developers
    • Documentation
      • Cinema 4D Python API
      • Cinema 4D C++ API
      • Cineware API
      • ZBrush Python API
      • ZBrush GoZ API
      • Code Examples on Github
    • Forum
    • Downloads
    • Support
      • Support Procedures
      • Registered Developer Program
      • Plugin IDs
      • Contact Us
    • Categories
      • Overview
      • News & Information
      • Cinema 4D SDK Support
      • Cineware SDK Support
      • ZBrush 4D SDK Support
      • Bugs
      • General Talk
    • Unread
    • Recent
    • Tags
    • Users
    • Login

    Text File to an Array?

    Scheduled Pinned Locked Moved SDK Help
    11 Posts 0 Posters 1.0k Views
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • H Offline
      Helper
      last edited by

      THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

      On 24/06/2012 at 09:48, xxxxxxxx wrote:

      If I remember correctly there was the MorphMixer object example in the SDK (not sure if it's still there, too long I didn't look in there) that showed how to handle file reading with the SDK and it also contained a ReadLine function. Check it out and learn.

      Get used to write your own stuff. The deeper you get into programming (not just c4d) the more complex situations you need to handle yourself.

      1 Reply Last reply Reply Quote 0
      • H Offline
        Helper
        last edited by

        THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

        On 24/06/2012 at 11:25, xxxxxxxx wrote:

        Thanks.
        I didn't know that code was there. I think I can alter that code example to do what I'm looking for.

        I can read the first line of text with it and push it into the array:

        static String ReadLine(BaseFile *bf, String *v)  
        {  
          CHAR ch,line[1024];  
          LONG len = bf->TryReadBytes(&ch, 1);  
          
          LONG i = 0;  
          while (i<1024 && len == 1 && ch != '\n' && ch != '\r')   
          {  
          line[i++] = ch;  
          len = bf->TryReadBytes(&ch, 1);          
          }  
          
          #ifdef __PC  
          if (ch == '\r')   
          {  
              len = bf->TryReadBytes(&ch, 1);  
              if (len == 1 && ch != '\n') bf->Seek(-1);  
          }  
          #endif  
          
          v->SetCString(line, i);  
          String copy = v->GetCStringCopy(STRINGENCODING_8BIT); //Strip out the C4D encoding gibberish stuff  
          return copy;  
        }  
          
          
        Bool myDialog::InitValues(void)  
        {  
          AutoAlloc<BaseFile> bf;  
          if(!bf) return FALSE;  
          Filename file = GeGetC4DPath(C4D_PATH_DESKTOP)+Filename("test.txt");      
          if(!bf->Open(file, FILEOPEN_READ, FILEDIALOG_ANY, BYTEORDER_INTEL, MACTYPE_CINEMA, MACCREATOR_CINEMA)) return FALSE;  
          
          String line = "";  
          String textPerLine = ReadLine(bf, &line);  
          
          GeDynamicArray<String>textarray(0);       //Create the new string type array with 0 blank elements  
          textarray.Push(textPerLine);              //Fills the array with the first line of text  
          GePrint(textarray[0]);  
          
          return TRUE;  
        }
        

        That gets me pretty close.
        I just need to figure out how to get the next lines of text in a loop. So I can push each line into the textarray.

        -ScottA

        1 Reply Last reply Reply Quote 0
        • H Offline
          Helper
          last edited by

          THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

          On 24/06/2012 at 12:47, xxxxxxxx wrote:

          I think I've got it.

          Here's what I came up with:

          static String ReadLine(BaseFile *bf, String *v)  
          {  
            CHAR ch,line[1024];  
            LONG len = bf->TryReadBytes(&ch, 1);  
            
            LONG i = 0;  
            while (i<1024 && len == 1 && ch != '\n' && ch != '\r')   
            {  
            line[i++] = ch;  
            len = bf->TryReadBytes(&ch, 1);          
            }  
            
            v->SetCString(line, i);  
            String copy = v->GetCStringCopy(STRINGENCODING_8BIT); //Strip out the encoding gibberish stuff  
            return copy;  
          }  
            
            
          .......  
            
            
          Bool myDialog::InitValues(void)  
          {  
            GeDynamicArray<String>textarray(0);     //Create the new string type array with 0 blank elements  
            
            AutoAlloc<BaseFile> bf;  
            if(!bf) return FALSE;  
            Filename file = GeGetC4DPath(C4D_PATH_DESKTOP)+Filename("test.txt");      
            if(!bf->Open(file, FILEOPEN_READ, FILEDIALOG_ANY, BYTEORDER_INTEL, MACTYPE_CINEMA, MACCREATOR_CINEMA)) return FALSE;  
            
            String line = "";  
            LONG fileLength = bf->GetLength();  
            
            for (LONG i = 0L; i != fileLength; ++i)  
            {  
                bf->Seek(i, FILESEEK_RELATIVE);  
                String textPerLine = ReadLine(bf, &line);  
                textarray.Push(textPerLine);  
                GePrint(textarray[i]);  
            }  
            
            textarray.~GeDynamicArray();    //Destructor to free any memory used by the array  
            
            return TRUE;  
          }
          

          It seems to be working good so far.

          -ScottA

          Edit:
          Doh! I spoke too soon.
          It's removing the first characters for each new line. Starting with the third line.
          Still looking for the proper solution.

          1 Reply Last reply Reply Quote 0
          • H Offline
            Helper
            last edited by

            THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

            On 24/06/2012 at 16:53, xxxxxxxx wrote:

            You're using i for both character seeking through the file and index into the textarray.  That is bound to create odd behavior.  Send a variable pointer to ReadLine() which gets the number of characters read and use that in your bf->Seek().  You may also want to add code to handle the case where count may be set to 0 by ReadLine().

            static String ReadLine(BaseFile *bf, String *v, LONG* count)  
            {  
              CHAR ch,line[1024];  
              LONG len = bf->TryReadBytes(&ch, 1);  
              
              LONG i = 0;  
              while (i<1024 && len == 1 && ch != '\n' && ch != '\r')   
              {  
              line[i++] = ch;  
              len = bf->TryReadBytes(&ch, 1);          
              }  
              
              *count =            i;  
              v->SetCString(line, i);  
              String copy = v->GetCStringCopy(STRINGENCODING_8BIT); //Strip out the encoding gibberish stuff  
              return copy;  
            }  
              
            Bool myDialog::InitValues(void)  
            {  
              GeDynamicArray<String>textarray(0);     //Create the new string type array with 0 blank elements  
              
              AutoAlloc<BaseFile> bf;  
              if(!bf) return FALSE;  
              Filename file = GeGetC4DPath(C4D_PATH_DESKTOP)+Filename("test.txt");      
              if(!bf->Open(file, FILEOPEN_READ, FILEDIALOG_ANY, BYTEORDER_INTEL, MACTYPE_CINEMA, MACCREATOR_CINEMA)) return FALSE;  
              
              String line = "";  
              LONG fileLength = bf->GetLength();  
              LONG count = 0L;  
              
              for (LONG i = 0L; i != fileLength; ++i)  
              {  
                  bf->Seek(count, FILESEEK_RELATIVE);  
                  String textPerLine = ReadLine(bf, &line, &count);  
                  textarray.Push(textPerLine);  
                  GePrint(textarray[i]);  
              }  
              
              textarray.~GeDynamicArray();    //Destructor to free any memory used by the array  
              
              return TRUE;  
            }
            
            1 Reply Last reply Reply Quote 0
            • H Offline
              Helper
              last edited by

              THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

              On 24/06/2012 at 16:56, xxxxxxxx wrote:

              Also note that TryReadBytes() may be updating the file pointer to the next character to read so that bf->Seek() is unnecessary.

              1 Reply Last reply Reply Quote 0
              • H Offline
                Helper
                last edited by

                THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

                On 24/06/2012 at 17:57, xxxxxxxx wrote:

                Thanks a lot Robert.
                That works much better.!Beer[URL-REMOVED]

                I removed the Seek() stuff because it ended up not being useful.

                The only bad thing I'm seeing now is that the array is being populated with empty elements.
                It looks like the array is inserting a blank element every other index.
                I don't think the code I ripped from the Morph Mixer was intended to be used like I'm using it.

                I think I can still use it this way if nobody posts a more efficient solution.

                Thanks for the help,
                -ScottA


                [URL-REMOVED] @maxon: This section contained a non-resolving link which has been removed.

                1 Reply Last reply Reply Quote 0
                • H Offline
                  Helper
                  last edited by

                  THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

                  On 24/06/2012 at 18:15, xxxxxxxx wrote:

                  You just need to eat the/any additional line-endings...

                    
                  static String ReadLine(BaseFile *bf, String *v, LONG* count)  
                  {  
                    CHAR ch,line[1024];  
                    LONG len = bf->TryReadBytes(&ch, 1);  
                    
                    // eat any line-ending characters (potentially left over from previous call ,but also potentially as first line of file)...  
                    while (len == 1 && ch == '\n' || ch == '\r')  
                    {  
                          len = bf->TryReadBytes(&ch, 1);  
                    }  
                    
                    LONG i = 0;  
                    while (i<1024 && len == 1 && ch != '\n' && ch != '\r')  
                    {  
                        line[i++] = ch;  
                        len = bf->TryReadBytes(&ch, 1);  
                    }  
                    
                    *count =            i;  
                    v->SetCString(line, i);  
                    String copy = v->GetCStringCopy(STRINGENCODING_8BIT); //Strip out the encoding gibberish stuff  
                    return copy;  
                  }  
                  
                  1 Reply Last reply Reply Quote 0
                  • H Offline
                    Helper
                    last edited by

                    THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

                    On 24/06/2012 at 18:19, xxxxxxxx wrote:

                    Grrrr.. why does the editor add extra lines?

                    EDIT: Ahh - I did not have the WYSIWYG editor enabled in my profile (!).

                    1 Reply Last reply Reply Quote 0
                    • H Offline
                      Helper
                      last edited by

                      THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

                      On 24/06/2012 at 18:35, xxxxxxxx wrote:

                      That's great!
                      Thanks Giblet. 🍺

                      I think the forum spaces out code copied and pasted directly from VS.
                      I usually remove all the tabs from my code and insert spaces in a .txt file before posting it here.
                      That usually keeps it nice and tight.

                      Nice teamwork guys.
                      Thanks again for the help. And have a good night.

                      -ScottA

                      1 Reply Last reply Reply Quote 0
                      • H Offline
                        Helper
                        last edited by

                        THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

                        On 25/06/2012 at 16:43, xxxxxxxx wrote:

                        UPDATE:

                        I was having memory leaks with my array using the code posted. And I tracked down the problem to the GetCStringCopy function I was using in the ReadLine() method.
                        Apparently that was causing the array to not free it's memory. And it turns out that I didn't need it in there anyway.

                        Here's the updated ReadLine() method I'm using now:

                        static String ReadLine(BaseFile *bf, String *v, LONG* count)  
                        {  
                          CHAR ch,line[1024];  
                          LONG len = bf->TryReadBytes(&ch, 1);  
                          
                          //This will delete any line-ending characters (potentially left over from previous call ,but also potentially as first line of file)...  
                          while (len == 1 && ch == '\n' || ch == '\r')  
                          {  
                          len = bf->TryReadBytes(&ch, 1);         
                          }  
                          
                          LONG i = 0;  
                          while (i<1024 && len == 1 && ch != '\n' && ch != '\r')  
                          {  
                          line[i++] = ch;  
                          len = bf->TryReadBytes(&ch, 1);         
                          }  
                          
                          *count = i;  
                          v->SetCString(line, i);  
                          String result = *v;  
                          return result;  
                        }
                        

                        This appears to have cured my array memory leak problems.

                        -ScottA

                        1 Reply Last reply Reply Quote 0
                        • First post
                          Last post