我编写了一个程序,其输出被写入一个文件(名为greater.dat),在同一个程序中我试图调用gnuplot并绘制存储在greater.dat文件中的那些数据。 但是在运行之后,代码出现错误
line 0: warning: Skipping data file with no valid points
gnuplot> plot'bigger.dat'
^
line 0: x range is invalid
我该如何删除此错误。
这是我的完整代码
#include <stdio.h>
#include <stdlib.h>
int main(void){
FILE *f;//pointer to a file
int i;
f = fopen("bigger.dat","w");// creating a file in the write mode
/*check whether it is opened or not*/
if (f == NULL)
{
printf("unable to open file");
return 0;
}
/* if the file is opened now then we write the results of following program to tht file*/
for (i=1;i<10;i++)
{
fprintf(f,"%d %d\n",i,i*i);
}
/* following code opens gnuplot and read data points from big.dat file*/
FILE *fp = fopen ("myfile","wt");
fprintf(f,"set xrange[0:10]\n");
fprintf(f, "set yrange [0:100]\n ");
fprintf(f, "set zeroaxis\n");
fprintf(fp,"plot'%s'\n","bigger.dat");
fclose(fp);
system("gnuplot -p <myfile");
return 0;
}//main
答案 0 :(得分:2)
通常,gnuplot
需要绘图文件来描述要绘制的数据(列)并设置各种绘图选项(标题,轴标签,网格,线等)。 How to pass command line argument to gnuplot?。如果您希望在C程序中进行绘图,您将需要拥有一个现有的绘图文件,或者在代码中动态创建一个。
此外,虽然您可以pipe
通过解决方案,但您可以更好地将绘图分配给单独的流程,使用所需参数构建命令行并从中调用gnuplot
execvp
等。 (提供shell路径名搜索等)使用fork
您可以将绘图卸载到子进程,从那里调用execvp
,让您的程序可以继续而无需等待在gnuplot
。
以下示例使用该方法。所有辅助函数都只是错误检查函数或简单的实用函数来分割路径名,并且与fork
,execvp
,gnuplot
示例没有密切关系。 (他们只是保持main()
整洁,这样你就可以专注于逻辑而不需要涉及所有的验证。(总有额外的验证可以添加)。
代码会将简单函数f(x) = x^3 - x2
生成的值写入作为命令行提供的第一个参数给出的文件名(如果没有提供参数,则写入gnuplot.dat
)。该程序将动态创建一个适当的绘图文件,写入gnuplot.plt
(默认情况下)或以filename.plt
格式提供的文件名(其中plt
}替换原来的扩展名)
该计划创建的情节如下:
以下是简短示例代码:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
enum { MAXL = 128, MAXC = 256};
FILE *xfopen (const char *fn, const char *mode);
int badmode (const char *s);
int xfclose (FILE *fp);
int xfexists (char *fn);
char *fnwoext (char *nm, char *fn);
int main (int argc, char **argv) {
int pid, status;
float f[MAXL] = {0.0};
char *fn = argc > 1 ? argv[1] : "gnuplot.dat";
char fnbase[MAXC] = "", fnplt[MAXC] = "";
size_t i;
FILE *fp = NULL;
for (i = 0; i < MAXL; i++) /* fill array of values */
f[i] = i * i * i - i * i; /* x^3 - x^2. no overflow */
fp = xfopen (fn, "w"); /* open output file */
for (i = 0; i < MAXL; i++) /* write values to file */
fprintf (fp, "%3zu %10.2f\n", i, f[i]);
xfclose (fp); /* close output file */
/* create 'plot' file 'fn.plt' */
strcpy (fnplt, fnwoext (fnbase, fn));
strcat (fnplt, ".plt");
if (!xfexists (fnplt)) {
xfopen (fnplt, "w");
fprintf (fp, "set xlabel 'x'\n"
"set ylabel 'f(x) = x^3 - x^2'\n"
"set title 'Function Plot of f(x) = x^3 - x^2'\n"
"set grid\n"
"set style data lines\n"
"plot \"%s\" using 1:2 lw 3 linecolor rgb \"blue\"\n"
"quit\n", fn);
xfclose (fp);
}
/* fill arguments array for execvp */
char *args[] = { "gnuplot", "-p", fnplt, NULL };
if ((pid = (fork())) < 0) { /* fork plot process */
fprintf (stderr, "fork() error: fork failed.\n");
return 1;
}
else if (pid == 0) { /* plot from child process */
if (execvp (*args, args) == -1) {
fprintf (stderr, "execvp() error: returned error.\n");
_exit (EXIT_FAILURE);
}
}
waitpid (pid, &status, 0); /* wait for plot completion (not req'd) */
return 0;
}
/** fopen with error checking - short version */
FILE *xfopen (const char *fn, const char *mode)
{
if (!fn || !mode || badmode (mode)) {
fprintf (stderr, "xfopen() error: invalid parameter.\n");
exit (EXIT_FAILURE);
}
FILE *fp = fopen (fn, mode);
if (!fp) {
fprintf (stderr, "xfopen() error: file open failed '%s'.\n", fn);
exit (EXIT_FAILURE);
}
return fp;
}
/** validate file mode 's' is "rwa+b" */
int badmode (const char *s)
{
const char *modes = "rwa+b";
for (; *s; s++) {
const char *m = modes;
int valid = 0;
while (*m) if (*s == *m++) { valid = 1; break; }
if (!valid) return *s;
}
return 0;
}
/** file close with error check */
int xfclose (FILE *fp)
{
if (fclose (fp)) {
fprintf (stderr, "xfclose() error: nonzero return on fclose.\n");
return 1;
}
return 0;
}
/** check if file 'fn' already exists */
int xfexists (char *fn)
{
/* if access return is not -1 file exists */
if (access (fn, F_OK ) != -1 )
return 1;
return 0;
}
/** isolate filename, without path or extension */
char *fnwoext (char *nm, char *fn)
{
char *p = NULL, *ep = NULL;
char fnm[MAXC] = "";
if (!fn) return NULL;
strcpy (fnm, fn);
if ((p = strrchr (fnm, '/')))
p++;
else
p = fnm;
if ((ep = strrchr (p, '.'))) {
*ep = 0;
strcpy (nm, p);
*ep = '.';
} else
strcpy (nm, p);
return nm;
}
查看代码,使用fork
和execvp
的方法,如果您有任何其他问题,请与我们联系。
答案 1 :(得分:0)
这是代码
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
FILE *f;//pointer to a file
int i;
f = fopen("BoosterData.dat","w");// creating a file in the write mode
/*check whether it is opened or not*/
if (f == NULL)
{
printf("unable to open file");
return 0;
}
/* if the file is opened now then we write the results of following program to tht file*/
for (i=1;i<10000;i++)
{
fprintf(f,"%d %d\n",i,i*i);
}
fclose(f);
FILE *pipe_gp = popen("gnuplot -p", "w");
// fputs("set terminal pn\n", pipe_gp);
fputs("set xlabel date\n",pipe_gp);
fputs("plot 'BoosterData.dat' u 1:2 title 'data1'\n", pipe_gp);
pclose(pipe_gp);
return 0;
}
答案 2 :(得分:-1)
根据我的理解,您希望阅读从bigger.dat
到myfile
的内容,然后将myfile
发送到gnuplot
?
在这种情况下,您必须以与撰写它们相同的方式使用它,即您必须从bigger.dat
读取到myfile
,然后将myfile
发送到gnuplot
}:
int main(void)
{
FILE *f;//pointer to a file
int i;
f = fopen("bigger.dat","w");// creating a file in the write mode
/*check whether it is opened or not*/
if (f == NULL)
{
printf("unable to open file");
return 0;
}
/* if the file is opened now then we write the results of following program to tht file*/
for (i=1;i<10;i++)
{
fprintf(f,"%d %d\n",i,i*i);
}
fclose(f);
FILE *fp = fopen("myfile", "w"); // I'm guesssiog you want to read it?
f = fopen("bigger.dat", "r"); // you have to open it again for reading
int a,b;
for (i=1; i<10; i++)
{
fscanf(f, "%d %d\n", &a,&b);
fprintf(fp, "plot %d %d\n", a,b);
}
fclose(f);
fclose(fp);
system("gnuplot -p <myfile");
return 0;
}
当然,这仍然无法正常工作,我的建议是编写一个bash脚本来阅读myfile
line by line,或者(如果你不知道bash脚本) out this answer,即构建要发送到system()
的命令:
#include <stdio.h>
#include <stdlib.h>
int main()
{
int a;
char buf[BUFSIZ];
printf("Please enter a number:\n");
scanf("%d",&a);
printf("Your number is: %d\n",a);
snprintf(buf, sizeof(buf), "echo %d",a);
system(buf);
}
在你的情况下(只是最后一部分):
...
f = fopen("bigger.dat", "r"); // open it again for reading
int a,b;
char command[30];
for (i=1; i<10; i++)
{
fscanf(f, "%d %d\n", &a,&b);
snprintf(buf, sizeof(buf), "gnuplot plot %d %d", a,b %d",a);
system(command);
command = ""; // reset the command variable
}
fclose(f);
return 0;
}