Thread: reading two numbers in the same line from a file

  1. #1
    Registered User
    Join Date
    Aug 2011
    Posts
    8

    reading two numbers in the same line from a file

    Hi,

    I am very new to C and I'm difficulty reading two specific numbers in the same line from a text file.

    For example, I have a txt file with lines that look like this:

    line 1 :000002 0.6749 0.3434 0.87 0.8234 -0.0003 0.345 121.77 0.673956 0.256482
    line 2: 000002 0.4738 0.1946 0.28 0.1659 -0.0002 0.562 103.67 0.194628 0.103829

    The highlighted numbers at the end of each line are the ones I want to read and then use them in a function. Let's say I wanted to write a program that would read and then add together the last two numbers of each line. So it would add the two red numbers together and then it would add the two green numbers together.

    I know how to use fgets to read multiple numbers if each line in the file is just one number, but that's all I know how to do. My program so far is:

    Code:
    #include <stdio.h>
    FILE *file;
    int main()
    {
    float limit;
    char line[50];
    file = fopen("nfile.txt", "r");
    while (fgets(line,20,file)!=NULL)
    {
    sscanf(line,"%f", &limit);
    printf("%.0f\n", limit);
    }
    fclose(file);
    return 0;
    }

  2. #2
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    Fgets() will read upto (and including) a newline if you give it a buffer big enough. There is no point in using tiny arrays like:

    Code:
    char line[50];
    Unless you are positive the lines are always that length. This space is from your stack memory, which is assigned by the OS is a big chunk (megabytes) whether you use it or not, so why not just:

    Code:
    char line[1024];
    Computers work well with power of two numbers and so they are good for memory assignments. 1Kb should be plenty of space. Now you can read in an entire line:

    Code:
    fgets(line, 1024, file);
    You can parse the line with sscanf(), as you are, or strtok(). Here's a hint about sscanf: the * qualifier tells (s)scanf to discard this item, ie, it is not put into a variable. So if I wanted the third number in the line:

    Code:
    if (sscanf(line, "%*f %*f %f", &limit) != 1) puts("scanf() failed!");
    Checking the return value of scanf to make sure it read 1 item (the discarded ones do not count) can save you a lot of hassle.
    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

  3. #3
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    > while (fgets(line,20,file)!=NULL)
    Well you need to pass a decently sized buffer to make sure you get the whole line.
    If line is a char array, then saying sizeof(line) is a nice way of keeping everything in sync.

    Then you could do something like
    sscanf(line, "%*f %*f %f", &result );

    Add as many %*f (or other %* formats) to skip what you're not interested in.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  4. #4
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    And if you don't know how many numbers are on each line ahead of time (e.g., if it changes from row to row), then you'll have to work a little harder since you can't use a single format string for all the lines.

  5. #5
    Banned
    Join Date
    Aug 2010
    Location
    Ontario Canada
    Posts
    9,547
    Quote Originally Posted by Telume9 View Post
    Hi,

    I am very new to C and I'm difficulty reading two specific numbers in the same line from a text file.

    For example, I have a txt file with lines that look like this:

    line 1 :000002 0.6749 0.3434 0.87 0.8234 -0.0003 0.345 121.77 0.673956 0.256482
    line 2: 000002 0.4738 0.1946 0.28 0.1659 -0.0002 0.562 103.67 0.194628 0.103829

    The highlighted numbers at the end of each line are the ones I want to read and then use them in a function.
    Those last two numbers are not uniquely marked in any way that makes them easy to discern from the rest, so read the whole line in with fscanf() to pull out all the numbers, and only use the last 2...
    Code:
    double num1, num2, total;
    double scrap;
    
    // open your file
    
    fscanf(FILE, "%lf %lf %lf %lf %lf %lf %lf %lf %lf %lf",&scrap,&scrap,&scrap,&scrap,&scrap,&scrap,&scrap,&scrap,&num1,&num2);
    total = num1 + num2;

  6. #6
    Registered User
    Join Date
    May 2011
    Location
    Around 8.3 light-minutes from the Sun
    Posts
    1,949
    ....or perhaps just use * so then you don't need the scrap variable.....
    Quote Originally Posted by anduril462 View Post
    Now, please, for the love of all things good and holy, think about what you're doing! Don't just run around willy-nilly, coding like a drunk two-year-old....
    Quote Originally Posted by quzah View Post
    ..... Just don't be surprised when I say you aren't using standard C anymore, and as such,are off in your own little universe that I will completely disregard.
    Warning: Some or all of my posted code may be non-standard and as such should not be used and in no case looked at.

  7. #7
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    fgets + strrchr + sscanf


    Quzah.
    Hope is the first step on the road to disappointment.

  8. #8
    Registered User
    Join Date
    Aug 2011
    Posts
    8
    oooooo, thank you all for the help it worked!

  9. #9
    Registered User
    Join Date
    Aug 2011
    Posts
    2
    Quote Originally Posted by Telume9 View Post
    oooooo, thank you all for the help it worked!
    to make your code simpler you can use the getline function ...this way you read a full line and the buffer is resized automatically if the line is longer than the preallocated one

    Then you can simply use strtok to tokenize the string into tokens.

    Should look something like this:
    Code:
    FILE *pFile = fopen(filename, "r+");
    //handle file not existing case ..
    
    int line_size = 0;
    size_t line_buffer_size = 100;
    char* line_buffer = malloc((line_buffer_size + 1) * sizeof(char));
    
    while ((line_size = getline(&line_buffer, &line_buffer_size, pFile)) != -1) {
         //tokenize string and get the values you need
         pch = strtok(result_array[i], "\t");
         int col = 0;
    
         while (pch != NULL) {
              pch = strtok(NULL, "\t");
              col++;
    	  if (col == #desired_col_number) {
                 // do stuff....
      	  }
          }
    }

  10. #10
    Registered User
    Join Date
    May 2011
    Location
    Around 8.3 light-minutes from the Sun
    Posts
    1,949
    Two things to note:

    1. The input file has a standard format so all the extra work for strtok does not make it an easier solution. In fact that makes it much harder and there are more areas for potential failure. The previous posted solutions are much simpler and easier to understand.

    2. getline is not a standard C function and thus the code is not portable.
    Quote Originally Posted by anduril462 View Post
    Now, please, for the love of all things good and holy, think about what you're doing! Don't just run around willy-nilly, coding like a drunk two-year-old....
    Quote Originally Posted by quzah View Post
    ..... Just don't be surprised when I say you aren't using standard C anymore, and as such,are off in your own little universe that I will completely disregard.
    Warning: Some or all of my posted code may be non-standard and as such should not be used and in no case looked at.

  11. #11
    Registered User
    Join Date
    Aug 2011
    Posts
    2
    1. yes true, I think I was aiming at a more generic solution ..rather than typing many %f's to skip the string.

    2.good point...this will only work using gnu gcc.

    Quote Originally Posted by AndrewHunter View Post
    Two things to note:

    1. The input file has a standard format so all the extra work for strtok does not make it an easier solution. In fact that makes it much harder and there are more areas for potential failure. The previous posted solutions are much simpler and easier to understand.

    2. getline is not a standard C function and thus the code is not portable.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 7
    Last Post: 12-13-2010, 02:13 PM
  2. Reading negative numbers from command line
    By Ace2187 in forum C Programming
    Replies: 3
    Last Post: 12-06-2009, 01:21 PM
  3. Reading Input from a file, line-by-line
    By Acolyte in forum C Programming
    Replies: 8
    Last Post: 09-30-2007, 01:03 PM
  4. Need help with reading numbers from the command line
    By Nterpol in forum C Programming
    Replies: 4
    Last Post: 06-01-2006, 01:40 AM
  5. reading a file line by line and char *
    By odysseus.lost in forum C Programming
    Replies: 8
    Last Post: 05-31-2005, 09:47 AM