LinuxQuestions.org
Share your knowledge at the LQ Wiki.
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 07-20-2019, 07:16 AM   #31
hazel
LQ Guru
 
Registered: Mar 2016
Location: Harrow, UK
Distribution: LFS, AntiX, Slackware
Posts: 7,597
Blog Entries: 19

Rep: Reputation: 4455Reputation: 4455Reputation: 4455Reputation: 4455Reputation: 4455Reputation: 4455Reputation: 4455Reputation: 4455Reputation: 4455Reputation: 4455Reputation: 4455

That's not how I'd remove a word from a string. How incredibly complicated! I'd use strstr() to see the position where the word starts, then I'd transcribe the string up to that point into an empty buffer, jump the length of the word and then transcribe the rest.
 
1 members found this post helpful.
Old 07-20-2019, 09:39 AM   #32
michaelk
Moderator
 
Registered: Aug 2002
Posts: 25,728

Rep: Reputation: 5919Reputation: 5919Reputation: 5919Reputation: 5919Reputation: 5919Reputation: 5919Reputation: 5919Reputation: 5919Reputation: 5919Reputation: 5919Reputation: 5919
As a starting point to make things much simpler I suggest using a single line for your configuration file i.e. type,options:
Code:
mp3,-f mp3,-an 1
Code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
 
int main(int argc, char **argv)
{

    char read_array[128],*cmdline[10],opt1[256];
    FILE *input_file;
    char *token,*myargs,*o;
    int i;

    cmdline[0]="ffmpeg";
     input_file=fopen("ffcliFront.conf","r");

    while(1) {
        fgets(read_array, 128, input_file);
        if( feof(input_file) ) 
          break;
        printf("Line from config file: %s\n", read_array);
        token = strtok(read_array, ",");
        printf( "Type = %s\n", token );
        o = strstr(token,argv[1]);
        if (o) {
           i=1;
           strcpy(opt1,"-i ");
           strcat(opt1,argv[2]);
           cmdline[i++]=opt1;
           while( token != NULL ) {

                token = strtok(NULL, ",");
                printf( " %s\n", token );
                cmdline[i++]=token;
            }

            execv ("ffmpeg", cmdline);
            break;
       }       
    }
    fclose(input_file);
}

}
In a nutshell strtok splits the string from the configuration line using a comma as the separator. strstr compares the type and if it matches strips the command line arguments. Code is a bit rough and I borrowed a bit from the others but hopefully it is easy to follow.

Last edited by michaelk; 07-26-2019 at 07:47 AM.
 
1 members found this post helpful.
Old 07-20-2019, 10:27 AM   #33
rtmistler
Moderator
 
Registered: Mar 2011
Location: USA
Distribution: MINT Debian, Angstrom, SUSE, Ubuntu, Debian
Posts: 9,883
Blog Entries: 13

Rep: Reputation: 4930Reputation: 4930Reputation: 4930Reputation: 4930Reputation: 4930Reputation: 4930Reputation: 4930Reputation: 4930Reputation: 4930Reputation: 4930Reputation: 4930
Quote:
Originally Posted by jsbjsb001 View Post
I tried it again without any changes, and yes strstr() does in fact appear to find the "identifier"/the first string specified to my program on the command-line - I must have missed it before, sorry about that.
Great! Glad you see that.
Quote:
Originally Posted by jsbjsb001 View Post
I done a search before starting this thread about how to remove a word from an array, it appears it involves a 2D array, along with some for loops, as well as strcmp() and strcpy() - although I don't really understand exactly what the example code is actually doing to convert the example array to a 2D array, and particularly when it comes to what strcmp() and strcpy() are really doing. This is the example I'm referring to - although I had to use Google Chrome to view that site, as I didn't want to disable Firefox's adblocker.
Not visiting that link, I don't prefer to get sidetracked with some number of references, which is a possibility there.
  1. BAD IDEA to browse the web, see some implementation where you say, "I don't really understand exactly what the example code is actually doing ...", and subsequently subscribe to that example. JUST DON'T! OK?
  2. If you post and if I can discern your problem and give you a solution, I'll probably continue to do so.
  3. Many will agree that with any computer language, there are numerous ways to skin the cat. Learn the easy to understand things. If you absolutely cannot understand a concept, then stay away from it until you get better.
  4. This program you have, you're trying to do a few things: Parse two files, manipulate strings, and then run ffmpeg using an argument list. Along with all of that you're using the argv[] array.
  5. I ALWAYS put in a check for a proper argument list, for when I have one, and I ALWAYS put in a line to illustrate my "usage" when I provide my error report at that check point. What do I mean by that? I have a printf() statement at the top error check saying, "Usage: program-name [argument-1] [argument-2] <optional-argument> ..."
Once again, you're doing too much where you haven't as yet "debugged" the earlier steps of your program.

You get a difficult to resolve situation because while you attain compiled code, you make some fundamental mistakes which cause your program to not do as intended.

What I'm trying to get you to understand is that you're not going back to debug logically, and from the beginning of the program. It would save you a lot of time and grief.
 
1 members found this post helpful.
Old 07-20-2019, 12:06 PM   #34
jsbjsb001
Senior Member
 
Registered: Mar 2009
Location: Earth, unfortunately...
Distribution: Currently: OpenMandriva. Previously: openSUSE, PCLinuxOS, CentOS, among others over the years.
Posts: 3,881

Original Poster
Rep: Reputation: 2063Reputation: 2063Reputation: 2063Reputation: 2063Reputation: 2063Reputation: 2063Reputation: 2063Reputation: 2063Reputation: 2063Reputation: 2063Reputation: 2063
Quote:
Originally Posted by hazel View Post
That's not how I'd remove a word from a string. How incredibly complicated! I'd use strstr() to see the position where the word starts, then I'd transcribe the string up to that point into an empty buffer, jump the length of the word and then transcribe the rest.
Yeah, it did seem pretty complicated just to remove one part of the string - glad there's easier ways! Thanks!

Quote:
Originally Posted by rtmistler View Post
Great! Glad you see that.Not visiting that link, I don't prefer to get sidetracked with some number of references, which is a possibility there.
  1. BAD IDEA to browse the web, see some implementation where you say, "I don't really understand exactly what the example code is actually doing ...", and subsequently subscribe to that example. JUST DON'T! OK?
  2. If you post and if I can discern your problem and give you a solution, I'll probably continue to do so.
  3. Many will agree that with any computer language, there are numerous ways to skin the cat. Learn the easy to understand things. If you absolutely cannot understand a concept, then stay away from it until you get better...
Don't worry, I haven't used any of that code, and now I know there's easier ways, I'll take the easier way out for now.

Quote:
I ALWAYS put in a check for a proper argument list, for when I have one, and I ALWAYS put in a line to illustrate my "usage" when I provide my error report at that check point. What do I mean by that? I have a printf() statement at the top error check saying, "Usage: program-name [argument-1] [argument-2] <optional-argument> ..."
I'm not clear on what you mean by "check for a proper argument list"? Do you mean check for what's been typed in by the user? If so, how would I go about doing that?

I was planning on adding a "Usage" function or similar to it. I was just caught up with trying to get it to at least find the "identifier" if nothing else.

Quote:
What I'm trying to get you to understand is that you're not going back to debug logically, and from the beginning of the program. It would save you a lot of time and grief.
I have added some printf's to verify the value of argv[1] for one.

I like michaelk's idea for separating the "identifier" with a comma - it does make it more clear. That way you know whatever is after the comma is what is actually passed to ffmpeg. Thanks for that michaelk!
 
Old 07-20-2019, 12:15 PM   #35
hazel
LQ Guru
 
Registered: Mar 2016
Location: Harrow, UK
Distribution: LFS, AntiX, Slackware
Posts: 7,597
Blog Entries: 19

Rep: Reputation: 4455Reputation: 4455Reputation: 4455Reputation: 4455Reputation: 4455Reputation: 4455Reputation: 4455Reputation: 4455Reputation: 4455Reputation: 4455Reputation: 4455
Quote:
Originally Posted by jsbjsb001 View Post
I'm not clear on what you mean by "check for a proper argument list"? Do you mean check for what's been typed in by the user? If so, how would I go about doing that?

I was planning on adding a "Usage" function or similar to it. I was just caught up with trying to get it to at least find the "identifier" if nothing else.
That's easy. argc contains the total number of command line tokens. The first of these is the program name, so argc-1 is the number of user-supplied arguments. If it is not the number your program requires, print the usage statement and exit.
 
2 members found this post helpful.
Old 07-20-2019, 12:18 PM   #36
michaelk
Moderator
 
Registered: Aug 2002
Posts: 25,728

Rep: Reputation: 5919Reputation: 5919Reputation: 5919Reputation: 5919Reputation: 5919Reputation: 5919Reputation: 5919Reputation: 5919Reputation: 5919Reputation: 5919Reputation: 5919
FYI I modified my code a bit and separated each option with a comma.
 
Old 07-20-2019, 02:09 PM   #37
rtmistler
Moderator
 
Registered: Mar 2011
Location: USA
Distribution: MINT Debian, Angstrom, SUSE, Ubuntu, Debian
Posts: 9,883
Blog Entries: 13

Rep: Reputation: 4930Reputation: 4930Reputation: 4930Reputation: 4930Reputation: 4930Reputation: 4930Reputation: 4930Reputation: 4930Reputation: 4930Reputation: 4930Reputation: 4930
Quote:
Originally Posted by jsbjsb001 View Post
I'm not clear on what you mean by "check for a proper argument list"? Do you mean check for what's been typed in by the user? If so, how would I go about doing that?
Please follow what hazel said here:
Quote:
Originally Posted by hazel View Post
That's easy. argc contains the total number of command line tokens. The first of these is the program name, so argc-1 is the number of user-supplied arguments. If it is not the number your program requires, print the usage statement and exit.
 
1 members found this post helpful.
Old 07-21-2019, 02:41 AM   #38
jsbjsb001
Senior Member
 
Registered: Mar 2009
Location: Earth, unfortunately...
Distribution: Currently: OpenMandriva. Previously: openSUSE, PCLinuxOS, CentOS, among others over the years.
Posts: 3,881

Original Poster
Rep: Reputation: 2063Reputation: 2063Reputation: 2063Reputation: 2063Reputation: 2063Reputation: 2063Reputation: 2063Reputation: 2063Reputation: 2063Reputation: 2063Reputation: 2063
Thanks Hazel and RT. So just to make sure I'm clear; you mean within the following if statement (between fprintf and return 1) to add a line to print out a usage statement?

Code:
 if ( argc != 3 ) {
       fprintf (stderr, "Missing option or filename\n");
       return 1;
    }
I've just read the link about functions that ntubski posted before; while other than the part at the bottom about "variable-length argument lists", it seems to make sense; other than the "..." to indicate a "variable-length argument list"; I'm not really clear on much else about "variable-length argument lists".

Also, I was reading michaelk's example code, and while some of it makes sense; I'm not sure why the following is there?

Code:
cmdline[0]="fselect.sh";
(the "fselect.sh" part of it)

But I'll still have to try a few things by themselves to really understand exactly what each line of michaelk's code is actually doing - particularly exactly what strtok(), strcpy() and strcat() are actually doing. While michaelk has explained what the code "as a whole" does, trying to read it and decipher it by itself isn't particularly easy for me, particularly what the functions I mentioned before are really doing (other than what michaelk has already said of course). So I haven't added any more code to my program yet.
 
Old 07-21-2019, 03:14 AM   #39
hazel
LQ Guru
 
Registered: Mar 2016
Location: Harrow, UK
Distribution: LFS, AntiX, Slackware
Posts: 7,597
Blog Entries: 19

Rep: Reputation: 4455Reputation: 4455Reputation: 4455Reputation: 4455Reputation: 4455Reputation: 4455Reputation: 4455Reputation: 4455Reputation: 4455Reputation: 4455Reputation: 4455
Quote:
Originally Posted by jsbjsb001 View Post
Thanks Hazel and RT. So just to make sure I'm clear; you mean within the following if statement (between fprintf and return 1) to add a line to print out a usage statement?

Code:
 if ( argc != 3 ) {
       fprintf (stderr, "Missing option or filename\n");
       return 1;
    }
That would certainly work, but the Linux convention is to print a usage statement. In other words, you don't just tell the poor sap he got it wrong; you tell him what he should have input. So put in another fprintf() with something like "Usage: %s THIS THAT THE OTHER", argv[0].
Quote:
I've just read the link about functions that ntubski posted before; while other than the part at the bottom about "variable-length argument lists", it seems to make sense; other than the "..." to indicate a "variable-length argument list"; I'm not really clear on much else about "variable-length argument lists".
Most functions take a fixed number of arguments, but a few do not. The best known of these is probably printf() and its analogues. In such cases, gcc needs to know how many arguments to expect so that it can report any syntax errors. Different functions have different ways of coding this, but there are two main ones:
1) The printf family require you to put placeholders in the string for any variables that it might contain. So in my example above, %s is a placeholder for a string variable inside the quoted string, and argv[0] (the program name) is the variable that goes in there. gcc knows that it should expect one and only one additional variable because there is one placeholder in the string.
2) Some functions require a variable-length list of arguments to end with a NULL pointer. The exec functions that are used to launch programs do it like this. You have a list or an array of command line arguments ending in a NULL.
Quote:
...what strtok(), strcpy() and strcat() are actually doing.
For goodness sake read the man pages for these functions. That's what they are there for. You should never use any function without reading its man page first.
 
1 members found this post helpful.
Old 07-21-2019, 04:26 AM   #40
rtmistler
Moderator
 
Registered: Mar 2011
Location: USA
Distribution: MINT Debian, Angstrom, SUSE, Ubuntu, Debian
Posts: 9,883
Blog Entries: 13

Rep: Reputation: 4930Reputation: 4930Reputation: 4930Reputation: 4930Reputation: 4930Reputation: 4930Reputation: 4930Reputation: 4930Reputation: 4930Reputation: 4930Reputation: 4930
Quote:
Originally Posted by hazel View Post
For goodness sake read the man pages for these functions. That's what they are there for. You should never use any function without reading its man page first.
THIS!

And why must you use fprint() to stderr? I know it's valid, but boy I'd hate to have to deal with some odd occurrence where it is actually redirected somewhere else besides the console. Just use plain old printf(). Similarly you were using fputs() at one point too. When you're learning, why complicate things?
 
Old 07-21-2019, 05:33 AM   #41
hazel
LQ Guru
 
Registered: Mar 2016
Location: Harrow, UK
Distribution: LFS, AntiX, Slackware
Posts: 7,597
Blog Entries: 19

Rep: Reputation: 4455Reputation: 4455Reputation: 4455Reputation: 4455Reputation: 4455Reputation: 4455Reputation: 4455Reputation: 4455Reputation: 4455Reputation: 4455Reputation: 4455
But it is an error message after all, so actually I think it should go to standard error.
 
2 members found this post helpful.
Old 07-21-2019, 05:53 AM   #42
jsbjsb001
Senior Member
 
Registered: Mar 2009
Location: Earth, unfortunately...
Distribution: Currently: OpenMandriva. Previously: openSUSE, PCLinuxOS, CentOS, among others over the years.
Posts: 3,881

Original Poster
Rep: Reputation: 2063Reputation: 2063Reputation: 2063Reputation: 2063Reputation: 2063Reputation: 2063Reputation: 2063Reputation: 2063Reputation: 2063Reputation: 2063Reputation: 2063
Thanks for explaining that Hazel - it's at least little more clear. Although I'm still not sure about what to make of the examples for "variable-length argument lists" in that same link that ntubski posted before though.

I was planning to read the man pages about those functions - that's why I said I haven't added any more code to my program. So it doesn't currently do anything, other than look for the id string so it knows which line in the config file to pass to ffmpeg.

Quote:
Originally Posted by hazel View Post
But it is an error message after all, so actually I think it should go to standard error.
That's what my thinking was when I wrote that code - that's why I used fprintf and stderr.
 
Old 07-21-2019, 06:39 AM   #43
michaelk
Moderator
 
Registered: Aug 2002
Posts: 25,728

Rep: Reputation: 5919Reputation: 5919Reputation: 5919Reputation: 5919Reputation: 5919Reputation: 5919Reputation: 5919Reputation: 5919Reputation: 5919Reputation: 5919Reputation: 5919
Code:
cmdline[0]="ffmpeg";
Sorry that should be ffmpeg not fselect.sh. I was just playing with a test script and forget to change it when I posted the updated code. It's how execv works. It uses an array for the command line arguments and the first argument is always the command itself.

The string manipulating stuff is probably confusing and mainly used because I was using different string types.
 
1 members found this post helpful.
Old 07-21-2019, 06:53 AM   #44
ntubski
Senior Member
 
Registered: Nov 2005
Distribution: Debian, Arch
Posts: 3,784

Rep: Reputation: 2083Reputation: 2083Reputation: 2083Reputation: 2083Reputation: 2083Reputation: 2083Reputation: 2083Reputation: 2083Reputation: 2083Reputation: 2083Reputation: 2083
Quote:
Originally Posted by jsbjsb001 View Post
I've just read the link about functions that ntubski posted before; while other than the part at the bottom about "variable-length argument lists", it seems to make sense; other than the "..." to indicate a "variable-length argument list"; I'm not really clear on much else about "variable-length argument lists".
Sorry, I was just looking at the example at the top. I didn't pay attention to the other stuff. I would not recommend learning about variable-length argument lists right now, it's an advanced topic that is seldom needed (you can generally use vararg functions like printf() without knowing the details of it).


Quote:
Originally Posted by rtmistler View Post
And why must you use fprint() to stderr? I know it's valid, but boy I'd hate to have to deal with some odd occurrence where it is actually redirected somewhere else besides the console. Just use plain old printf(). Similarly you were using fputs() at one point too. When you're learning, why complicate things?
Sending error messages to stderr is standard practice:

Code:
$ cp a 2> /dev/null
$ cp a > /dev/null
cp: missing destination file operand after 'a'
Try 'cp --help' for more information.
 
2 members found this post helpful.
Old 07-22-2019, 02:28 AM   #45
jsbjsb001
Senior Member
 
Registered: Mar 2009
Location: Earth, unfortunately...
Distribution: Currently: OpenMandriva. Previously: openSUSE, PCLinuxOS, CentOS, among others over the years.
Posts: 3,881

Original Poster
Rep: Reputation: 2063Reputation: 2063Reputation: 2063Reputation: 2063Reputation: 2063Reputation: 2063Reputation: 2063Reputation: 2063Reputation: 2063Reputation: 2063Reputation: 2063
So I read the man pages for the functions I mentioned before in michaelk's code above, and while some of it was a bit like "yeah ok, whatever that really means"; those functions do make at least a little more sense now, and therefore michaelk's code is at least a little easier to follow. I still haven't touched my program yet, as I've just been practising good old strcpy(). I wrote a little program just to try and get the hang of strcpy(), and while I think I understand it a lot better now, I have a few questions about it; why does it put all of the strings in s1[] if I declare my "test arrays" outside of the main function? But if I declare the array within the main function, it doesn't do that. Also, why does strcpy() expect you to declare an array size?

Here's my little "test program";

Code:
#include <stdio.h>
#include <string.h>

int main(void) {
  
    int i;
    char s1[6] = { 'T', 'e', 's', 't', ' ' };
    char s2[6] = { 't', 'e', 's', 't', '2' };
    char s3[6] = { 't', 'e', 's', 't', '3' };
    char s4[6];

    printf("s1 = %s\n", s1);
    printf("s2 = %s\n", s2);
    printf("s3 = %s\n", s3);
    printf("s4 = %s\n\n", s4);
    puts("Running strcpy...\n"); 
    // copy string in "s2" to "s1"
    strcpy(s1, s2);
    printf("s1 = %s\n", s1);
    // copy string "test" to s2
    strcpy(s2, "test");
    printf("s2 = %s\n", s2);
    // copy string in "s3" to "s4"
    strcpy(s4, s3);
    printf("s4 = %s\n", s4);
    // copy string "test4" to "s4"
    strcpy(s4, "test4");
    printf("s4 = %s\n", s4);
    
    puts("\ns2 looped twice: ");
    for ( i = 0; i < 2; ++i ) {
        printf("s2 = %s\n", s2);
    }

    return 0;
}
Here's it's output;

Code:
[james@jamespc devel]$ ./strcpy_example
s1 = Test 
s2 = test2
s3 = test3
s4 = 

Running strcpy...

s1 = test2
s2 = test
s4 = test3
s4 = test4

s2 looped twice: 
s2 = test
s2 = test
 
  


Reply



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
[SOLVED] virtualbox installs pcbsd again and again and again straffetoebak Linux - Virtualization and Cloud 4 11-21-2014 07:14 PM
LXer: Do you want a serious—I mean serious—developer laptop? Then Dell and Ubuntu have the system fo LXer Syndicated Linux News 0 11-29-2012 03:30 PM
Firefox...I have tried and tried... Basslord1124 Fedora 4 10-29-2004 11:51 PM
my ps/2's wheel doesn't work. tried and tried but failed. Choey Linux - Hardware 5 09-17-2003 06:47 PM
I have tried and tried, I really have! Ewen Linux - General 13 01-14-2003 11:31 PM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 08:51 PM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration