数字。 fprintf(fp,"%。2f \ t%。2f \ t%。2f \ t%。2f \ n",a,b,c,d); if((fclose(fp))== EOF) perror(错误); 同样,fclose()不需要在失败时设置errno,所以没有 告诉可能输出的内容各种实现。 返回0; } 全部谢谢。 比尔 程序没有未定义行为的实例,尽管 perror()调用不是保证输出有用的信息。 如果文件尚不存在,fopen()将失败。如果您想要创建该文件(如果它尚不存在),或者附加到 ,如果它存在,则可以使用模式a +。 使用第一个if块之后的变量定义,代码是符合C99的,但不符合C89。除此之外它也是正确的C89。 fopen()在strtod()调用下没有真正的意义 编写程序,因为strtod()调用不会失败。如果命令行参数不表示正确的数值,那么它们可以做的就是将a,b,c和/或d设置为不是特别有用的值 。 如果您要检查这四个输入的有效性,而不是 将任何内容写入输出文件,除非所有四个都有效,那么它 将fopen()置于其后是有意义的,所以你可以跳过它 如果其中一个或多个输入是坏的。 - Jack Klein 主页: http://JK-Technology.Com 常见问题解答 comp.lang.c http://c-faq.com/ comp.lang.c ++ http://www.parashift.com/c++-faq-lite/ alt.comp.lang.learn.c-c ++ http://www.club.cc.cmu.edu/~ajo/docs/FAQ-acllc.html " Bill Cunningham" < no **** @ nspam.invalidwrites: 我以为我会发布此代码。它似乎做了我想要的但是我想b 我认为我会批评它。我使用的是C89,但我认为可能有些代码可能放错地方了。例如,fopen可能应该在 下strtod'不应该吗? / *代码C89 * / #include< stdio.h> #include< stdlib.h> int main(int argc,char * argv [ ]) { if(argc!= 6){ puts(print usage error); 退出(EXIT_FAILURE); } FILE * fp; char *错误; double a,b,c,d; if((fp = fopen(argv [5]," a"))== NULL) perror(error) ; a = strtod(argv [1],NULL); b = strtod(argv [2],NULL); c = strtod( argv [3],NULL); d = strtod(argv [4],NULL); fprintf(fp,"%。2f \ t%。2f \t%。2f \ t%。2f \ n",a,b,c,d); if((fclose(fp))== EOF) perror(错误); 返回0; } 比打印使用错误更好的使用错误会好的。告诉我们它应该做的事情会更好。意图*似乎* 显而易见,但我们无法确定你要做什么。 将输出附加到命名文件似乎是一个奇怪的选择。你可以肯定,如果你愿意的话,可以做到这一点,但是你应该在 中提到你对该程序应该做什么的解释。 如上所述,我没有看到fopen和strtod 电话的订购有什么不同。如果你正在进行适当的错误检查, 它可能会影响行为;在这种情况下,您应该首先确定要检测哪种类型的错误。你可以这样做。 如果你认为fopen应该遵循strtod因为C89' 要求订购声明和声明,你' '错了; 都是陈述。 "错误"永远不会初始化,但是你将它的值传递给perror两次。 如果你在类Unix系统上,试试传递/ dev / null / nosuchfile。 as 第五个参数;如果你在类似Windows的系统上,试试一下 就像foo?bar一样(Windows禁止在文件名中''''。 如果fopen()失败,则打印错误消息*然后继续 执行为如果没有发生任何事情*。 你不能检查strtod()中的错误。 strtod的第二个参数是有原因的。尝试使用参数运行程序 " one two three four output.txt"。请参阅 strtod()的文档,了解你在output.txt中看到的内容。 - Keith Thompson( The_Other_Keith) ks***@mib.org < http://www.ghoti.net/~kst> 诺基亚 我们必须做点什么。这是事情。因此,我们必须这样做。 - Antony Jay和Jonathan Lynn,是部长 I thought I would post this code. It seems to do what I want it to but Ithought I would have it critiqued. I use C89 but I think that maybe some ofthe code maybe misplaced. For example, the fopen probably should be underthe strtod''s shouldn''t it ?/*code C89 */#include <stdio.h>#include <stdlib.h>int main(int argc, char *argv[]){if (argc != 6) {puts("print usage error");exit(EXIT_FAILURE);}FILE *fp;char *error;double a, b, c, d;if ((fp = fopen(argv[5], "a")) == NULL)perror(error);a = strtod(argv[1], NULL);b = strtod(argv[2], NULL);c = strtod(argv[3], NULL);d = strtod(argv[4], NULL);fprintf(fp, "%.2f\t%.2f\t%.2f\t%.2f\n", a, b, c, d);if ((fclose(fp)) == EOF)perror(error);return 0;}Thanks all.Bill 解决方案 On 2008-10-01, Bill Cunningham <no****@nspam.invalidwrote:I thought I would post this code. It seems to do what I want it to but Ithought I would have it critiqued. I use C89 but I think that maybe some ofthe code maybe misplaced. For example, the fopen probably should be underthe strtod''s shouldn''t it ?/*code C89 */#include <stdio.h>#include <stdlib.h>int main(int argc, char *argv[]){ if (argc != 6) { puts("print usage error"); exit(EXIT_FAILURE); }Well, at this point you''re mixing declarations and code. Movethis if statement below your declarations. FILE *fp; char *error;error needs to point somewhere before you use it - what you dohere invokes undefined behavior because the value of error isindeterminate. double a, b, c, d; if ((fp = fopen(argv[5], "a")) == NULL) perror(error); a = strtod(argv[1], NULL); b = strtod(argv[2], NULL); c = strtod(argv[3], NULL); d = strtod(argv[4], NULL);It might also do to check if all those strtod() calls weresuccessful. fprintf(fp, "%.2f\t%.2f\t%.2f\t%.2f\n", a, b, c, d); if ((fclose(fp)) == EOF) perror(error); return 0;}--Andrew Poelstra ap*******@wpsoftware.netOnly GOD may divide by zero. That is how he created black holes.-Veselin JungicOn Tue, 30 Sep 2008 21:36:14 -0400, "Bill Cunningham"<no****@nspam.invalidwrote in comp.lang.c:I thought I would post this code. It seems to do what I want it to but Ithought I would have it critiqued. I use C89 but I think that maybe some ofthe code maybe misplaced. For example, the fopen probably should be underthe strtod''s shouldn''t it ?/*code C89 */Actually, Bill, it''s not valid C89, as you said, the declarations aremisplaced.#include <stdio.h>#include <stdlib.h>int main(int argc, char *argv[]){ if (argc != 6) { puts("print usage error"); exit(EXIT_FAILURE); }Above is an executable statement. FILE *fp; char *error; double a, b, c, d;Here, after the first executable statement, you have a number ofvariable definitions. C89 does not allow declarations or definitionsafter any executable statements in a block. You are either using C99or a compiler that allows this as an extension in its not strictlyconforming mode. if ((fp = fopen(argv[5], "a")) == NULL) perror(error);The line above is not portable, fopen() is not required to set errnoon failure. If it was me, I would have just written:fprintf(stderr, "Can''t open %s\n", argv[5]);That has the advantage of showing the user what the unusable file namewas. a = strtod(argv[1], NULL); b = strtod(argv[2], NULL); c = strtod(argv[3], NULL); d = strtod(argv[4], NULL);The code above is safe, but of course does not detect whether thosefour values were actually valid representations of floating pointnumbers. fprintf(fp, "%.2f\t%.2f\t%.2f\t%.2f\n", a, b, c, d); if ((fclose(fp)) == EOF) perror(error);Again, fclose() is not required to set errno on failure, so there''s notelling what might be output on various implementations. return 0;}Thanks all.BillThe program has no instances of undefined behavior, although theperror() calls are not guaranteed to output useful information.The fopen() will fail if the file does not already exist. If youwanted to create the file if it does not already exist, or append toit if it does, you could use the mode "a+".With the variable definitions after the first if block, the code isconforming C99, but not C89. Other than that it is also correct C89.There''s no real point to the fopen() being under the strtod() calls asthe program is written, since the strtod() calls can''t fail. All theycan do is to set a, b, c, and/or d to not particularly useful valuesif the command line arguments do not represent proper numeric values.If you were going to check the validity of those four inputs, and notwrite anything to the output file unless all four were valid, then itwould make sense to put the fopen() after them, so you could skip itif one or more of those inputs were bad.--Jack KleinHome: http://JK-Technology.ComFAQs forcomp.lang.c http://c-faq.com/comp.lang.c++ http://www.parashift.com/c++-faq-lite/alt.comp.lang.learn.c-c++ http://www.club.cc.cmu.edu/~ajo/docs/FAQ-acllc.html"Bill Cunningham" <no****@nspam.invalidwrites:I thought I would post this code. It seems to do what I want it to but Ithought I would have it critiqued. I use C89 but I think that maybe some ofthe code maybe misplaced. For example, the fopen probably should be underthe strtod''s shouldn''t it ?/*code C89 */#include <stdio.h>#include <stdlib.h>int main(int argc, char *argv[]){ if (argc != 6) { puts("print usage error"); exit(EXIT_FAILURE); } FILE *fp; char *error; double a, b, c, d; if ((fp = fopen(argv[5], "a")) == NULL) perror(error); a = strtod(argv[1], NULL); b = strtod(argv[2], NULL); c = strtod(argv[3], NULL); d = strtod(argv[4], NULL); fprintf(fp, "%.2f\t%.2f\t%.2f\t%.2f\n", a, b, c, d); if ((fclose(fp)) == EOF) perror(error); return 0;}A better usage error than "print usage error" would be nice. Tellingus what it''s supposed to do would be even nicer. The intent *seems*obvious, but we can''t be sure what you''re trying to do.Appending the output to the named file seems like an odd choice. Youcan certainly do that if you like, but that should be mentioned inyour explanation of what the program is supposed to do.As written, I don''t see that the ordering of the fopen and strtodcalls makes any difference. If you were doing proper error checking,it could affect the behavior; in that case you should decide whichkind of error you want to detect first. You could do it either way.If you''re thinking that fopen should follow strtod because of C89''srequirements on ordering of declarations and statements, you''re wrong;both are statements."error" is never initialized, but you pass its value to perror twice.If you''re on a Unix-like system, try passing "/dev/null/nosuchfile" asthe 5th argument; if you''re on a Windows-like system, try somethinglike "foo?bar" (Windows forbids ''?'' in file names).If fopen() fails, you print an error message *and then continueexecuting as if nothing had happened*.You don''t check for errors in strtod(). The second parameter tostrtod is there for a reason. Try running your program with arguments"one two three four output.txt". Consult the documentation forstrtod() to understand what you see in output.txt.--Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>Nokia"We must do something. This is something. Therefore, we must do this."-- Antony Jay and Jonathan Lynn, "Yes Minister" 这篇关于码的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持! 上岸,阿里云!
07-29 23:27