Thread: How to get back-to-back digits from the first line in any file

  1. #1
    Registered User
    Join Date
    Jun 2019
    Posts
    44

    How to get back-to-back digits from the first line in any file

    X1.txt
    Code:
    July15 
    July1 
    August15 
    August1
    I managed to get something done using C since my previous question. I finally thought to extract the lines I needed instead of deleting the ones I don’t. I’ts not perfect but it’s better then nothing. Now I’m trying to get the digits that are in the first line in a file and copy them to array_2 so that I can operate on it latter. This code can only get one digit and that’s no good. What is needed to make this work?


    Code:
    #include <string.h>
    #include <stdio.h>
    #include <ctype.h>
    
    #define BUFFER_MAX 512
    #define MEM (BUFFER_MAX+1)
    
    FILE *fptr, *fptw;
    char array_1[MEM];
    char array_2[MEM];
    
    int main()
    {
    
      unsigned int len1;
      unsigned int len2;
    
      fptw = fopen("X2.txt", "w");
      fclose(fptw);
    
      // read file into a buffer.
      fptr = fopen("X1.txt", "r");
      len1 = fread(array_1, sizeof(char), BUFFER_MAX, fptr);
      array_1[len1] = '\0';
      fclose(fptr);
    
      // get digits from the first line in a file.
      char *s = array_1;
      if (!isdigit(*s)) {
        while (*s && !isdigit(*++s));
      }
      if (*s)
        putchar(*s);
    
      printf("  size=\%db.  One number missing.\n", len1);
      return 0;
    }
    Result: 1 size=30b. one number missing.
    Last edited by Salem; 07-08-2019 at 09:04 PM. Reason: Ugh, font abuse

  2. #2
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Write a function to extract the digits in a string. Test it. After you are sure, you can then use this function on the lines of your text file by reading them as strings.
    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

  3. #3
    Registered User
    Join Date
    Jun 2019
    Posts
    44
    If it’s out there, I read and tested tons of C functions doing these past hours that will not grab more then one plain number just like the block in my example. This is strike-3 for me.

    I keep coming back to this since nothing works off the WWW and nothing that I can figure:: Is there a way to make this loop or continue to get the 2nd number directly next to it if any?


    Code:
    char *s = array_1;
    if (!isdigit(*s)) {
      while (*s && !isdigit(*++s));
    }
    if (*s)
      putchar(*s);
    
    printf("  size=\%db.  One number missing.\n", len1);
    Last edited by Salem; 07-08-2019 at 09:02 PM. Reason: Ugh, font abuse!

  4. #4
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    I was thinking along the lines of:
    Code:
    char *extract_consecutive_digits(const char *input, char *output, size_t output_size)
    {
        const char *digits = input + strcspn(input, "0123456789");
        size_t i = 0;
        while (i < output_size - 1 && isdigit(digits[i]))
        {
            output[i] = digits[i];
            ++i;
        }
        output[i] = '\0';
        return output;
    }
    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

  5. #5
    Registered User
    Join Date
    Jun 2019
    Posts
    44
    I finally got something to work! It was there aready. I just needed to print the s-varable.

    Code:
      printf(s);
    
    
    fopen( "c.txt", "wb" );
    fwrite( s, 1, 3, fptw );
    fclose(fptw);

    Theres a warning but I'm not going to let it worry me right now.

    Code:
    
    /matchDate.c:55:10: warning: format string is not a
          string literal (potentially insecure) [-Wformat-security]
      printf(s);
             ^
    1 warning generated.
    

  6. #6
    TEIAM - problem solved
    Join Date
    Apr 2012
    Location
    Melbourne Australia
    Posts
    1,907
    Quote Originally Posted by jc2020 View Post
    I finally got something to work! It was there aready. I just needed to print the s-varable.

    Code:
      printf(s);
    
    
    fopen( "c.txt", "wb" );
    fwrite( s, 1, 3, fptw );
    fclose(fptw);

    Theres a warning but I'm not going to let it worry me right now.

    Code:
    
    /matchDate.c:55:10: warning: format string is not a
          string literal (potentially insecure) [-Wformat-security]
      printf(s);
             ^
    1 warning generated.
    
    It's a security weakness.

    See Denial of Service here
    Fact - Beethoven wrote his first symphony in C

  7. #7
    Registered User
    Join Date
    Jun 2019
    Posts
    44

    Hi @
    Click_here
    Format String parameter, like %x, is inserted into the posted data …

    1) Would this security issue only apply when a user on the same machine has access to input data at the command-line?

    2) Would this effect a standalone c-program running inside a jail which has no connection to the internet what-so-ever?

    3) Or could this type of program running as described in question-2; be vulnerable at an un-trusted administrator at a data center running under a VPS?


  8. #8
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    It's not just a security issue, it's a potential bug even under normal usage by a trusted user: if the string accidentally is constructed to contain a format specification, the behaviour is then undefined. It's only not a bug if you have constructed the format string from a string literal itself such that you are sure that it cannot contain anything that will be specially interpreted as part of a format string. It is a potential bug in all other cases, regardless of where you deploy the program.

    As for how much of a security issue it could be: in each of your cases, ask yourself if a malicious user could control the input.
    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 2019
    Posts
    44
    Thanks you for the explanation @laserlight and @Click_here for bringing this to the light.


    I always figure it depends on the situation but those hints are never included. Now I know on a scale of 0 -100% safety, it is still a potential bug. I’m happy to know this because I will not be leaving any form of print() functions in production code. That little piece of isdigit code works flawlessly so I removed:
    Code:
    if(*s)
    putchar(*s);
    printf(s);

    … and now the warning is gone.

    The key is how you save with fwrite to get more back-to-back numbers to show. Now things are finally becoming clear to me.
    Last edited by jc2020; 07-08-2019 at 11:53 PM.

  10. #10
    TEIAM - problem solved
    Join Date
    Apr 2012
    Location
    Melbourne Australia
    Posts
    1,907
    Would this effect a standalone c-program running inside a jail which has no connection to the internet what-so-ever?
    It's those sort of assumptions that people look for.

    Remember, just because we can't think of a way someone can access the programme, doesn't mean someone else can't.

    An example of this is when people leave their 2nd story balcony door open on hot days with the assumption that no one can get on it - Makes sense, right? But for someone who wants to get in, all they would need is a ladder. You could then say, "but someone will see them working up to the house with a ladder" - But most houses keep their ladders outside up against the house... My point is that when you start making assumptions, you need to understand that they are sometimes wrong.

    Don't leave a window open in your code and think that no one will think of a way to get to it.


    My only remaining question is how would I save it to array_2 so I can operation on it latter before closing the program? or how to use memcopy I guess?
    strncpy is probably what you are after.
    Fact - Beethoven wrote his first symphony in C

  11. #11
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Quote Originally Posted by jc2020
    I finally got something to work! It was there aready.
    That's only true if you know for sure that the input ends in digits only.

    Quote Originally Posted by jc2020
    I will not be leaving any form of print() functions in production code.
    If you want to print to standard output, printf is fine. It was your use of it that was problematic. You could have written:
    Code:
    printf("%s\n", s);
    You will find a similiar idea if you ever deal with SQL and database libraries: to avoid SQL injection, the best practice is to separate the data from the code. For such databases, the code is the SQL code with placeholders and the data consists of the values/variables to be bound to the placeholders, whereas for printf, the "code" is the format string with format specifiers and the "data" consists of arguments corresponding to the format specifiers.
    Last edited by laserlight; 07-09-2019 at 12:43 AM.
    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

  12. #12
    Registered User
    Join Date
    Jun 2019
    Posts
    44
    If you want to print to standard output, printf is fine.

    Thanks for telling me that @laserlight. Earlier I just realize I should have never said that because it’s seem to be wise to keep some printf permanently in the code. If my program crash because of changes in a text file or something, the last printf result would be the closest to the problematic code. There will be no need to write error checking every step of the way. .. Maybe so?


    I read you loud and clear @Click_here!

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 2
    Last Post: 01-12-2016, 11:31 AM
  2. How do I back up a line with ifstream?
    By Programmer_P in forum C++ Programming
    Replies: 2
    Last Post: 04-20-2011, 01:50 PM
  3. Some woman back ended my car today, and back hurts
    By Terrance in forum A Brief History of Cprogramming.com
    Replies: 19
    Last Post: 08-20-2003, 12:42 AM
  4. back a line
    By madmardigan53 in forum A Brief History of Cprogramming.com
    Replies: 5
    Last Post: 08-04-2003, 05:19 PM
  5. Replies: 1
    Last Post: 10-21-2002, 02:32 PM

Tags for this Thread