Thread: matching the newline

  1. #1
    Registered User
    Join Date
    Jul 2005
    Posts
    14

    matching the newline

    hi all, i'm so mess up with this problem.
    suppose a data file Data.dat:

    0 1 3 4
    1 3
    2 4

    how can i stop read those numbers when matching the newline?
    PS: # of numbers must be counted.


    Thanks

  2. #2
    Registered User
    Join Date
    Jul 2005
    Posts
    14
    This my code

    Code:
      int main()
    
    {
      
      int i,j;
      int z[500];
      FILE *num_cluster=NULL;
      num_cluster = fopen("clus_size.dat","r");
         i=0;
         while(fscanf(num_cluster, "%d", &z[500])!=EOF)
        {
              printf("%d\n", z[500]);
              if(z[500]=='\n'){
                break;
                printf("newline matched, stop reading file!\n");
               }
               i++;
         }
      
         fclose(num_cluster);
        return 0;
    }

  3. #3
    Registered User mitakeet's Avatar
    Join Date
    Jun 2005
    Location
    Maryland, USA
    Posts
    212
    All wrong. RTFM scanf before you go much further!

    Try this (compiled, but not tested):

    Code:
    #include <stdio.h>
    #include <stdlib.h>
    
    int main() {
        int i,j;
        int z[500];
        FILE *num_cluster=NULL;
        num_cluster = fopen("clus_size.dat","r");
        if (!num_cluster){
            fprintf(stderr, "Can't open input file!\n");
            exit(1);
        }
    
        i=0;
        while(fscanf(num_cluster, "%d", &z[i]) == 1) {
            printf("%d\n", z[i]);
            i++;
            if (i>=500){
                fprintf(stderr, "Too many numbers!\n");
                break;
            }
        }
    
        fclose(num_cluster);
        return 0;
    }
    This won't help you read in one line's worth at a time, you will have to do your own buffering for that.

    Free code: http://sol-biotech.com/code/.

    It is not that old programmers are any smarter or code better, it is just that they have made the same stupid mistake so many times that it is second nature to fix it.
    --Me, I just made it up

    The reasonable man adapts himself to the world; the unreasonable one persists in trying to adapt the world to himself. Therefore, all progress depends on the unreasonable man.
    --George Bernard Shaw

  4. #4
    Registered User mitakeet's Avatar
    Join Date
    Jun 2005
    Location
    Maryland, USA
    Posts
    212
    This will do what you want, though it is quite sensitive to the format of your input file (it basically requires that there be a linefeed immediately after the last number):

    Code:
    #include <stdio.h>
    #include <stdlib.h>
    
    int main() {
        int i,j, chr;
        int z[500];
        char buf[40];
        FILE *num_cluster=NULL;
        num_cluster = fopen("clus_size.dat","r");
        if (!num_cluster){
            fprintf(stderr, "Can't open input file!\n");
            exit(1);
        }
    
        i=0;
        while(fscanf(num_cluster, "%39s", buf) == 1) {
            z[i] = atoi(buf);
            printf("%d ", z[i]);
            if ((chr = getc(num_cluster)) == '\n'){
                printf("We found a linefeed!\n");
            }else{
                ungetc(chr, num_cluster);
            }
            i++;
            if (i>=500){
                fprintf(stderr, "Too many numbers!\n");
                break;
            }
        }
    
        fclose(num_cluster);
        return 0;
    }

    Free code: http://sol-biotech.com/code/.

    It is not that old programmers are any smarter or code better, it is just that they have made the same stupid mistake so many times that it is second nature to fix it.
    --Me, I just made it up

    The reasonable man adapts himself to the world; the unreasonable one persists in trying to adapt the world to himself. Therefore, all progress depends on the unreasonable man.
    --George Bernard Shaw

  5. #5
    Registered User
    Join Date
    Jul 2005
    Posts
    14
    Thanks for that , I forgot to say that i am not good in C programming , I just start to do so , so please help me !!!

  6. #6
    Registered User
    Join Date
    Jul 2005
    Posts
    14
    Thaks mitakeet , But it doesn't work !!!

  7. #7
    Just Lurking Dave_Sinkula's Avatar
    Join Date
    Oct 2002
    Posts
    5,005
    If you're just going to read the first line, then consider reading it into a string using fgets. Then you can parse the string into individual values.
    Code:
    #include <stdio.h>
    
    int main()
    {
       FILE *file = fopen("file.txt","r");
       if ( file != NULL )
       {
          char line[BUFSIZ];
          /*
           * Read the line of text.
           */
          if ( fgets(line, sizeof line, file) != NULL )
          {
             int i = 0, j, n, z[500];
             char *ptr = line;
             fclose(file);
             /*
              * Parse the numbers from the string.
              */
             while ( sscanf(ptr, "%d%n", &z[i], &n) == 1 )
             {
                ptr += n;
                ++i;
             }
             /*
              * Output the data.
              */
             for ( j = 0; j < i; ++j )
             {
                printf("z[%d] = %d\n", j, z[j]);
             }
          }
       }
       return 0;
    }
    
    /* file.txt
    0 1 3 4
    1 3
    2 4
    */
    
    /* my output
    z[0] = 0
    z[1] = 1
    z[2] = 3
    z[3] = 4
    */
    7. It is easier to write an incorrect program than understand a correct one.
    40. There are two ways to write error-free programs; only the third one works.*

  8. #8
    Registered User
    Join Date
    Jul 2005
    Posts
    14
    Thanks Dave_Sinkula , But I would like the out put will be same as the data file !!! any help

  9. #9
    Registered User
    Join Date
    Mar 2002
    Posts
    1,595
    First, a disclaimer---I don't use C style I/O very much so take everything here with a grain of salt, look it up yourself, and/or verify my ideas before trying them out yourselr.

    Second, I assume a line is defined as a string ending with a newline char as opposed to line on the screen, etc.

    Given that, when I looked it up fscanf(), it appears to stop input into a string at whitespaces. Therefore, I doubt that fscanf() will differentiate between spaces, newline char, tabs, etc, as the terminating char. So how could you tell when you reached the end of a line to stop counting the number of ints on the line?

    fgetc() apparently reads one char at a time. Therefore the input could be assessed char by char, with the number of ints being counted until a newline char is found. However, what happens if the int in the file has more than one digit?

    fgets() apparently reads up to a specified number of char into the given string or until a newline or EOF is encountered. Therefore, you could read a whole line at a time into a string at a time. Once you have isolated a string of chars representing a given line you could then count the number of white spaces in the string and add 1 to get a rough idea of the number of ints or get a better count by parsing the original string into substrings using strtok() and counting the number of substrings isolated, or parsing the original string into substrings using sscanf() and counting the number of substrings identified, or whatever other technique you want to try.
    You're only born perfect.

  10. #10
    Registered User mitakeet's Avatar
    Join Date
    Jun 2005
    Location
    Maryland, USA
    Posts
    212
    The problem with fgets() (and why I didn't use it) is that if you have lines longer than your buffer you get truncation with the next read being the remainder of the buffer (presuming it is still large enough). That means you have to have complex code to detect when you have more data remaining and have to stitch together the remaining bits from the previous read. If you can use C++ use the string class and the version of getline in <string> and then parse with a stringstream.

    Free code: http://sol-biotech.com/code/.

    It is not that old programmers are any smarter or code better, it is just that they have made the same stupid mistake so many times that it is second nature to fix it.
    --Me, I just made it up

    The reasonable man adapts himself to the world; the unreasonable one persists in trying to adapt the world to himself. Therefore, all progress depends on the unreasonable man.
    --George Bernard Shaw

  11. #11
    Just Lurking Dave_Sinkula's Avatar
    Join Date
    Oct 2002
    Posts
    5,005
    Quote Originally Posted by mitakeet
    The problem with fgets() (and why I didn't use it) is that if you have lines longer than your buffer you get truncation with the next read being the remainder of the buffer (presuming it is still large enough).
    Well, there is a similar issue with the size of the string to contain the text representation of the integer value. That one is just buried deeper. Such a thing could be portablized, but that is a bit icky.

    [edit]Although the 40-char buffer would be good enough for a 126-bit integer, so it would be a safe assumption for quite some time one would think.
    Last edited by Dave_Sinkula; 07-14-2005 at 01:53 PM.
    7. It is easier to write an incorrect program than understand a correct one.
    40. There are two ways to write error-free programs; only the third one works.*

  12. #12
    Registered User
    Join Date
    Jul 2005
    Posts
    14
    Thanks alot Dave_Sinkula , it works , and as what i need , agian thanks alot

  13. #13
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    Well since we're all having fun here, here's a variation of a theme...
    Code:
    int c, l = 0, x=0, array[ BUFSIZ ] = {0};
    while ( (c = fgetc( fp )) != EOF && c != '\n' )
    {
        if ( isdigit( c ) )
        {
            if ( isdigit( l ) )
                array[ x ] *= 10;
            array[ x ] += c - '0';
        }
        else
        if( isdigit( l ) )
            x++;
        l = c;
    }
    I think that'll do the trick.

    [edit] I think that fixes an indexing bug where the last character wasn't a digit so it incremented too much. Haven't tested that last change. [/edit]

    Quzah.
    Last edited by quzah; 07-14-2005 at 01:10 PM.
    Hope is the first step on the road to disappointment.

  14. #14
    Registered User
    Join Date
    Jul 2005
    Posts
    14
    Hi quzah

    Please could you explain to me , i didn't understand what you did , I am not very good in C

  15. #15
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    I read the file one character at a time, and if it's not the end of file marker (EOF) or a newline, I process that character. We use the following:

    a) If it is a digit (0 - 9), we use the current array spot for it. First, we multiply what's there by 10, and then add this character's decimal value. This allows us to read numbers that are bigger than one digit correctly. (At least until you overflow your integer, but that's a different issue...)
    b) If it's not a digit, but the last character we read was a digit, we have to advance our array's index.
    c) Finally, we copy this character to the "last character" place holder so we can use it for future reference (as we do in step b).


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

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 5
    Last Post: 06-01-2009, 07:54 PM
  2. Matching numbers
    By kirksson in forum C Programming
    Replies: 7
    Last Post: 07-23-2008, 01:51 PM
  3. Possible circular definition with singleton objects
    By techrolla in forum C++ Programming
    Replies: 3
    Last Post: 12-26-2004, 10:46 AM
  4. Brace matching
    By coskun in forum C Programming
    Replies: 6
    Last Post: 07-30-2004, 06:45 AM
  5. Going out of scope
    By nickname_changed in forum C++ Programming
    Replies: 9
    Last Post: 10-12-2003, 06:27 PM