Having command line displayed in output

This is a discussion on Having command line displayed in output within the C Programming forums, part of the General Programming Boards category; Hey guys: What i am trying to do is have an element in the command line effect my output. For ...

  1. #1
    Registered User
    Join Date
    Feb 2008
    Posts
    20

    Having command line displayed in output

    Hey guys: What i am trying to do is have an element in the command line effect my output.

    For example:

    In the command line i say:

    cutchar - 2 -6 < theFileName

    so then when i run a textfile, it removes columns 2 to 6
    What am i doing wrong?

    Here's how the text file looks:

    123456789123456789123456789
    123456789123456789123456789
    123456789123456789123456789
    123456789123456789123456789
    123456789123456789123456789
    123456789123456789123456789
    123456789123456789123456789


    123456789123456789123456789
    123456789123456789123456789
    123456789123456789123456789
    123456789123456789123456789
    123456789123456789123456789
    123456789123456789123456789

    Here's my source code. It has something to do with under scanf

    Code:
    include <stdio.h>
    #include <string.h>
    
    int main(int argc, char ** argv)
    {
    int i, j=0; 
    char *token;
    char c;
    int range[10];
    
     for(i=1;i<argc;i++) 
     {
      token=strtok(argv[i]+1, "-");
    
      while (token != NULL)
      {
      range[j++] = atoi(token);
      token=strtok(NULL, "-");
      }
     }
    
     for (i=0;i<j;i++)
     {
      if(i==0)
      printf("Range from column: ");
      else
      printf("\t to column: ");
      printf("%d", range[i]);
     }
    
    printf("\n");
    
    i=0;//i is then returned
    
     while (scanf("%c",&c) != EOF)
     {
      if (i < range[0] || i> range[1])
      printf("%c", c);
      printf("%c", argv);
     }
    return 0; 
    }
    help would be appreciated.

  2. #2
    Dr Dipshi++ mike_g's Avatar
    Join Date
    Oct 2006
    Location
    On me hyperplane
    Posts
    1,218
    I'd store the columns to remove in order then read the file something like:
    Code:
    int ch;
    int count = 0;  // holds the character position
    int index = 0;  // holds the position in the array holing characters to skip
    while((ch = fgetc(file)) != EOF)
    {
        if(count != remove_cols[index])
        {
            putchar(ch);
        }
        else // Its a column to omit
        {
            index++;
        }
        count++;
    
        if(ch == '\n')
        {
             count=0;
             index=0;
        }
    }
    Its pretty crude, can probably be done better, and may have errors in it. but its just an idea I wrote off the top of my head.

  3. #3
    Frequently Quite Prolix dwks's Avatar
    Join Date
    Apr 2005
    Location
    Canada
    Posts
    8,048
    So what happens? Obviously not what you wanted, but you have to describe in more detail what actually happens.

    Besides the missing '#' at the very beginning of the program:
    Code:
      if (i < range[0] || i> range[1])
      printf("&#37;c", c);
      printf("%c", argv);
    argv most certainly cannot be printed with %c. %c prints chars, and argv is a char **. I think that perhaps you're missing some curly braces around the statements of that if statement as well. Why are you printing argv there anyway? . . . .

    Code:
    while (scanf("%c",&c) != EOF)
    scanf() returns EOF when the end of the file is reached, but it can return 0 as another error code (which is unlikely for %c, but still). It's best to compare the return value of scanf() against the number of format specifiers passed to it -- so if there's only one %c or %d or whatever, you'ld want something like this:
    Code:
    while(scanf("%c", &c) == 1)
    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.

  4. #4
    Registered User
    Join Date
    Feb 2008
    Posts
    20
    what actually happens is that it just displays the same output as the text file w/o any changes.
    This is once i remove "prinf(argv)" which i didn't need.

  5. #5
    Frequently Quite Prolix dwks's Avatar
    Join Date
    Apr 2005
    Location
    Canada
    Posts
    8,048
    Well that's probably because you never change i in your last while loop . . . you'll need to increment it for every character, and set it to 0 when you encounter a newline.
    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.

  6. #6
    Registered User
    Join Date
    Feb 2008
    Posts
    20
    Hey man i just incremented i, and set it back to zero, but it displays the same thing.

    Code:
    while (scanf("%c",&c) != EOF)//while the file is scanned
     {
     if (i <= range[0] || i > range[1])//if the new number is less than the first number in range or greater than the second number in range
      i++; 
      if(c == '\n')
      i = 0;
        printf("%c", c);//print all the characters
     }

  7. #7
    Frequently Quite Prolix dwks's Avatar
    Join Date
    Apr 2005
    Location
    Canada
    Posts
    8,048
    I told you before, you need to add curly braces to your if statement(s). Here's what it looks like when I do.
    Code:
    while (scanf("&#37;c",&c) != EOF)//while the file is scanned
    {
        // if the new number is less than the first number in range
        // or greater than the second number in range
        if (i <= range[0] || i > range[1]) {
            i++;
        }
        if(c == '\n') {
            i = 0;
        }
        printf("%c", c);  // print all the characters
    }
    Do you see the problem? You're only incrementing i when i is within the range you want to print -- and the printf() is always executed. Swap the i++ and the printf() statements and everything should be just fine.

    Of course, you still need to handle more than one range . . . perhaps a for loop would be in order.

    To find this sort of error yourself, it would help to indent properly at least, and preferably also add extra curly braces.
    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.

  8. #8
    Registered User
    Join Date
    Feb 2008
    Posts
    20
    Thanks man! That truly helped!

    Now one last question

    I can do the values for a range
    How would i do it to where i do for example:

    "cutchar -46,52 < TheFileName"
    to where i can get the numbers that don't appear for columns "46 and 52" only?
    would i have to do another StringTokenizer and if so...how?

    I'm very very close!

    Thanks for ur help thus far!

  9. #9
    Frequently Quite Prolix dwks's Avatar
    Join Date
    Apr 2005
    Location
    Canada
    Posts
    8,048
    Let's have a look at your original code.
    Code:
     for(i=1;i<argc;i++) 
     {
      token=strtok(argv[i]+1, "-");
    
      while (token != NULL)
      {
      range[j++] = atoi(token);
      token=strtok(NULL, "-");
      }
     }
    You're tokenizing the string with "-"s as the separators. If you added "," to the list of separators -- making it "-," -- I think that would do exactly what you want.

    A suggestion: consider using strtol() or even sscanf() instead of atoi(). atoi() has pretty bad error checking.

    BTW -- I would get rid of the requirement for a "-" in front of the numbers. It makes the numbers look negative.
    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.

  10. #10
    Registered User
    Join Date
    Feb 2008
    Posts
    20
    hey dwks, i have to do the '-', it indicates range. -8 -12...means that it removes numbers 8 to 12. But if its like -8,12....it means it removes 8 and 12 ONLY while the characters in between that range don't get removed. I tried to replace it with a comma but it didn't do anything different than a - would.

  11. #11
    Frequently Quite Prolix dwks's Avatar
    Join Date
    Apr 2005
    Location
    Canada
    Posts
    8,048
    Oh, I see. Hmm. Well, unfortunately, your current code only handles one range, because all you use is this:
    Code:
    if (i < range[0] || i> range[1])
    With a loop, you could loop over the elements of range[] to handle more than one range.

    But to remove single columns -- in that case, you'd either need to specify ranges that start and being at the same place -- inefficient -- or invent a new array and add some code to handle it. Which would be wasteful as well.

    That's assuming you can even parse the numbers separately. strtok() will let you do this, you just have to instruct it to.

    I'm actually a little confused about the parameters of your program. In your first example, you used this:
    Code:
    cutchar - 2 -6 < theFileName
    But with your current code, because the first "-" is separated, it only works by fluke. It simply takes all numbers that it can see and uses them as ranges. If you were to add blacklisted columns in addition to ranges, you'd need to modify that code.

    I'll assume your initial example was meant to be "-2 -6". What are you going to do with something like "-2,4 -6"? Is that columns 2 and 4 eliminated, and the range from 4 to 6 as well? It doesn't make sense. Sucky syntax if you ask me. Or wait: was it meant to be "-2-6"? That makes sense.

    If that's the case, you'll want to look for parameters that start with a "-", parse a number from them, check the next character to see if it's a '-' or a ',' or the end of the string, and continue doing this until you actually get to the end of the string. sscanf(), or better yet, strtol() would really help you in doing this. For example:
    Code:
    int n;
    char *begin, *p;
    
    /* ... */
    begin = argv[x];  /* set begin to the beginning of the string */
    n = strtol(begin, &p, 0);
    if(begin == p) {  /* there was no number in begin */
        break;  /* we're done parsing this argument */
    }
    if(*p == ',') {
        /* ... */
    }
    begin = p + 1;
    /* loop around again and start parsing begin . . . */
    Maybe that was just confusing. Any questions?
    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.

  12. #12
    Registered User
    Join Date
    Feb 2008
    Posts
    20
    yea the same code u mentioned confused me just a little bit. lol.
    But the "-2-6" bit yea....thats what im looking for. Its main purpose is to remove columns 2 to 6.
    "-2,6" its purpose is just to remove column 2 and column 6 only.

  13. #13
    Frequently Quite Prolix dwks's Avatar
    Join Date
    Apr 2005
    Location
    Canada
    Posts
    8,048
    So have you tried to implement support for multiple ranges yet? Did you get anywhere?
    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.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Help for my output array
    By qwertysingh in forum C Programming
    Replies: 1
    Last Post: 02-17-2009, 03:08 PM
  2. execl()/fork() output
    By tadams in forum C Programming
    Replies: 19
    Last Post: 02-04-2009, 03:29 PM
  3. Replies: 4
    Last Post: 11-30-2005, 04:44 PM
  4. Formatting output into even columns?
    By Uncle Rico in forum C Programming
    Replies: 2
    Last Post: 08-16-2005, 06:10 PM
  5. Output problems with structures
    By Gkitty in forum C Programming
    Replies: 1
    Last Post: 12-16-2002, 05:27 AM

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21