Thread: Help discarding a space in char array

  1. #1
    Registered User
    Join Date
    Apr 2008
    Posts
    115

    Help discarding a space in char array

    I have some embedded sql code that reads data from a sql database and inserts the data into a ingres isql database. That works fine. My problem lies in the code when I use atof to convert a character field (set up by outside company) in sql to a double for the ingres database. This value should have been an integer in SQL as well. So I store this char field from sql into a variable called rslt_rec_char.Hardness and if there is a space before the number (seems to be only problem) I need to remove it so the atof function will work. Can someone help me make changes to the code below to do this? Thanks. The int is_double just looks for decimal point and the function is posted below also.

    Code:
        879         if (is_double(rslt_rec_char.Hardness))
        880             rslt_rec.Hardness = atof(rslt_rec_char.Hardness);
        881         else if (!strcmp(rslt_rec_char.Hardness,"")) 
        882             rslt_rec.Hardness = 0.0;
        883         else
        884         {
        885             rslt_rec.Hardness = 0.0;
        886             sprintf(jnl.mesg, "ERROR: CIN %s. Hardness test value invalid - \"%s\".\n"
        887                 "Hardness in test record %s not recorded!",
        888                 rslt_rec_char.CIN, rslt_rec_char.Hardness, rslt_rec_char.ResultsID);
        889             log_it(logfile,jnl);
        890             send_email(db_nm,"Met lab test upload error",jnl.mesg);
        891         }


    Code:
       1421 int
       1422 is_double(char s[])
       1423 {
       1424     int index, decimal_point_found = 0;
       1425
       1426     if (!strcmp(s,"")) return 0; 
       1427
       1428     for (NULL; *s && isspace(*s); s++);
       1429     if (s[0] == '-') s++;
       1430
       1431     for (index = 0; index < strlen(s); index++)
       1432     {
       1433         if (s[index] == '.') decimal_point_found++;
       1434         else if (!isdigit(s[index])) return 0;
       1435     }
       1436
       1437     return ((decimal_point_found <= 1) ? 1 : 0);
       1438 }
    Last edited by cjohnman; 05-12-2008 at 02:48 PM.

  2. #2
    Jack of many languages Dino's Avatar
    Join Date
    Nov 2007
    Location
    Chappell Hill, Texas
    Posts
    2,332
    Code:
    char * first_nonblank = rslt_rec_char.Hardness ; 
    while (*first_nonblank) { 
       if ( isspace(*first_nonblank) ) first_nonblank++ ; 
       else break ; 
    }
    then use first_nonblank inside the atof() function.
    Mainframe assembler programmer by trade. C coder when I can.

  3. #3
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Surely this:
    Code:
         for (NULL; *s && isspace(*s); s++);
    is much clearer as:
    Code:
         while(*s && isspace(*s))
              s++;
    If nothing else, you can certainly remove the NULL before the first semicolon.

    Also, you isdigit doesn't allow the
    Code:
    E{,+,-}[0-9]*
    format of floating point.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  4. #4
    Registered User
    Join Date
    Apr 2008
    Posts
    115

    Thanks for feedback

    Thanks for pointing out some improvements for my existing code. I will look into making those changes. I plugged the code above in this morning and it works but I am seeing the space in my printf and that concerns me. I don’t think the space is being removed. I copied the code below and placed the results of the printf below the code. Any ideas why I see the output like this. Before passing the string I have to remove that space. Also I am wondering what I can do if I happen to get a string with more than one whitespace. Couldn’t that cause a memory leak with this while loop?



    Code:
         88     char hardness[256];
    
         89     char *first_nonblank;
    
         90     double hardness2;
    
         91
    
         92     strcpy(hardness,"23.345");
    
         93     first_nonblank = hardness;
    
         94
    
         95     while (*first_nonblank)
    
         96     {
    
         97     if (isspace(*first_nonblank))
    
         98     first_nonblank++;
    
         99     else break;
    
        100     }
    
        101
    
        102     hardness2 = atof(hardness);
    
        103
    
        104     printf("&#37;s\n", hardness);
    
        105      
    
                  /* Print again this time with space*/
    
        106     strcpy(hardness," 23.345");
    
        107     first_nonblank = hardness;
    
        108
    
        109     while (*first_nonblank)
    
        110     {
    
        111     if (isspace(*first_nonblank))
    
        112     first_nonblank++;
    
        113     else break;
    
        114     }
    
        115
    
        116     hardness2 = atof(hardness);
    
        117
    
        118     printf("%s\n", hardness);

    Output:

    23.345

    (space)23.345

  5. #5
    Jack of many languages Dino's Avatar
    Join Date
    Nov 2007
    Location
    Chappell Hill, Texas
    Posts
    2,332
    Yes, you have to print the string pointed to by first_nonblank to see the space removed. It really not physically "removed", it is just not part of the new string pointed to by first_nonblank, which is what you need for atof().
    Mainframe assembler programmer by trade. C coder when I can.

  6. #6
    Registered User
    Join Date
    Apr 2008
    Posts
    115

    Made following changes and now get core dump

    Code:
        char hardness[256];
        char *first_nonblank;
        double hardness2;
    
        strcpy(hardness,"23.345");
        first_nonblank = hardness;
    
        while (*first_nonblank)
        {
        if (isspace(*first_nonblank))
        first_nonblank++;
        else break;
        }
    
        hardness2 = atof(first_nonblank);
    
        printf("%s\n", hardness2);
    
        strcpy(hardness," 23.345");
        first_nonblank = hardness;
    
        while (*first_nonblank)
        {
        if (isspace(*first_nonblank))
        first_nonblank++;
        else break;
        }
    
        hardness2 = atof(first_nonblank);
    
        printf("%s\n", hardness2);

  7. #7
    Jack of many languages Dino's Avatar
    Join Date
    Nov 2007
    Location
    Chappell Hill, Texas
    Posts
    2,332
    hardness2 is a double, not a string.
    Mainframe assembler programmer by trade. C coder when I can.

  8. #8
    Registered User
    Join Date
    Apr 2008
    Posts
    115

    Thanks Tod!!!

    The following works great thanks to Tod's help!

    Code:
        char hardness[256];
        char *first_nonblank;
        double hardness2;
    
        strcpy(hardness,"23.345");
        first_nonblank = hardness;
    
        while (*first_nonblank)
        {
        if (isspace(*first_nonblank))
        first_nonblank++;
        else break;
        }
    
        hardness2 = atof(first_nonblank);
    
        printf("%f\n", hardness2);
    
        strcpy(hardness," 23.345");
        first_nonblank = hardness;
    
        while (*first_nonblank)
        {
        if (isspace(*first_nonblank))
        first_nonblank++;
        else break;
        }
    
        hardness2 = atof(first_nonblank);
    
        printf("%f\n", hardness2);

  9. #9
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Personally, I find this:
    Code:
    while (*first_nonblank)
    {
    if (isspace(*first_nonblank))
    first_nonblank++;
    else break;
    }
    easier to read and understand as:
    Code:
    while (*first_nonblank && isspace(*first_nonblank))
    {
        first_nonblank++;
    }
    Also, since the null character is not a space, you could simplify that to:
    Code:
    while (isspace(*first_nonblank))
    {
        first_nonblank++;
    }
    which is even more straightforward to read and understand.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  10. #10
    Jack of many languages Dino's Avatar
    Join Date
    Nov 2007
    Location
    Chappell Hill, Texas
    Posts
    2,332
    Good simplification laserlight.

    Todd
    Mainframe assembler programmer by trade. C coder when I can.

  11. #11
    Registered User
    Join Date
    Apr 2008
    Posts
    115

    Laserlight Thanks!

    I plugged your simplified version of Todds code in and it worked great! Thanks for your feedback. If there was more than one space this would work and no worrys about memory leak right?

  12. #12
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Quote Originally Posted by cjohnman View Post
    I plugged your simplified version of Todds code in and it worked great! Thanks for your feedback. If there was more than one space this would work and no worrys about memory leak right?
    There are no memory allocations in the code posted here, so I don't see how it could leak anything.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  13. #13
    Registered User
    Join Date
    Apr 2008
    Posts
    115

    Just ran into one problem

    I just realized I need to discard the first space if one exists but if more than one exists do some error handling. So I only want the value if no space exists or if one exists. Other than that break out of loop and do some error handling. Any one care to help me adjust the loop laserlight posted?

    Thanks in advance.

  14. #14
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    My idea would be to add an additional variable, which is originally zero, then increment it within the loop, and if it's greater than one when the loop finishes, you've got an error.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  15. #15
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Actually, in that case I do not think you need a loop. If the first two characters are spaces, then there is an error. Else, if only the first character is a space, then you ignore it. Else, you can convert immediately.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Code review
    By Elysia in forum C++ Programming
    Replies: 71
    Last Post: 05-13-2008, 09:42 PM
  2. Need help understanding info in a header file
    By hicpics in forum C Programming
    Replies: 8
    Last Post: 12-02-2005, 12:36 PM
  3. Quick question about SIGSEGV
    By Cikotic in forum C Programming
    Replies: 30
    Last Post: 07-01-2004, 07:48 PM
  4. String sorthing, file opening and saving.
    By j0hnb in forum C Programming
    Replies: 9
    Last Post: 01-23-2003, 01:18 AM