Thread: Convert scanf output to long double and discard the last newline

  1. #1
    Registered User
    Join Date
    Oct 2012
    Posts
    19

    Convert scanf output to long double and discard the last newline

    My goal is to read a one line file of a comma separated numbers into a floating point array. The numbers have up to 25 positions after the decimal. I'm having two issues with the following code.

    1) atof() seems to be returning zeros every time. Why?
    2) The last number includes the new line character. How do I get rid of it?

    Note that I adapted the scanf command from here: The power of scanf() - Cprogramming.com, and don't completely understand it, either (so talk slowly when you answer).

    Code:
    #include <stdio.h>
    #include <math.h>
    
    //The following will be calculated in the real program.
    #define DIM 1
    #define N 8
    
    int main()
    {
      char fn[] = "/raid/fpuData/bak/N=0008_Beta=09.00_tol=1e-08_t=0000.LC.csv";
      FILE *LC = fopen(fn, "r");
    
      int numElts=2*N;
      double z[numElts];
    
      char tmp[30];
      int nextChar, i;
      for (i=0; i<numElts; i++) {
        //    scanf("%[^,],", tmp);
        fscanf(LC, "%[^,],", tmp);
        printf("%d) %s\t\t", i+1, tmp);
        z[i] = atof(tmp);
        printf("%f\n", z[i]);
      }    // */
    }
    In the "real" program, N is calculated and known before reading in the file and the file will always have 2 times N numbers.

    TIY

  2. #2
    Registered User
    Join Date
    Jun 2005
    Posts
    6,815
    My guess is one of

    1) fopen() failing.
    2) fscanf() not successfully reading anything (which will also happen if fopen() fails).
    3) the data in the file cannot be scanned as a floating point value.

    All of those possibilities might explain atof() returning zero. In short, you need to check if your operations succeed, not just assume they do succeed.

    I fail to see why it matters if the data being read includes a newline character, since atof() will just treat them as whitespace. But, if it matters, add \n at the end of the format string.
    Right 98% of the time, and don't care about the other 3%.

    If I seem grumpy or unhelpful in reply to you, or tell you you need to demonstrate more effort before you can expect help, it is likely you deserve it. Suck it up, Buttercup, and read this, this, and this before posting again.

  3. #3
    Registered User
    Join Date
    Oct 2012
    Posts
    19
    I should have been clearer in my original post. The scanf works, because the first printf prints the values read. The second printf is just printing zeros. I didn't know that atof will strip the newline, so that's good to know.

    I'm not worried about error checking in this code since this is just toy code for learning. The real code has plenty of checking.

  4. #4
    Registered User
    Join Date
    Jun 2005
    Posts
    6,815
    Then it comes down to the data in the file, about which you have provided no information.

    atof() doesn't strip anything. It just starts and stops scanning based on content of the supplied string. And it returns zero if it cannot interpret the string contents as a floating point value.
    Right 98% of the time, and don't care about the other 3%.

    If I seem grumpy or unhelpful in reply to you, or tell you you need to demonstrate more effort before you can expect help, it is likely you deserve it. Suck it up, Buttercup, and read this, this, and this before posting again.

  5. #5
    Registered User
    Join Date
    Oct 2012
    Posts
    19
    OK. Let me try to give more info. Following is my full code (currently), and the compile and execution output. The tabs got lost in the copy and paste, but if you look closely enough, you can see that the first number prints, but the second number is always zero.

    I tried to attach a sample data file, but the site wouldn't let me. So the last thing is a sample data file.

    Code:
    #include <stdio.h>
    #include <math.h>
    
    //The following will be calculated in the real program.
    #define DIM 1
    #define N 8
    
    int main()
    {
      printf("Hello, world!/n");
    
      char fn[] = "/raid/fpuData/bak/N0008.csv";
      FILE *LC = fopen(fn, "r");
    
      int numElts;
      if (DIM==1) {
        numElts = 2*N;
      } else if (DIM==2) {
        numElts = (int)(2*pow(N,2));
      }
      double z[numElts];
    
      char tmp[30];
      int i;
      for (i=0; i<numElts; i++) {
        fscanf(LC, "%[^,\n],\n", tmp);
        printf("%d) %s\t\t", i+1, tmp);
        z[i] = atof(tmp);
        printf("%f\n", z[i]);
      }    // */
    }
    What happens when I compile and execute it:
    node18>gcc temp.c -o temp
    node18>temp
    Hello, world!/n1) 0.3320050679932874393429643 0.000000
    2) 0.1795292710677374725669608 0.000000
    3) 0.2548644422720920954539281 0.000000
    4) 0.1291108939967801905179812 0.000000
    5) 0.04502583412925827144324131 0.000000
    6) 0.08858780006895942971123503 0.000000
    7) 0.08357951715367695211256205 0.000000
    8) 0.1290374431012948075458979 0.000000
    9) -0.01412022523901419746028552 0.000000
    10) 0.3524604879293016246322168 0.000000
    11) 0.3981955476580613106918349 0.000000
    12) 0.3668510236732072660181814 0.000000
    13) -0.0001249706213128355084159005 0.000000
    14) 0.04492531336006604092414563 0.000000
    15) 0.3135495829306365611621743 0.000000
    16) 0.05318410281640114506407357 0.000000
    The data file (N0008.csv):
    0.3320050679932874393429643,0.17952927106773747256 69608,0.2548644422720920954539281,0.12911089399678 01905179812,0.04502583412925827144324131,0.0885878 0006895942971123503,0.08357951715367695211256205,0 .1290374431012948075458979,-0.01412022523901419746028552,0.3524604879293016246 322168,0.3981955476580613106918349,0.3668510236732 072660181814,-0.0001249706213128355084159005,0.04492531336006604 092414563,0.3135495829306365611621743,0.0531841028 1640114506407357
    Last edited by uncreativename; 04-18-2014 at 10:15 PM.

  6. #6
    Registered User
    Join Date
    Jun 2005
    Posts
    6,815
    Also, have you tried to #include <stdlib.h>? That is the header atof() is declared in, and you're not using it. Without it, the compiler will assume atof() returns int which, since atof() doesn't, means your code will have undefined behaviour.


    I'm not even going to ask why your code is using pow() to evaluate powers of 2 - gack!
    Right 98% of the time, and don't care about the other 3%.

    If I seem grumpy or unhelpful in reply to you, or tell you you need to demonstrate more effort before you can expect help, it is likely you deserve it. Suck it up, Buttercup, and read this, this, and this before posting again.

  7. #7
    Registered User Alpo's Avatar
    Join Date
    Apr 2014
    Posts
    877
    Check and see if atof is returning a 0. A good sort of general advice about any debugging is to check the functionality of all the small parts, preferably while being built.

    As to striping the newline, I've had success with using a while loop on the condition that the variable doesn't equal newline. Or if it is an array, you can scan it using a for loop, and replace the newline with '\0'.

    Code:
    for(scan=0; scan<arraysize; ++scan){
        array[scan]=(array[scan]=='\n') ? '\0' : array[scan];
    }

  8. #8
    Registered User
    Join Date
    Oct 2012
    Posts
    19
    Quote Originally Posted by grumpy View Post
    Also, have you tried to #include <stdlib.h>? That is the header atof() is declared in, and you're not using it. Without it, the compiler will assume atof() returns int which, since atof() doesn't, means your code will have undefined behaviour.
    Including stdlib.h fixed the problem. A programming 101 error, I guess. But shouldn't the compiler have warned me that it couldn't find atof()?

    Quote Originally Posted by grumpy View Post
    I'm not even going to ask why your code is using pow() to evaluate powers of 2 - gack!
    What's wrong with pow()? According to the book I'm using and whatever I read on the web at the time I wrote tha tline, that is how you raise something to a power.

    Quote Originally Posted by Alpo View Post
    As to striping the newline, I've had success with using a while loop on the condition that the variable doesn't equal newline. Or if it is an array, you can scan it using a for loop, and replace the newline with '\0'.
    The newline problem was taken care of by changing the scanf() statement the way it was suggested in this thread's first response.

    All issues now resolved. TY.

  9. #9
    Registered User Alpo's Avatar
    Join Date
    Apr 2014
    Posts
    877
    Ah good. I'm an incredibly slow poster, and usually find everything is resolved by the time I've quit dicking around and submit lol.

  10. #10
    Registered User
    Join Date
    Jun 2005
    Posts
    6,815
    Quote Originally Posted by uncreativename View Post
    Including stdlib.h fixed the problem. A programming 101 error, I guess. But shouldn't the compiler have warned me that it couldn't find atof()?
    Nope. In C, if a function is not declared, the compiler assumes it returns an int (which causes problem if it actually doesn't).

    That said, most modern compilers can be configured to give more warnings, and will detect your problem. However, the default setting for all modern compilers is that those warning levels are disabled - and the means of configuring a compiler to give those warnings is compiler dependent.

    You can thank a generation of lazy and semi-incompetent programmers and teachers for that state of affairs - they lobbied compiler vendors to disable such warnings, based on the premise that compiler warnings don't actually prevent a program from being compiled (they only provide indications it might not work as intended - which goes to show what those programmers and teachers paid attention to).

    Quote Originally Posted by uncreativename View Post
    What's wrong with pow()? According to the book I'm using and whatever I read on the web at the time I wrote tha tline, that is how you raise something to a power.
    pow() is a floating point function, and is only intended for use in code that needs floating point operations.

    Problem is, a lot of people (including presumably the author of your book, and of web pages you have read) believe that floating point is there to be used for any mathematical calculation. They are wrong. Floating point is an approximate representation of real numbers, and comes with disadvantages, such as finite precision and round-off error. A whole discipline of computer science (numerical analysis) is concerned with understanding and addressing the problems that arise when using floating point calculations in real-world algorithms.

    If you want to compute an integral value of 2 to some integral power, either use a loop, or use bitwise operations (on unsigned integral types).
    Right 98% of the time, and don't care about the other 3%.

    If I seem grumpy or unhelpful in reply to you, or tell you you need to demonstrate more effort before you can expect help, it is likely you deserve it. Suck it up, Buttercup, and read this, this, and this before posting again.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. how do I convert a long long int into a char array?
    By Once-ler in forum C Programming
    Replies: 15
    Last Post: 02-22-2013, 01:46 PM
  2. How to convert char array of 64 bytes to long long int
    By pkumarn in forum C Programming
    Replies: 19
    Last Post: 03-06-2012, 02:23 AM
  3. Replies: 7
    Last Post: 08-21-2011, 10:49 AM
  4. number bigger than long long double
    By suryak in forum C Programming
    Replies: 9
    Last Post: 08-18-2011, 02:02 PM
  5. Replies: 1
    Last Post: 04-23-2011, 08:40 PM