【发布时间】:2020-03-06 23:01:05
【问题描述】:
我有一个代码可以测试命令是否与正确的参数一起使用,如果是,则通过调用另一个函数将其附加到文件中。
下面是代码:
void main(int argc, char *argv[]){
char accnum[10];
char fname[30];
char lname[30];
char date[10];
int amt;
FILE *q = fopen("bankdata.csv","r");
if(!q){
fprintf(stderr,"Error, unable to locate the data file bankdata.csv");
exit(100);
}
if(argc == 1 ){
fprintf(stderr,"Error, incorrect usage!\n");
fprintf(stderr,"-a ACCTNUM NAME\n");
exit(1);
}
if(strcmp(argv[1],"-a") == 0){
if(argc < 4){
fprintf(stderr,"Error, incorrect usage!\n");
fprintf(stderr,"-a ACCTNUM NAME\n");
exit(1);
}else if(argc > 3){
if((sscanf(argv[2], "%s", accnum ) == 1 ) &&
(sscanf(argv[3], "%s", fname ) == 1) &&
/*(sscanf(argv[4], "%s", lname ) == 1)*/){ //commented out
add(accnum,fname/*,lname*/);
}
}
}
}
void add(char accnum[], char fname[]/*, char lname[]*/){
// printf("%s, %s, %s", accnum, fname, lname);
size_t line = 0;
char buf[100] = "";
char *term = accnum;
FILE *fp = fopen ("bankdata.csv", "a+");
while (fgets (buf, 100, fp)) { /* read each line */
if (strstr (buf, term)) { /* test for term */
fprintf(stderr,"Error, account number %s already exists\n", accnum);
fclose(fp);
exit(50);
}
if (strchr (buf, '\n')) line++; /* increment line */
}
fprintf(fp,"AC,%s,%s",accnum,fname);
fclose(fp);
}
这样当我进入时
./a.out -a 1111 Joe Blow
它附加到另一个文件
Ac,1111,Joe
问题是,当我尝试添加姓氏(即uncomment && (sscanf(argv[4], "%s", lname ) == 1)))并使用相同的命令行(./a.out -a 1111 Joe Blow)时,它给了我一个分段错误,我不知道为什么。我还尝试取消注释添加功能中的所有相关部分,但它不会改变任何东西。
我认为这与 argv[4] 为空有关,因为这是我之前编写代码时遇到的问题之一,但是 argv[4] 应该是“吹”吧?
任何帮助表示赞赏。
【问题讨论】:
-
要使
argv[4]不为空,argc必须大于 4,而不是大于 3。您是否修改了fprintf(fp,"AC,%s,%s",accnum,fname);以发出lname?也无需像您一样复制argv[ n ]- 只需将参数直接传递给您的add()函数:add( argv[2], argv[3],...)。如果用户输入过长的字符串,你现在所做的很容易出现各种问题。 -
char *argv[]是一个 指针数组,指向保存参数的以 nul 结尾的字符串。最后一个参数之后的下一个指针是NULL(一个sentinel NULL)。./a.out -a 1111 Joe Blow中有多少个参数,其中./a.out是第一个参数 (argv[0]),"Blow"是最后一个参数argv[4]。 -
你为什么使用,例如
sscanf(argv[2], "%s", accnum )什么时候可以简单地以add (argv[2], argv[3], argv[4]);进行函数调用,而不必重复存储已经是每个程序参数的内容? -
该代码应该会给您一堆警告,除非您禁用它们,因为缺少各种标准标头的包含。我猜你的真实代码有它们,但是你的问题缺少minimal reproducible example。
标签: c segmentation-fault