Thread: Program to find two consecutive numbers from a text file.

  1. #1
    Registered User
    Join Date
    May 2017
    Posts
    61

    Program to find two consecutive numbers from a text file.

    The program is working but if anyone know more efficient ways please let me know.

    Side question about strings.

    Why i need to use

    char * string[100] and i canīt use char * string ?

    Text File:
    DIM: 4
    Linha0: 12 4 60 60
    Linha1: 3 7 3 5
    Linha2: -56 31 31 12
    Linha3: 34 -33 2 4

    Code:
    #include <stdio.h>
    #include <stdlib.h>
    
    
    int main(int argc, char** argv) {
    
    
        FILE *pFile = fopen("ex1.txt", "rt");
    
    
        char * string[100];
        int size;
        int numbers[4];
    
    
        if (pFile) {
            // To consume the 1 line
            fscanf(pFile, "%s %d", string, &size);
    
    
            // To consume  the others lines
            while (fscanf(pFile, "%s %d %d %d %d", string, &numbers[0], &numbers[1], &numbers[2], &numbers[3]) == 5) {
                for (int i = 0; i < size - 1; i++) {
                    if (numbers[i] == numbers[i + 1])
                        printf("The numbers %d %d, are equals\n", numbers[i], numbers[i + 1]);
                }
            }
    
        } else {
            printf("Error opening the file");
        }
            fclose(pFile);
    
        return (EXIT_SUCCESS);
    }

  2. #2
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,661
    Are you compiling with -Wall yet?
    Code:
    $ gcc -Wall foo.c
    foo.c: In function ‘main’:
    foo.c:18:23: warning: format ‘%s’ expects argument of type ‘char *’, but argument 3 has type ‘char **’ [-Wformat=]
             fscanf(pFile, "%s %d", string, &size);
                           ^
    foo.c:22:30: warning: format ‘%s’ expects argument of type ‘char *’, but argument 3 has type ‘char **’ [-Wformat=]
             while (fscanf(pFile, "%s %d %d %d %d", string, &numbers[0], &numbers[1], &numbers[2], &numbers[3]) == 5) {
                                  ^
    It only 'works' because you're lucky enough that "char * string[100]" allocates probably 400 or 800 bytes of memory for you to play with.

    > char * string[100] and i canīt use char * string ?
    Because char *string by itself doesn't point to any useful memory.

    Try
    Code:
    char string[100];
    or
    Code:
    char *string = malloc(100);
    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.

  3. #3
    Registered User
    Join Date
    May 2017
    Posts
    61
    Great great...

    I really "hate" Netbeans, this semester they force us to use that compiler because the C99 Standard but even the teachers donīt know very well to work with Netbeans.

    I already use Visual Studio a little before, and i was really missing the -Wall, now i already activated.

    Other thing i really hate at netbeans sometimes my code is 100% i make some correction lots of code go to red, and then the red only go away after i need rebuild the code again...

    And some other minors things.

    What program you recommend to code ?


    Quote Originally Posted by Salem View Post
    Are you compiling with -Wall yet?
    Code:
    $ gcc -Wall foo.c
    foo.c: In function ‘main’:
    foo.c:18:23: warning: format ‘%s’ expects argument of type ‘char *’, but argument 3 has type ‘char **’ [-Wformat=]
             fscanf(pFile, "%s %d", string, &size);
                           ^
    foo.c:22:30: warning: format ‘%s’ expects argument of type ‘char *’, but argument 3 has type ‘char **’ [-Wformat=]
             while (fscanf(pFile, "%s %d %d %d %d", string, &numbers[0], &numbers[1], &numbers[2], &numbers[3]) == 5) {
                                  ^
    It only 'works' because you're lucky enough that "char * string[100]" allocates probably 400 or 800 bytes of memory for you to play with.

    > char * string[100] and i canīt use char * string ?
    Because char *string by itself doesn't point to any useful memory.

    Try
    Code:
    char string[100];
    or
    Code:
    char *string = malloc(100);

  4. #4
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,661
    > I really "hate" Netbeans, this semester they force us to use that compiler
    Netbeans is an IDE (a glorified text editor), not a compiler.

    You can use any text editor you like.

    I'm guessing you're using Windows, in which case I would suggest Notepad++ Home (or perhaps Notepad++ Alternatives and Similar Software - AlternativeTo.net)

    The basic difference is
    - with an IDE, you can press a toolbar button labelled "compile", error messages are parsed automatically and you can run/debug all without pressing alt-tab.
    - with a simple editor, you have to switch back to a console and recall the previous compile command, and do other things that involve a few extra keys.
    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.

  5. #5
    Registered User
    Join Date
    May 2017
    Posts
    61
    I am try to transform the program into a generic one, so the matrix could be DIM 2 or DIM 10 for example.

    But i am not see what function should i use.

    I was trying with sscanf but with start always from the begin of the buffer each time i use it.

    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #define LENGTH 100
    
    
    int main(int argc, char** argv) {
    
    
        FILE *pFile = fopen("ex1.txt", "rt");
    
    
        char buffer[LENGTH];
        int * vector;
        size_t size;
        
        if (pFile != NULL) {
            
            fgets(buffer, sizeof (buffer), pFile);
            sscanf(buffer, "%*s %d", &size); // %*s - Consume and throw away, and get the size of the matrix
            
            vector = malloc(sizeof (int) * size);
    
    
            while (fgets(buffer, sizeof (buffer), pFile)) {
                sscanf(buffer, "%*s"); 
    
    
                for (int i = 0; i < size; i++) {
                    sscanf(buffer, "%d", &vector[i]);
                    printf("%d \n", vector[i]); // Only prints garbage
                }
            }
    
    
            fclose(pFile);
            return (EXIT_SUCCESS);
        }
    }

  6. #6
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,661
    Perhaps the easiest way to walk through a line on integers is by using https://linux.die.net/man/3/strtol

    The jist of it being something like
    Code:
    char *p = buff;
    long int n;
    while ( (n=strtol(p, &p, 0)) && errno == 0 ) {
      printf("Read %ld\n", n );
    }
    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.

  7. #7
    Registered User
    Join Date
    May 2017
    Posts
    61
    Quote Originally Posted by Salem View Post
    Perhaps the easiest way to walk through a line on integers is by using strtol(3): convert string to long integer - Linux man page

    The jist of it being something like
    Code:
    char *p = buff;
    long int n;
    while ( (n=strtol(p, &p, 0)) && errno == 0 ) {
      printf("Read %ld\n", n );
    }
    Maybe i am missing something i donīt full understand that function.

    But if my text file is

    DIM: 1
    12 4 60 60

    Works nice but if it have a string before the numbers does not work correctly.

    DIM: 1
    Linha0: 12 4 60 60
    Last edited by thinkabout; 07-11-2017 at 08:37 AM.

  8. #8
    Registered User
    Join Date
    May 2017
    Posts
    61
    Working but what a mess...

    Code:
            while (fgets(buffer, sizeof (buffer), pFile)) {
                char *p = buffer;
    
                while (*p) {
                    if (isdigit(*p) && (*(p + 1)) != ':') {
                        long value = strtol(p, &p, 0); // 
                        printf("%ld\n", value);
                    } else {
                        p++;
                    }
                }
            }

  9. #9
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,661
    Perhaps post some lines from your file.
    Just guessing that you have : separated numbers.
    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.

  10. #10
    Registered User
    Join Date
    May 2017
    Posts
    61
    Quote Originally Posted by Salem View Post
    Perhaps post some lines from your file.
    Just guessing that you have : separated numbers.
    It was on the first post, but yeah the thread is already a little old and long, so easily miss.

    Text File:
    DIM: 4
    Linha0: 12 4 60 60
    Linha1: 3 7 3 5
    Linha2: -56 31 31 12
    Linha3: 34 -33 2 4
    Last edited by thinkabout; 07-11-2017 at 08:44 AM.

  11. #11
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,661
    So your numbers are not actually separated by : then.

    Code:
    int lineNum, numChars;
    if ( sscanf(buffer,"Linha%d:%n",&lineNum,&numChars) == 1 ) {  // %n does NOT count as a conversion
       char *p = buffer + numChars;
       // now you can walk the line using a much simpler strtol loop
    }
    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.

  12. #12
    Registered User
    Join Date
    May 2017
    Posts
    61
    Quote Originally Posted by Salem View Post
    So your numbers are not actually separated by : then.

    Code:
    int lineNum, numChars;
    if ( sscanf(buffer,"Linha%d:%n",&lineNum,&numChars) == 1 ) {  // %n does NOT count as a conversion
       char *p = buffer + numChars;
       // now you can walk the line using a much simpler strtol loop
    }
    Finally working... Thanks a million.

    Still going to need to read about strtol when i got some time.

    I still didn't yet grasp the concept of it the endptr parameter.

    strtol - C++ Reference.


    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #define LENGTH 100
    
    
    int main(int argc, char** argv) {
    
    
        FILE *pFile = fopen("ex1.txt", "rt");
    
    
        char buffer[LENGTH];
        int * vector;
        size_t size;
    
    
        if (pFile != NULL) {
    
    
            fgets(buffer, sizeof (buffer), pFile);
            sscanf(buffer, "%*s %d", &size); // %*s - Consume and throw away, and get the size of the matrix
    
    
            vector = malloc(sizeof (int) * size);
    
    
            int lineNum, numChars;
            int value;
            int count = 0;
            while (fgets(buffer, sizeof (buffer), pFile)) {
                if (sscanf(buffer, "Linha%d:%n", &lineNum, &numChars) == 1) { // %n does NOT count as a conversion, it counts the numbers of caracters https://stackoverflow.com/questions/3401156/what-is-the-use-of-the-n-format-specifier-in-c
                    char *p = buffer + numChars;                
    
    
                    while ((value = strtol(p, &p, 0)) && errno == 0) {
                        vector[count] = value;
                        count++;
                    }
                    count = 0;
                  
                    for (int i = 0; i < size - 1; i++) {
                        if (vector[i] == vector[i + 1])
                            printf("The numbers %d %d, are equals\n", vector[i], vector[i + 1]);
                    }
                }
            }
    
    
            free(vector);
            fclose(pFile);
            return (EXIT_SUCCESS);
        }
    }

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 7
    Last Post: 04-07-2013, 03:45 PM
  2. consecutive numbers
    By SDH in forum C Programming
    Replies: 27
    Last Post: 01-22-2013, 05:24 AM
  3. Replies: 10
    Last Post: 02-08-2012, 03:17 PM
  4. To Find Largest Consecutive Sum Of Numbers In 1D Array
    By chottachatri in forum C Programming
    Replies: 22
    Last Post: 07-10-2011, 01:43 PM
  5. Comparing numbers to a list of numbers held in a text file
    By jmajeremy in forum C++ Programming
    Replies: 3
    Last Post: 11-06-2006, 07:56 AM

Tags for this Thread