Home > c# > Reading a file and storing the contents in an array

Reading a file and storing the contents in an array

April 21Hits:1
Advertisement

This is my code for reading a file with a delimiter. Any suggestions to help improve my code efficiency?

I am not satisfied with using array data structure. Can any other data structure be used instead of an array?

bool read_file(char *p_file_name,char *file_content[FILE_NO_OF_ROWS][FILE_NO_OF_COL],const char *delimiter, int& token_count ) {     using namespace std;    ifstream file_is_obj;    file_is_obj.open(p_file_name,ios::in);     string buffer,token;    int token_pos;    token_count=0;     if( file_is_obj.is_open())    {       while( !file_is_obj.eof() )       {          if(token_count >= FILE_NO_OF_ROWS)          {             break;          }            buffer.clear();           token_pos=0;           std::getline(file_is_obj,buffer);          for( int iter=0;  token_pos  != -1 || iter >= FILE_NO_OF_COL ; iter++)          {             token.clear();              token_pos=buffer.find(delimiter,0);             token=buffer.substr(0,token_pos);             if( !token.empty() )             {                buffer.erase(0,token_pos+strlen(delimiter));                file_content[token_count][iter] = new char[token.length()+1] ;                 memset(file_content[token_count][iter],'\0',(token.length()+1)*sizeof(char));                token.copy( file_content[token_count][iter], token.length(), 0);             }          }          token_count++;       }       token_count-=1; // Token incremented for reading end of file    }    else    {       printf("\nFile not found (or) Error in opening the file");       return false;    }     return true; } 

Answers

Some comments:

  1. Use std::vector instead of an inflexible array. You're writing in C++, so you really ought to use the power of that language to write better code.
  2. Don't use memset. It's generally wise to avoid mixing old-style C library functions such as memset, malloc and so forth, with C++. Strange things can happen and there's usually a better C++ way to do things without those.
  3. Instead of using string.find, consider using other techniques such as the ones described here to split a line into its constituent pieces.
  4. Rather than printing an error message, throw an exception. That way your code can be reused in situtations in which std::cout is not present or not visible.
  5. Do NOT embed using namespace std; into code like that! It's extremely bad practice

EDIT: Here's a quick alternative using a variation of the string split I pointed to in point #3.

#include <iostream>
#include <fstream>
#include <string>
#include <vector>

template <typename Container>
Container& split(Container& result,
  const typename Container::value_type& s,
  const typename Container::value_type& delimiters)
{
  result.clear();
  size_t current;
  size_t next = -1;
  do {
    current = next + 1;
    next = s.find_first_of( delimiters, current );
    result.push_back( s.substr( current, next - current ) );
  } while (next != Container::value_type::npos);
  return result;
}

int main(int argc, char *argv[])
{
    if (argc < 2) {
        std::cout << "Usage readarray filename\n";
        return 0;
    }
    const std::string delimiter{","};
    std::vector<std::vector<std::string> > v;
    // fetch the file into v
    std::string line;
    std::vector<std::string> fields;
    for( std::ifstream in(argv[1]); std::getline(in, line); ) {
        v.push_back(split(fields, line, delimiter));
    }
    // now print the results
    for (const auto &i : v) {
        for (const auto &j: i)
            std::cout << "[" << j << "]";
        std::cout << '\n';
    }
}

This uses C++11, but could easily be adapted for old compilers. Based on this input file:

alpha,frank,ruby,diamond
beta,joseph,emerald,circle
gamma,may,onyx,triangle

The code produces this output:

[alpha][frank][ruby][diamond]
[beta][joseph][emerald][circle]
[gamma][may][onyx][triangle]

Lets start with the function definition:

bool read_file(char *p_file_name,char *file_content[FILE_NO_OF_ROWS][FILE_NO_OF_COL],const char *delimiter, int& token_count )

You are passing C-Strings and arrays of C-String. That's not a good start. Who owns the pointers? Am I supposed to free the pointers after use create them? I can't tell based on this interface.

About the only thing I can tell for sure is that token_count is an out parameter but I am not even sure if I should reset that to zero before starting (which means the user of the code does not know if they need to set it to zero before starting, which means the only safe thing to do is set it to zero (which means if you set it to zero inside the function you are wasting instructions))?

Also passing arrays through a function is dodgy. Its not doing quite what you expect. In this case you are passing char *(*)[FILE_NO_OF_COL] through as the parameter. Which makes validation on the other side a pain. When passing arrays don't give the function a false sense of security be exact with your type (or learn how to pass an array by reference).

Also I am betting FILE_NO_OF_ROWS and FILE_NO_OF_COL are macros. Don't do that macros are not confined by scope. Prefer to use static const objects. Note if you use a vector all that information is stored for you.

Prefer to pass C++ objects. `std::string is always good for passing strings and why not a vector for a container of objects.

Unlike normal; I will not complain about this (as it is confined to a very strict scope). But you should be aware that its frowned upon.

   using namespace std;

Why take two lines to open a file?

   ifstream file_is_obj;
   file_is_obj.open(p_file_name,ios::in);

   // I would have just done
   std::ifstream     file_is_obj(p_file_name);

Declare variables as close to the point of usage as you need them. Declaring them out here seems like a waste. Also it makes the code more complex as you have to reset things manually rather than let the compiler do it.

   string buffer,token;
   int token_pos;
   token_count=0;

Sure you can test if it is open. But usually that is a waste of time. If it failed to open nothing else is going to work. So exit the function now and reduce them number of levels of indention of the code.

   if( file_is_obj.is_open())
   {

This is RARELY correct in any language.

      while( !file_is_obj.eof() )
      {
          // STUFF
      }

The pattern for reading from a file is:

      while( <READ Value> )
      {
           // Read Succeeded continue to processes code.
           // STUFF
      }

This is because EOF is not set until you read past the end of the file. The last successful read will read up-to but not past the end of file. Thus you have no data left to read but the EOF flag is not set and thus you enter the loop. When you attempt to read the next item it will fail and set the EOF flag. So if you are doing it your way your code should look like this:

      while( !file_is_obj.eof() )  // This is now redundant.
      {
          <READ VALUE>
          if (file_is_obj.eof())   // You have to check for read failure
          {    break;              // In all languages.
          }
          // STUFF
      }

Thus it is better to use the standard pattern were you do the read as part of the test.

If you declare buffer here. Then you would not need to manually clear it here (or reset token).

         buffer.clear();
         token_pos=0;

Looking at your string splitting code:

         for( int iter=0;  token_pos  != -1 || iter >= FILE_NO_OF_COL ; iter++)

You are making assumptions about the result of std::string::find(). Why do you think token_pos != -1 will ever be correct. The documentation is very clear. If there is no match to the find it returns std::string::npos. Dont make any assumptions on what that value is.

The standard way of testing for out of bounds is less than iter < FILE_NO_OF_COL though your test is perfectly valid iter >= FILE_NO_OF_COL it looks weird.

Prefer pre-increment to post increment. It makes no difference in this case. But in general siuation it can make a difference (because we use the same kind of loop with iterators). So to be consistent and always get the best loop characteristics use the pre-increment.

Would not need to clear token if it was local.

            token.clear();

This bit of code is real over-complex.

            token_pos=buffer.find(delimiter,0);
            token=buffer.substr(0,token_pos);
            if( !token.empty() )
            {
               buffer.erase(0,token_pos+strlen(delimiter));
               file_content[token_count][iter] = new char[token.length()+1] ;

               memset(file_content[token_count][iter],'\0',(token.length()+1)*sizeof(char));
               token.copy( file_content[token_count][iter], token.length(), 0);
            }
         }

  1. You find the delimiter.
  2. You copy the token into another object.
    Which would clear it (so the above clear is usless).
  3. You manually allocate memory
  4. You manually clear all the memory.
  5. You do a second copy.
    Note this second copy is wrong (as you don't copy the terminating '\0' to make it a real C-String and thus you loose all information about its end.

So you are copying the string twice. You are manually allocating memory (with no definition of how the memory should be released).

Also any unset members of the array have there original values (which may be misleading). Either the caller of the function has to make sure that the array is correctly nulled out before calling (which you do not make clear in your interface) or you should be nulling out the undefined cells.

Related Articles

  • Reading a file and storing the contents in an arrayApril 21

    This is my code for reading a file with a delimiter. Any suggestions to help improve my code efficiency? I am not satisfied with using array data structure. Can any other data structure be used instead of an array? bool read_file(char *p_file_name,ch

  • mac os not playin Mp4 and mov file when stored in content document [on hold]February 8

    From External Video URL: http://websitehelpers.com/video/mymovie.mp4 Same Video From SFDC Video URL from Content Object: https://codevapr14.ap1.visual.force.com/sfc/servlet.shepherd/version/download/06890000002z0deAAA?v=.MP4

  • mac os not playing mov file when stored in content documentFebruary 8

    From External Video URL: http://download.wavetlan.com/SVV/Media/HTTP/MOV/ConvertedFiles/MediaCoder/MediaCoder_test1_1m9s_AVC_VBR_32kbps_320x240_24fps_AACLC_VBR_32kbps_Stereo_11025Hz.mov Same Video From SFDC Video URL from Content Object: https://code

  • Is the content of a file always stored continuously?August 2

    In ext filesystems, Is the content of a file always stored continuously? Or the file conent can be partitioned into different parts, with each part stored continuously, and all the parts stored not continuously? (The storage of the content of a file

  • How can I mount this .img file and browse its contents?February 28

    I am interested in mounting a firmware image and browsing its contents. I attempted this with the mount command but received some errors ("you must specify filesystem type"). However I think there may be other issues here. I believe the below in

  • Why is Zip able to compress single file smaller than multiple files with the same content?December 14

    Suppose that I have 10,000 XML files. Now suppose that I want to send them to a friend. Before sending them, I would like to compress them. Method 1: Don't compress them Results: Resulting Size: 62 MB Percent of initial size: 100% Method 2: Zip every

  • I'm trying to populate a Mysql database with Excel File using stored procedures, phpJanuary 17

    I'm trying to populate a Mysql database from an Excel file using Stored procedures but, the problem is that the Excel File cointains fields like Genre or Country that are text (ex. Female, Male or country like El Salvador) but the database is a relat

  • What GUI Linux programs are there for finding files based upon their contents?September 18

    What GUI Linux programs are there for finding files based upon their contents? --------------Solutions------------- Gnome Search Tool is a built-in GUI tool available from Places -> Search For Files. Internally, it uses locate, find and grep to perfo

  • File size :size of content and what is seen differentApril 5

    Assume you have a file 342MB but when you get into that file and look the content of it; you see that everything occupy around 92 MB. No hidden file or any other thing exist on it. How can that be possible. Is there a solution to fix this. Here is be

  • ZFS: Is there a way to find out where the blocks for a file are stored?April 11

    Is there a way in zfs to find out where blocks for a particular file are stored? I'd like to be able to ask for the locations of all the blocks for a file, including ditto blocks. (Yes, I understand that this is low-level stuff not normally exposed t

  • How to deduplicate files when storing in the SDFS file system using OpenDedupJuly 11

    I followed the link, http://www.opendedup.org/quickstart for installing OpenDedup in my linux machine (Ubuntu 12.04 - 64 bit). I created a SDFS volume and mounted it. I copied two similar Ubuntu VMs, which has a high amount of sharing, into the SDFS

  • Filter files by name and contents in Windows 7March 5

    How to: filter files by name and contents in Windows 7? I need to find files named bob.xml recursively and leave (in the search results) only those that contain the phrase <gold>100</gold> Can it be done under Windows 7 w/o using any external

  • Content type ID on a file different from actual content type ID?March 9

    Moving from "a sharepoint user" to "a sharepoint power user", I now am facing the world of Powershell and more. One thing that really puzzles me is the following. Ok, so I have a document library containing many document sets, containi

  • What disk is a file / directory stored on? June 10

    This question already has an answer here: What file system is my file on? [duplicate] 2 answers From the command line (bash) I would like to know what disk a given file is stored in. E.G.: $ [what filesystem is this file in command] /tmp/example/file

  • Renaming files based on the contents of a text fileAugust 21

    I have lots of point files I need to change for model input. I want to rename lots of these files based on the contents of a file. These files are text files arranged in rows. file name: data_lat_long.txt 1 data_20_20 2 data_30_40 3 data_50_60 . . an

  • Adding title to file field in a content typeSeptember 5

    I am making a change to an already existing site. There is a content type called lesson, and one of its fields is called 'File'. It is being displayed using the "Generic File" format in the content type's display settings which results in a link

  • Delete old files from server when content is updated in Drupal7October 22

    When a node is updated by replacing a new file upload, old files exist on the server maintaining versions.I want delete old files from server when content is updated in Drupal7 --------------Solutions------------- This is already discussed topic. I f

  • Do encfs stashes with the same settings produce encrypted files with same encrypted contents and encrypted filenames?March 6

    If I create two files with the same content and filenames (and paths) in two separate encfs filesystems that share the same settings and key, will the encrypted versions of those files (as well as their encrypted filenames) necessarily be identical?

  • Where are QGIS application setting file(s) stored?April 22

    I have some application settings (Windows/QGIS v2.0) that I would like to pass to other users (such as those settings defined under Settings menu>Options>Rendering tab). In ArcGIS they are stored in a Normal.mxt file located: C:\Users\userName\AppDa

  • Determine which files are stored in bad sectorsDecember 14

    I ran CHKDSK last night (log below) and noticed that apparently I have 4 KB of data stored in bad sectors. Is there a way to find out which files are stored in (or at least are partially stored) in those bad sectors? Checking file system on C: The ty

Copyright (C) 2017 ceus-now.com, All Rights Reserved. webmaster#ceus-now.com 14 q. 0.950 s.