Thread: scanf confusion

  1. #1
    Registered User
    Join Date
    Jun 2009
    Posts
    486

    scanf confusion

    Hey all, another question for you.

    I have an input file consisting of three columns of double values representing x,y,z coordinates. I need to read them into an array. Now, my code works, but the compiler complains that I don't check the return value from fscanf - just a warning, the code still runs fine. But I tried to rewrite to check the return value anyway. It seems to read the values in fine, but when I go to reprint the array to check, all the values are 0. Any idea why?

    Here is the working code. The printf both inside and outside the loop print the same thing.

    Code:
    for (i = 0; i < N_part; i++)
      {
        fscanf(particleList,"%lf%lf%lf", &particleMatrix[i][0], &particleMatrix[i][1], &particleMatrix[i][2]);
        printf("%f\t%f\t%f\n",particleMatrix[i][0], particleMatrix[i][1], particleMatrix[i][2]);
        if (particleMatrix[i][0] * particleMatrix[i][0] + particleMatrix[i][1] * particleMatrix[i][1] + particleMatrix[i][2] * particleMatrix[i][2] > maxRadiusSquared)
        { 
          maxRadiusSquared = particleMatrix[i][0] * particleMatrix[i][0] + particleMatrix[i][1] * particleMatrix[i][1] + particleMatrix[i][2] * particleMatrix[i][2];
        }
      }  
      maxRadius = sqrt(maxRadiusSquared);//Radius of the cluster
    
    for (i = 0; i < N_part; i++)
    {
       printf("%f\t%f\t%f\n",particleMatrix[i][0], particleMatrix[i][1], particleMatrix[i][2]);
    }
    Here is the nonworking code - the inside printf prints what it should, but the one outside prints 0's.

    Code:
    while (fscanf(particleList,"%lf%lf%lf", &particleMatrix[i][0], &particleMatrix[i][1], &particleMatrix[i][2]) != EOF)
      { 
        maxRadiusSquared = particleMatrix[i][0] * particleMatrix[i][0] + particleMatrix[i][1] * particleMatrix[i][1] + particleMatrix[i][2] * particleMatrix[i][2];
        printf("%f\t%f\t%f\n",particleMatrix[i][0], particleMatrix[i][1], particleMatrix[i][2]);
      }
    
    
      maxRadius = sqrt(maxRadiusSquared);
    
    for (i = 0; i < N_part; i++)
    {
       printf("%f\t%f\t%f\n",particleMatrix[i][0], particleMatrix[i][1], particleMatrix[i][2]);
    }
    I am sure I am just using fscanf wrong in the second one, but how?

  2. #2
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    You could change i at some point, if you want to move forward in the array.

  3. #3
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    What is the initial value of "i" in the while loop in the non-working example? And subsequently?

    [aside] this is an interesting hybrid of the "mk27" and "allman" indentation styles Now I understand why I am losing in the pole...
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

  4. #4
    Frequently Quite Prolix dwks's Avatar
    Join Date
    Apr 2005
    Location
    Canada
    Posts
    8,057
    Also, I'd suggest a
    Code:
    #define SQUARE ((x) * (x))
    or
    Code:
    double square(double number) {
        return number * number;
    }
    and an intermediate variable to shorten that really long radius-square expression calculation.

    With your second version, you should probably also record how many particles you read (how high i becomes, once you start incrementing it as per tabstop's post!), instead of looping up until N_part.
    dwk

    Seek and ye shall find. quaere et invenies.

    "Simplicity does not precede complexity, but follows it." -- Alan Perlis
    "Testing can only prove the presence of bugs, not their absence." -- Edsger Dijkstra
    "The only real mistake is the one from which we learn nothing." -- John Powell


    Other boards: DaniWeb, TPS
    Unofficial Wiki FAQ: cpwiki.sf.net

    My website: http://dwks.theprogrammingsite.com/
    Projects: codeform, xuni, atlantis, nort, etc.

  5. #5
    Registered User
    Join Date
    Jun 2009
    Posts
    486
    Hahahaha wow, what a dumb mistake. I am so used to using for loops that I competely forgot the increment step in the while loop. Lol...

    Thanks for the tips, but in comparison to other parts of the code, that part takes less than 0.1% of the runtime, so making that faster won't really do anything.

    And yeah, sorry about the indentation, I ended up adding a few things afterward and just added them here instead, so the indentatin got messed up. My code looks prettier, honest!

  6. #6
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Quote Originally Posted by KBriggs
    I am so used to using for loops that I competely forgot the increment step in the while loop.
    I suggest that you use a for loop, but incorprate the check of fscanf's return value with the i < N_part condition.
    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

  7. #7
    Registered User
    Join Date
    Jun 2009
    Posts
    486
    You mean:

    Code:
    for (i = 0; i < N_part && fscanf(particleList,"%lf%lf%lf", &particleMatrix[i][0], &particleMatrix[i][1], &particleMatrix[i][2]) != EOF; i++)
      { 
        maxRadiusSquared = particleMatrix[i][0] * particleMatrix[i][0] + particleMatrix[i][1] * particleMatrix[i][1] + particleMatrix[i][2] * particleMatrix[i][2];
        printf("%f\t%f\t%f\n",particleMatrix[i][0], particleMatrix[i][1], particleMatrix[i][2]);
      }

  8. #8
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Quote Originally Posted by KBriggs
    You mean:
    Yeah, though if I were you, I would define:
    Code:
    int readParticle(FILE *file, double particle[3])
    {
        return fscanf(file, "%lf%lf%lf", &particle[0], &particle[1], &particle[2]);
    }
    
    void printParticle(FILE *file, double particle[3])
    {
        fprintf(file, "%f\t%f\t%f\n", particle[0], particle[1], particle[2]);
    }
    
    double computeMaxRadiusSquared(double particle[3])
    {
        return particle[0] * particle[0]
            + particle[1] * particle[1]
            + particle[2] * particle[2];
    }
    Then write:
    Code:
    for (i = 0; i < N_part && readParticle(particleList, particleMatrix[i]) != EOF; ++i)
    {
        maxRadiusSquared = computeMaxRadiusSquared(particleMatrix[i]);
        printParticle(stdout, particleMatrix[i]);
    }
    I assume that you will actually do more with maxRadiusSquared than assign to it on each iteration of the loop.
    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

  9. #9
    Registered User
    Join Date
    Jun 2009
    Posts
    486
    Yeah, it becomes a parameter for other functions through the program, all this stuff is just initializing. Thanks for the tips, I suppose it couldn't hurt to break the program up a little more, right now each function does quite a bit of stuff.

    That should actually be

    if (maxRadiusSquared > currentMaxRadius)
    {
    maxRadiusSquared = currentMaxRadius;
    }
    but since my list is sorted right now it is irrelevent. I had that elsewhere... I must have removed it when I redid the loop and forgot to put it back. Thanks.
    Last edited by KBriggs; 06-06-2009 at 11:31 AM.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Help with a basic scanf procedure.
    By killpoppop in forum C Programming
    Replies: 9
    Last Post: 11-03-2008, 04:39 PM
  2. Scanf confusion, 2 dimensional array modification
    By Leojeen in forum C Programming
    Replies: 23
    Last Post: 10-19-2008, 10:58 PM
  3. scanf issue
    By fkheng in forum C Programming
    Replies: 6
    Last Post: 06-20-2003, 07:28 AM
  4. Scanf and integer...
    By penny in forum C Programming
    Replies: 3
    Last Post: 04-24-2003, 06:36 AM
  5. scanf - data is "put back" - screws up next scanf
    By voltson in forum C Programming
    Replies: 10
    Last Post: 10-14-2002, 04:34 AM