Solved

Simple file I/O parsing problem

Posted on 2004-10-25
267 Views
Last Modified: 2010-04-15
main()
{
  //Code for opening a file and reading it (not showing it since kISS=true)                  
               
      while(fgets(acctInfo,ACCT_BUFFER,inFile)!=NULL)
        {
                           procInput(acctInfo);
                         

        }

}

void proc(char *str)
{
          int tempCounter=0;
          int i=0;
           char balance[ACCT_BUFFER]//Defined in macro ACCT_BUFFER=200

       
        for(i=(strlen(str)-1);i>=0;i--)
        {

                printff("%c", str[i]);
              if(str[i]!='&')
              balance[tempCounter]=str[i];
              else
              break;

              tempCounter++;

        }
         printf("\n%s",balance);

}

Not to make it complicated look at my next comment for question.
0
Question by:b_vishwajit
    24 Comments
     
    LVL 5

    Author Comment

    by:b_vishwajit
    >> procInput(acctInfo);
    that should proc(acctInfo); //sorry


    My input file is a plain text file which has following information:

    Jones Bob&12/11/1965&854367451&300082.95
    Adams         Mark&05/03/1970&453863681&10000.00

    As you can see I am trying to parse Balance in my code. When I compile everything works fine except I have bizzare characters and invalid numbers. Here is the output:
    59.280003&

    59.280003→
    00.00001&

    00.000013→

    First balance is being printed correctly but with bizzare arrow character.
    Second balance has an arrow and an extra 3(where the hell did it come from ?)//Scary.

    Whats wrong with my code snippet? REPLY ASAP. Thank you all in advance.
    0
     
    LVL 1

    Assisted Solution

    by:x-pander
    first, u should terminate your string with \0, as below:

    #define ACCT_BUFFER 200
    void proc(char *str)
    {
      int tempCounter=0;
      int i=0;
      char balance[ACCT_BUFFER];

      for(i=(strlen(str)-1);i>=0;i--)
      {
        if(str[i]!='&')
          balance[tempCounter]=str[i];
        else
          break;
        tempCounter++;
      }
      balance[tempCounter] = '\0';
      printf("\n%s",balance);
    }


    second, i assume that you actually want that last field with digit in reversed order...
    0
     
    LVL 55

    Expert Comment

    by:Jaime Olivares
    It is a strange routine, I guess 59.280003 is not the true value. I think you need just this:

    void proc(char *str)
    {
              int tempCounter, i;
              char balance[ACCT_BUFFER];    //Defined in macro ACCT_BUFFER=200

           
            for(i=tempCounter=0; str[i]; i++)
            {
                  if(str[i]=='&')
                        tempCounter = 0;
                  else
                        balance[tempCounter++]=str[i];
            }
            balance[tempCounter] = 0;    /* necessary ending null character */
             printf("\n%s",balance);

    }

    Anyway, your strange behaviour is due to the missing ending null character
    0
     
    LVL 5

    Author Comment

    by:b_vishwajit
    >>Anyway, your strange behaviour is due to the missing ending null character
    Both of you have answered it. Even I tried to end the balance string with null character. But I was doing it wrong way.

    I used balance[tempCounter+1]='\0';
    Hence it did not work. Now it works!!! Its realy strange. C is so  fu***n scary.
    Now I am reversing the string and converting it to a double using atof.
    Works perfectly. Thank you both for helping. I will close this question when I am done. I might have other issues. Thanks. But keep checking this thread.
    0
     
    LVL 55

    Expert Comment

    by:Jaime Olivares
    Even if your code works now, it is not so much efficient, because it need two passes: first to copy desired portion, and second to reverse the string. I suggest to to re-design your parsing algorithm.
    0
     
    LVL 8

    Expert Comment

    by:ssnkumar
    >Now I am reversing the string and converting it to a double using atof.
    Why do you need to reverse the string!?

    -ssnkumar
    0
     
    LVL 5

    Author Comment

    by:b_vishwajit
    >>Why do you need to reverse the string!?
    I dont know I am just doing it. I dont know how atof works!!!!
    and jaime thanks for your suggestion. I dont care about efficiency for time being.
    I have another question see my next comment.
    0
     
    LVL 5

    Author Comment

    by:b_vishwajit
    How exactly do you sort an array of structs where each struct has a first name and last name as its elements?
    Both first name and last name are character arrays. Do I have to compare character by character? What algorithmis appropriate here. I am just thinking of a simple sorting algorithm like selection sort. What da ya people think?Thanks. Bonus points will be givne since this is not related to this thread.


    No urls please. No source code unless and until I give up and ask for it. Thanks.
    Sorting strings in java is as easy as printing helloworld in c:).
    0
     
    LVL 5

    Author Comment

    by:b_vishwajit
    How can I use system() calls to sort a text file containing First name and last name?

    Can some one provide source code for this? A simple example would be of great help.
    0
     
    LVL 55

    Expert Comment

    by:Jaime Olivares
    About string comparison, just have to use strcmp() standard function.

    About your strange reversing function, just need this:

    /* find and return balance amount */
    double ExtractBalance(char *str)
    {
          double balance= 0.0;
          char *ptr = strrchr(str, '&');
          if (ptr)
               balance= atof(ptr);

          printf("\n%f",balance);
          return balance;
    }
    0
     
    LVL 55

    Expert Comment

    by:Jaime Olivares
    You must provide more detail about how you have organized your data in file and memory, to help you better.
    But the sorting issue is a totally different question than the original parsing question.
    0
     
    LVL 5

    Author Comment

    by:b_vishwajit
    I just wrote a simple test program to check two strings. strcmp does check two strings lexicographicaly. I guess that solves my problem. Only thing is i have to implement a sorting algorithm on my array of structs and I am done. If using system() calls is easier and efficient than this then you are most welcome to give an answer.
    0
     
    LVL 55

    Accepted Solution

    by:
    If you want to sort by a multiple criteria, like firstname-lastname, then I recommend to sort by yourself, without using system to call sort.exe.

    You can make a simple bubble sort. I assume will be something like this:

    int i, end, comp;

    end = 0;
    while (!end) {
        end = 1;

        for (i=0; i<arraySize-1; i++) {
            comp = strcmp(yourArray[i].lastname, yourArray[i+1].lastname);

             if (comp>0 || (!comp && strcmp(yourArray[i].firstname, yourArray[i+1].firstname)>0)) {
                  /* swap both structures here */
                  end = 0;
             }
         }
    }
    0
     
    LVL 5

    Author Comment

    by:b_vishwajit
    Ok I am implementing it. I have to sort by last name first  and if last names are same then i sort by first names. I am goint to do it now.
    Thanks.
    0
     
    LVL 5

    Author Comment

    by:b_vishwajit
    Algorithm works jaime. Thanks a lot. I have another issue.
    Elements in array after sorting start from index 1 instead of 0. I am looking at my code right now and trying to debug by brute force which realy sucks. I will get back to you. Thanks again.
    0
     
    LVL 55

    Expert Comment

    by:Jaime Olivares
    Notice that:

        for (i=0; i<arraySize-1; i++) {

    the for loop goes just up to arraySize-1 because you operate up to i+1:

         strcmp(yourArray[i].lastname, yourArray[i+1].lastname);

    If you loop until the last item, then you will loose one item, because you will swap value with an inexistent 'last+1' item
    0
     
    LVL 5

    Author Comment

    by:b_vishwajit
    I am not losing any item anyway. It is just that the first array element which is array[0] has no value stored in it.
    Help. Weird!!!!!!
    0
     
    LVL 55

    Expert Comment

    by:Jaime Olivares
    Well, then start with the second element in your array in your sorting algorithm:

    for (i=1; i<arraySize-1; i++) {
    0
     
    LVL 8

    Expert Comment

    by:ssnkumar
    Post your code for sorting and we will analyze it.

    -ssnkumar
    0
     
    LVL 5

    Author Comment

    by:b_vishwajit
    /*Code snippet for sorting structure elements*/
             for (i=0; i<arraySize; i++)
            {
                comp = strcmp(sortedDB[i].Last_Name, sortedDB[i+1].Last_Name);

                //printf("\nDEBUG:%d",i);
                if(comp>0 || (!comp && strcmp(sortedDB[i-1].First_Name, sortedDB[i].First_Name)>0))
                {
                    tempAccount=sortedDB[i];
                    sortedDB[i]=sortedDB[i+1];
                    sortedDB[i+1]=tempAccount;//I think this is not the proper way to swap
                    end = 0;
                }
            }


    sortedDB is the structure which contains First name and last name.
    What I am thinking is ignore the first entry in my array of structs and print starting from index 1?
    I hope it always works.
    0
     
    LVL 55

    Expert Comment

    by:Jaime Olivares
    I guess it is:

     for (i=1; i<arraySize-1; i++)   // some changes here
            {
                comp = strcmp(sortedDB[i].Last_Name, sortedDB[i+1].Last_Name);

                // Why strcmp(sortedDB[i-1].First_Name....? it must be i+1
                if(comp>0 || (!comp && strcmp(sortedDB[i+1].First_Name, sortedDB[i].First_Name)>0))
                {
                    tempAccount=sortedDB[i];
                    sortedDB[i]=sortedDB[i+1];
                    sortedDB[i+1]=tempAccount;//I think this is not the proper way to swap
                    end = 0;
                }
            }


    0
     
    LVL 5

    Author Comment

    by:b_vishwajit
    >>// Why strcmp(sortedDB[i-1].First_Name....? it must be i+1
    That was a mistake jaime.
    Anyway. I am not gonna worry about it. I am just printing the array starting from 1 and ignoring 0th element.
    0
     
    LVL 5

    Author Comment

    by:b_vishwajit
    Ok time to close this thread.Thank you everyone for participating and helping.
    0
     
    LVL 5

    Author Comment

    by:b_vishwajit
    0

    Write Comment

    Please enter a first name

    Please enter a last name

    We will never share this with anyone.

    Featured Post

    How to improve team productivity

    Quip adds documents, spreadsheets, and tasklists to your Slack experience
    - Elevate ideas to Quip docs
    - Share Quip docs in Slack
    - Get notified of changes to your docs
    - Available on iOS/Android/Desktop/Web
    - Online/Offline

    Have you thought about creating an iPhone application (app), but didn't even know where to get started? Here's how: ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ Important pre-programming comments: I’ve never tri…
    Windows programmers of the C/C++ variety, how many of you realise that since Window 9x Microsoft has been lying to you about what constitutes Unicode (http://en.wikipedia.org/wiki/Unicode)? They will have you believe that Unicode requires you to use…
    The goal of this video is to provide viewers with basic examples to understand and use pointers in the C programming language.
    The goal of this video is to provide viewers with basic examples to understand and use switch statements in the C programming language.

    884 members asked questions and received personalized solutions in the past 7 days.

    Join the community of 500,000 technology professionals and ask your questions.

    Join & Ask a Question

    Need Help in Real-Time?

    Connect with top rated Experts

    18 Experts available now in Live!

    Get 1:1 Help Now