在下面的C程序中,有不同的输入参数。其中一个参数-f
用于指定结果的文件名
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#define SOURCES 4
#define NUM_T 1000
char *prgname;
char usage[]="%s [-uUdipT] -f filenamen";
int main(int argc, char *argv[])
{
FILE *filefd;
char *fname;
int lt; /* lower threshold */
int ut; /* upper threshold */
int T; /* Actualization time (cells) */
double RDF, RIF; /* Rate Decrease-Increate Factor */
double PCR; /* Peak Cell Rate */
int qlen; /* queue length */
int bitEFCI[SOURCES]; /* EFCI bit */
double ACR [SOURCES]; /* Allowed Cell Rate */
double mean[SOURCES]; /* Mean Cell Rate */
int i, t; /* control variables */
double ACRacc;
prgname = strrchr(argv[0], '/');
if (prgname == (char *)NULL) prgname = argv[0];
else prgname++;
/********************************************/
/* DEFAULT VALUES & INICIALIZATION */
/********************************************/
fname = (char *)malloc(200*sizeof(char));
fname = "abr.res";
ut = 550;
lt = 450;
RDF = 0.4;
RIF = 0.02;
PCR = 150E6;
T = 70;
qlen = 0;
for (i=0; i < SOURCES; i++)
{bitEFCI[i] = 0; ACR[i] = 0.0; mean[i] = 0.0;}
/********************************************/
/* USER COMMAND LINE VALUES */
/********************************************/
while (1)
{
int c;
c = getopt(argc, argv, "u:U:d:i:p:T:f:h");
if (c == EOF) break;
switch (c)
{
case 'h': printf(usage, prgname);
fputs("-htHelpn", stdout);
fputs("-utLower threshold (cells)n", stdout);
fputs("-UtUpper threshold (cells)n", stdout);
fputs("-dtDecrement factorn", stdout);
fputs("-itIncrement factorn", stdout);
fputs("-ptPeak cell rate (Mbps)n", stdout);
fputs("-TtActualization period (cells)n", stdout);
fputs("-ftResults file namen", stdout);
exit(0);
case 'u': lt = atoi(optarg);
break;
case 'U': ut = atoi(optarg);
break;
case 'd': RDF = atof(optarg);
break;
case 'i': RIF = atof(optarg);
break;
case 'p': PCR = atof(optarg);
break;
case 'T': T = atoi(optarg);
break;
case 'f': strcpy(fname, optarg);
break;
default : fprintf(stderr, usage, prgname); exit(1);
}
}
if ((filefd = fopen(fname, "w")) == NULL)
{perror("fopen"); exit(1);}
/********************************************/
/* MAIN LOOP */
/********************************************/
for (t = 1; t<= NUM_T; t++)
{
ACRacc = 0.0;
fprintf(filefd, "%dt", t);
for (i=0; i < SOURCES; i++)
{
if (bitEFCI[i] == 0)
ACR[i] = (ACR[i]+PCR*RIF>PCR)?(PCR):(ACR[i]+PCR*RIF);
else ACR[i] *= RDF;
mean[i] += (ACR[i]-mean[i])/(double)t;
ACRacc += ACR[i];
fprintf(filefd, "%4.1ft%4.1ft", ACR[i]/1E6, mean[i]/1E6);
}
qlen += (int)(ACRacc*T*424/PCR);
qlen = (qlen<=T*424)?(0):(qlen - T*424);
fprintf(filefd, "%dn", qlen/424);
for (i=0; i < SOURCES; i++)
{
if (qlen >= ut*424) bitEFCI[i] = 1;
else if (qlen < lt*424) bitEFCI[i] = 0;
}
fflush(filefd);
}
fclose(filefd);
exit(0);
}
我用
编译过gcc -c abr1.c -Wall
gcc abr1.o -o abr1
但是当我运行程序
./abr1 -f "result01.res"
zsh: bus error ./abr1 -f "result01.res"
如何将文件名传递给这个C程序?
这是一个问题:
fname = (char *)malloc(200*sizeof(char));
fname = "abr.res";
你的malloc
空间,fname
指向,然后在下一行告诉fname
指向字符串文字" &;这会造成内存泄漏,因为现在没有任何东西指向malloc
ed内存。
此外,对于f
选项,您可以使用strcpy
来写入fname
。修改字符串字面值是未定义行为,当然可以解释你看到的行为。
我推荐使用
char fname[200] = "abr.res";
这将fname
创建为200字节长的可写内存区域,并将"abr.res"
作为默认值初始化,并且不处理手动内存管理。
根据@Laci的注释,您很容易出现缓冲区溢出,盲目地将用户输入从命令行复制到您的缓冲区。应采取步骤消除这种风险。一种方法是使用strncpy
:
case 'f':
strncpy(fname, optarg, sizeof fname);
// one of the dangers of strncpy is it is NOT guaranteed to NUL
// terminate the string, so do that manually just in case
fname[sizeof(fname)-1] = ' ';
break;