Dear all,
I am novice in C+= programing. I would like to seek help in one of the progra. Here it is, I have txt file which has the data as following order
I need to plot the
Log(varA) vs average of the varB on graph. I am confuse as the columns for varB are all undecided, how shall I do that? Trying to look for help in google, not much help..
Do you create the data file, or are you stuck with something? Can you change the data file, because whatever process creates the data file "knows" how many values in varB column:
Hi,
Thanks for the reply.
I have some experimental measurement which I am suppose to put in txt file and also need to plot. So the no of values for varB can be maximum of 6 or 7 maybe.
If you kindly write a small program for doing it, would be useful.
I figured out the TGraph from ROOT is good tool to plot it, but reading the txt file with second column has so many variables.. I am confuse...
HI Corona,
Sorry I thought I explained this before, let me try again.
These are the set of measurement, which I got manually from some hardware setup.
And I need to plot the varA vs Average no of the VarB
thanks Corona,
Actually, I work around with C++ and also on ROOT. I find the combination really good and effective.
It is just that I begin with such task, so sometimes stuck !!
I will see if I can use the TGraph from ROOT here to plot a nice Graph, thanks for your kindness..
Out or curiosity, which other language you would refer, where it would be really easy to plot it?
awk FS="[ ,]" # Separate columns on spaces and commas \
'NR > 1 { # Do not try to do math on the first line with column names
for(N=3; N<=NF; N++) # Loop over column 3 to the last column, adding them to column 2 in turn
$2 += $N ;
$2 /= (NF-1); # Divide the column by 1-number of columns
NF=2; # Strip off all columns beyond the second
} 1 # Print all lines' inputfile
Never a fan of strtok() or scanf myself, debugging too many core dumps, I guess, especially in C++ (stateful subroutines in OO, ooooh!). I would fgets() lines into a char array and then process them as follows. If the byte is not a number part (strchr( " ,\t\n\r\f", this_char ), strchr( "1234567890-.", this_char) -- I like the positive test), set it to null and reset the in-number flag, else if it is, then if the in-number flag is not set, record the address in a char[], increment the index on that array and set the in-number flag. When you are done, you have an array of pointers to null terminated character strings of numbers to atof() in the processing layer, with the index telling you the count of numbers found.
I would not read 4k into a 1k buf. fgets( buf, sizeof( buf ), stdin ) ?
Every fgets needs a "line too long" check to be stable. WHne this occurs, the last buffer byte is null and then preceeding one is not a line feed. Seed the buffer tail, rather than pawing over the line an additional time, for a quick check. Put it all in a nice subroutine p_fgets() (private fgets) with if ! fgets() if ferror() perror( "stdin" ); exit 1; else exit 0;
It definitely has its flaws. Doing further editing on the string after it's tokenized is a bad idea. It's not re-entrant. And other such gripes.
But seeing your description of how you'd do it, particularly the 'set it to null', that's exactly what strtok does, to the letter. I don't see what makes your way better -- bigger program, slower program, bigger chance for bugs.
Same goes for sscanf. It makes some really complicated problems simple, and vice versa.
If the problem wasn't this simple though, I certainly wouldn't have used those.
Sorry to repeat. But it sounds like you DO create the data file. Is that correct?
If so, what if you simply change the data file to something like the following, and then the programming to read the data would be trivial, using fscanf.
CSV might be nice, too -- just read with excel. However, differentiating numbers from not is pretty trivial. The major challenge here is the variable number of fields. A more normal form would have one varB per line, and downstream, assuming you do not lose the sort, you process when the two keys change or EOF. Normal could be put in RDBMS and processed in SQL. You are writing in two dimensions, sometimes across and sometimes down. But that's OK.
It's probably better to use "strtod()" or "atof()" to convert a string to a double, if only because "sscanf()" can and does do weird things when input is not as expected. "strtod()" also provides the ability to know the last character processed, so it's easier to tell if something went bad.
Can even be done in shell with bc for the floating point, something like:
while read a b c
do
f=$(
( echo 'e=0
n=0'
for d in $c
do
echo 'n=n+1
e=e+'"$d"
done
echo e/n
) | bc -l | sed 's/\.*0*$' )
echo $a $b $f
done <in_file >out_file
I second the sscanf() concerns. I like to validate my inputs -- never give inputs the benefit of the doubt. The man says atof() is strtod() with less error checking. You get to choose. And that is UNIX in a nutshell: lots of options, support for quick, devil-may-care code, but the wise chose the more robust alternatives.
hi,
Thanks for the reply..but I am confuses, I need to plot both columns, how am I suppose to plot them the?
So you propose to use shell script to make them like single valued columns..and then call in C++ code to plot?
I am sure there are shell friendly graph programs, too. Heck, you can lay down images in text and then call utilities to make them into images! I am never shy about using a popen() to read shell output in C/C++! You can use system() to make an named pipe and sort it to itself, so all you have to do is write the named pipe and then read it. Unlike COBOL, no embedded sort!
system( "(mknod p p ; sort -o p p ; rm p )&" );
FILE *f = fopen( "p", "w" );
while (...) { ... fputs( buf, f ); ... }
fclose( f );
f = fopen( "p", "r" );
while ( fgets( buf, sizeof( buf ), f )){...}
fclose( f );