PDA

View Full Version : How do I parse information that was printed to the command line by another program?


bobleny
03-01-2010, 09:47 PM
I have yet another question for you, if you don't mind.

I have this line of code:

system("amixer sget 'Master',0");


When ran, it prints to the screen:

Simple mixer control 'Master',0
Capabilities: pvolume pvolume-joined pswitch pswitch-joined
Playback channels: Mono
Limits: Playback 0 - 31
Mono: Playback 0 [0%] [-46.50dB] [on]


The following, of course, wont work, but it is an example of what I'm looking to do:

char *stringy = system("amixer sget 'Master',0");
printf("%s\n", stringy);


I want to be able to parse the information that was printed to the command line. My question to you is, can I instead, or in addition to, have the text stored into a string? Is this even possible to do?

Thank you very much!

oracleguy
03-01-2010, 10:24 PM
Well in this case, what are you trying to do? Like why are you running that command and trying to parse the result?

If in this case amixer is the ALSA command line utility, you'd be better off just using the alsa headers and writing your program so it leverages the ALSA API instead. That will make it way easier to program and give you more flexibility and more power since you won't be limited by a 3rd party utility.

Plus using those system calls is something that should be avoided in a C program. That type of usage is better in a interpreted scripting language.

bobleny
03-02-2010, 11:05 PM
What I would like to do is control the master and PCM volume as part of my program. I am able to control it via system("amixer options"). However, there doesn't seem to be a way of determining the current volume or if it is currently muted, which I would like to know.

I've downloaded the source file for amixer, and it appears to be using libasound2 to control the volume. So installed the libasound2-dev so that I may use it to control the volume instead of amixer.

I came up with a little test to try this out and aside from being very confusing, the problem I am having now is, I can't build the program. It will compile with out errors using the -c option (do not link), but I get the following error during the build:

gcc -Wall -std=c99 "KooKoo.c" -o "KooKoo" (in directory: ~/Programming/C/KooKoo)
/tmp/ccEEELyZ.o: In function `main':
Compilation failed.
undefined reference to `snd_mixer_open'
undefined reference to `snd_mixer_first_elem'
undefined reference to `snd_mixer_selem_has_playback_volume'
undefined reference to `snd_mixer_close'
collect2: ld returned 1 exit status


Here is my program:

#include <stdio.h>
#include <alsa/asoundlib.h>

int main(void)
{
snd_mixer_t *handle;
snd_mixer_elem_t *elem;

if(snd_mixer_open(&handle, 0) < 0)
{
// Error
}
else
{
elem = snd_mixer_first_elem(handle);
//elem = snd_mixer_find_selem(handle, id);
if(snd_mixer_selem_has_playback_volume(elem))
{
printf("Yay!");
}
}

snd_mixer_close(handle);

return 0;
}


The command used to build it is:

gcc -Wall -std=c99 "%f"

%f is the filename with the .c extension

At first I thought maybe it was a linking error, but alsa/asoundlib.h is located in /usr/include/alsa/. The compiler should search /usr/include/ by default right?

Does anyone know what I am doing wrong? I don't understand why I would have a problem with <alsa/asoundlib.h> but not <stdio.h>, which is also located in /usr/include/.

oracleguy
03-02-2010, 11:24 PM
ld is the linker so it means you basically hit your first linker error and thankfully this is a relatively easy one. Before I explain the solution, let me give you some background on how programs are compiled (typically).

There are three main phases, the preprocessor which is where #defines, #include and such are used. The second phase is where the compiler uses a lexical analyzer and a code generator to turn the programming language into actual instructions that the computer can execute. (There is more to it than that in most compilers but that is the gist) Then that code is linked together, so it knows where different functions are.

So if your C program had more than one .c file (which is very common), you would compile each file with the -c option so it doesn't link. This produces an object file. Then those object files are linked together to form an executable.

You can also link in static libraries (.a files) into your program, that is how the libc stuff (printf, scanf, all the standard functions) is included. The reason you don't have to manually tell gcc to do something for stdio.h is because the static library is implied. The compiler by default will link the program with it because 99.9999% of the time you would want to. Static libraries allow you to include 3rd party code into your program.

So back to your problem. You need to tell gcc to link to an additional library. Which you would do like this: -lasound the -l means link and asound is the name of the library.

Try this: gcc -Wall -std=c99 -lasound "KooKoo.c" -o "KooKoo"

bobleny
03-02-2010, 11:58 PM
You know, I actually tried the -l option but I was doing this:
-l/usr/include/alsa/asoundlib.h

It never once occurred to me to just enter -lasound...

It builds just fine now, if only the program ran just fine now... lol
This is a lot harder than using system().

Thank you very much!

oracleguy
03-03-2010, 02:21 AM
This is a lot harder than using system().


It just takes getting used to, in the end you'll be a lot happier with it.

bobleny
03-08-2010, 03:31 AM
It just takes getting used to, in the end you'll be a lot happier with it.

Yeah, I am happy that I got it figured out, but I couldn't have figured it out with out the source of another program. I had to use the source file of amixer to figure out how to do it...

I don't suppose there is anyway of controlling the volume in windows is there?

oracleguy
03-08-2010, 04:34 AM
There probably is but it will use different headers and different functions.