[英] code

查看:53
本文介绍了码的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我以为我会发布这段代码。它似乎做了我想要的但是我想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;

}


谢谢大家。


比尔

解决方案

2008-10-01,Bill Cunningham< no **** @ nspam.invalidwrote:


我以为我会发布这段代码。它似乎做了我想要的但是我想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);

}



嗯,此时你正在混合声明和代码。在声明下方移动

这个if语句。


FILE * fp;

char * error;



错误需要在你使用之前指向某个地方 - 你做什么

这里调用未定义的行为,因为错误的值是

不确定。


加倍a,b,c,d;

if((fp = fopen(argv [5 ],a))== NULL)

perror(错误);

a = strtod(argv [1],NULL);

b = strtod(argv [2],NULL);

c = strtod(argv [3],NULL);

d = strtod(argv [4],NULL) ;



它也可以检查所有strtod()调用是否成功。


fprintf(fp,"%。2f \ t%。2f \ t%。2f \ t%。2f \ n",a,b,c,d);

if((fclose(fp))== EOF)

perror(错误);

返回0;

}



-

Andrew Poelstra ap *******@wpsoftware.net

只有GOD可以除以零。这就是他创造黑洞的方式。

-Veselin Jungic


On Tue,2008年9月30日21:36:14 -0400,"比尔坎宁安&#

< no **** @ nspam.invalidwrote in comp.lang.c:


我以为我会发布这段代码。它似乎做了我想要的但是我想b
我认为我会批评它。我使用的是C89,但我认为可能有些代码可能放错地方了。例如,fopen可能应该在

下strtod'不应该吗?


/ *代码C89 * /



实际上,Bill,它是无效的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 *错误;

双a,b,c,d;



这里,在第一个可执行语句之后,你有一些

变量定义。在块中的任何可执行语句之后,C89不允许声明或定义

。您要么使用C99

,要么使用编译器作为其严格符合

符合模式的扩展名。


if((fp = fopen(argv [5]," a"))== NULL)

perror(错误);



上面的行不可移动,失败时不需要fopen()来设置errno

。如果是我,我会写的:


fprintf(stderr,不能打开%s \ n,argv [5]);


这样做的好处是向用户显示无法使用的文件名

是什么。


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(错误);



同样,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 I
thought I would have it critiqued. I use C89 but I think that maybe some of
the code maybe misplaced. For example, the fopen probably should be under
the 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 I
thought I would have it critiqued. I use C89 but I think that maybe some of
the code maybe misplaced. For example, the fopen probably should be under
the 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. Move
this if statement below your declarations.

FILE *fp;
char *error;

error needs to point somewhere before you use it - what you do
here invokes undefined behavior because the value of error is
indeterminate.

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 were
successful.

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.net
Only GOD may divide by zero. That is how he created black holes.
-Veselin Jungic


On 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 I
thought I would have it critiqued. I use C89 but I think that maybe some of
the code maybe misplaced. For example, the fopen probably should be under
the strtod''s shouldn''t it ?

/*code C89 */

Actually, Bill, it''s not valid C89, as you said, the declarations are
misplaced.

#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 of
variable definitions. C89 does not allow declarations or definitions
after any executable statements in a block. You are either using C99
or a compiler that allows this as an extension in its not strictly
conforming mode.

if ((fp = fopen(argv[5], "a")) == NULL)
perror(error);

The line above is not portable, fopen() is not required to set errno
on 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 name
was.

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 those
four values were actually valid representations of floating point
numbers.

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 no
telling what might be output on various implementations.

return 0;
}

Thanks all.

Bill

The program has no instances of undefined behavior, although the
perror() calls are not guaranteed to output useful information.

The fopen() will fail if the file does not already exist. If you
wanted to create the file if it does not already exist, or append to
it if it does, you could use the mode "a+".

With the variable definitions after the first if block, the code is
conforming 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 as
the program is written, since the strtod() calls can''t fail. All they
can do is to set a, b, c, and/or d to not particularly useful values
if the command line arguments do not represent proper numeric values.

If you were going to check the validity of those four inputs, and not
write anything to the output file unless all four were valid, then it
would make sense to put the fopen() after them, so you could skip it
if one or more of those inputs were bad.

--
Jack Klein
Home: http://JK-Technology.Com
FAQs for
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:

I thought I would post this code. It seems to do what I want it to but I
thought I would have it critiqued. I use C89 but I think that maybe some of
the code maybe misplaced. For example, the fopen probably should be under
the 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. Telling
us 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. You
can certainly do that if you like, but that should be mentioned in
your explanation of what the program is supposed to do.

As written, I don''t see that the ordering of the fopen and strtod
calls makes any difference. If you were doing proper error checking,
it could affect the behavior; in that case you should decide which
kind 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''s
requirements 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" as
the 5th argument; if you''re on a Windows-like system, try something
like "foo?bar" (Windows forbids ''?'' in file names).

If fopen() fails, you print an error message *and then continue
executing as if nothing had happened*.

You don''t check for errors in strtod(). The second parameter to
strtod is there for a reason. Try running your program with arguments
"one two three four output.txt". Consult the documentation for
strtod() 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"


这篇关于码的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆