Reading Lines with Fgets(?) and a bit of C++ {Novice Programmer}

Discussion in 'C++' started by AMT2K5, Jul 6, 2005.

  1. AMT2K5

    AMT2K5 Guest

    I have a file (for a school assignment) with the following format and
    delimiter format. Each record in the file has the following format:
    123423454567987,29873,James,Ha­rry,St. Louis,416-555-5555;
    "accountNumber,balance,lastNam­e,city,phoneNumber;" Each record is
    guranteed to be no longer than 350 characters. "balance" is no longer
    than 20 characters, "accountNumber" is exactly 15 characters and the
    total number of characters in "lastName,firstName,city,phone­Number;"
    no longer than 315 characters. Copy the fields in this record to the
    appropriate data member of the first empty Account in the array
    savings, using all the rules for copying (initializing).

    Contents of a3.dat



    Since each "record" is not a line and is shown as is (above) in the
    file, how might I go and read each "record", extract the information
    and send it to the correct data member of the first empty object in the

    So far I have my function like this

    void Bank::workFP(FILE* fp)
    if(fp != NULL){

    else printf("Unable to open file.\n");

    Thanks in advance. Appreciate any help whatsoever.
    AMT2K5, Jul 6, 2005
    1. Advertisements

  2. AMT2K5

    titancipher Guest

    It's not "nice" because the data file is intentionally jumbled. One
    way to do this is to read exactly 350 characters, and parse it
    according to the rules you've outlined for the data elements. Then,
    save-off the remainder. Loop again, and read another 350, prepend the
    remainder and continue. Keep in mind that you will not have nice NULL
    terminated strings, and also check that you read 350 characters.
    titancipher, Jul 6, 2005
    1. Advertisements

  3. From your description: Each "record" ends with a ';' character.
    So read character by character until you encounter a ';'. Save those
    characters in a buffer (probably a std::string). Then you have all
    characters for one record and can proceed to break it into
    individual pieces.
    Karl Heinz Buchegger, Jul 6, 2005
  4. AMT2K5

    jason Guest

    since you can't guarantee that each record occupies it's own line, then
    you will have to read the whole file into memory. if you can gaurantee
    that the file is not of huge size, then you can just read the while
    file into a char* buffer, or a std::string object:

    if (fp != NULL)
    char *chunk = new char[256];
    std::string sBuffer;
    while (!feof(fp))
    fread(chunk, sizeof(char), 256, fp); // you might even be able to
    read right into the string struct, but i'm not sure
    string = string + sBuffer;
    delete[] chunk;
    chunk = null;

    once you have the whole file in a buffer, it's easy to use string
    manipulation to parse it, first by ';' to get the records, then by ','
    to get the fields in each record.

    if you can't gaurantee that the file is reasonable in size, then it
    gets trickier. you have to analyze each chunk for records first, and
    then do an fseek to get to the last place in the file you left off:

    if (fp != NULL)
    char *chunk = new char[256];
    int nextstartposition = 0;
    while (!feof(fp))
    fseek(fp, nextstartposition, 0);
    fread(chunk, sizeof(char), 256, fp);
    nextstartposition = nextstartposition +
    delete[] chunk;
    chunk = null;

    in this case DoParsingAndOtherStuff does the same thing, but it has to
    return the position that the last ';' was found on, because everything
    after that was only a partial record. then the file can seek to that
    new starting location, and read another chunk. it's only a little
    trickier than reading the whole thing into memory, really.

    if you need help with what DoParsingAndOtherStuff would look like, let
    me know.

    hope this helps,

    jason, Jul 6, 2005
  5. AMT2K5

    AMT2K5 Guest

    How can I program my loop to read the next record after the first ';'?
    AMT2K5, Jul 6, 2005
  6. As said: you can read character by character. eg.

    std::string buffer;
    char c;

    while( fin >> c ) {
    if( c == ';' ) {
    // buffer contains a record, process it
    Process( buffer );
    buffer = "";
    buffer += c;

    Not very fast, but it does its job.
    Karl Heinz Buchegger, Jul 6, 2005
  7. AMT2K5

    AMT2K5 Guest

    What is that string = string come from? What is string?

    I am trying to interpret your code.
    AMT2K5, Jul 6, 2005
  8. AMT2K5

    Puppet_Sock Guest


    You will need to get and read one of the fine introductory
    textbooks on C++. The stuff you are talking about is fairly
    elementary. For example, Koenig and Moo, _Accelerated C++_
    is well thought of. Also, your instructor should have said
    what text you should be reading, and you should be reading it.
    Puppet_Sock, Jul 6, 2005
  9. AMT2K5

    jason Guest

    it's from the std library. if you can't use such things in your
    assignment, then char arrays work well too, though then it will be much
    easier to just process each chunk that you pull out, so that you're not
    constantly resizing the char array for the full file buffer.

    either Karl or my samples should work. his processes character by
    character, mine in larger chunks. both should be fine for an assignment.
    jason, Jul 6, 2005
  10. AMT2K5

    Howard Guest

    Why would you allocate and delete a buffer like that? Why not just declare
    a local array? Just because fread takes a pointer does not mean you have to
    _declare_ a pointer. All that function wants is the address of the first
    element, which you can get with either just "chunk" or "&chunk[0]". (If you
    can avoid using new and delete, it's generally better to do so, both because
    it is faster and because it's less error-prone.)

    Howard, Jul 6, 2005
  11. AMT2K5

    AMT2K5 Guest

    I just want to keep this as simple as possible. For parsing and working
    with the fields is it suggessted that I use strtok?
    AMT2K5, Jul 6, 2005
  12. AMT2K5

    red floyd Guest

    jason wrote:
    in addition to Howard's comment on allocating "chunk", you also have the
    usage of feof incorrect. feof doesn't kick in until you try to read and
    actually have alreay hit EOF. It's not predictive like Pascal.

    while (fread(chunk, sizeof(char), 256, fp) > 0)
    // ...

    Also, sizeof(char) is redundant since by definition it's 1, but it's
    probably better to use it since you may in the future want to go to wchar_t.


    while (fread(chunk,sizeof(chunk[0]), 256, fp) > 0)
    // ...

    which then becomes independent of the size of your character.
    red floyd, Jul 6, 2005
  13. AMT2K5

    AMT2K5 Guest

    Thanks for the help guys. I asked my prof for extra help today and he
    suggested that I use fscanf.

    Now I am using it but I am having trouble with my format string. I can
    display the first fields fine, but the (%315) field I can not. I get a
    single garbage character on my screen if I display it.

    char accountTemp[16];
    int balanceTemp = 0;
    char stringTemp[316];

    fscanf(fp, "%15[^,],%20d[^,],%315[^;]", accountTemp, &balanceTemp,

    AMT2K5, Jul 6, 2005
    1. Advertisements

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments (here). After that, you can post your question and our members will help you out.