对给定代码的批评。 [英] Critic of the given code.

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

问题描述

我编写了以下函数,从stdin返回任意长度为b / b
的字符串。到目前为止,它似乎应该工作。代码中有任何

不可移植的假设和/或逻辑错误吗?返回字符串的长度会更好吗?
?或整数值

表示成功或失败,(失败的类型)?


谢谢。


#include< stdio.h>

#include< stdlib.h>


#define IBUFSIZ 32

#定义BUF_DELTA IBUFSIZ

#define BUF_INP_DIFF 3

#define BUF_CROP_THRESHOLD(BUF_INP_DIFF + 1)


char * getl_stdin(void);


char * getl_stdin(void){

char * inp_p = NULL,* inp_p_cpy;

int nc,buffer_exists = 0 ,no_buf_crop = 0;

size_t curr_bufsiz = 0,curr_inpsiz = 0;


while((nc = fgetc(stdin))!= EOF){

if((curr_bufsiz - curr_inpsiz)< BUF_INP_DIFF){

curr_bufsiz + = BUF_DELTA;

if((inp_p = realloc(inp_p,curr_bufsiz) ))== NULL){

if(buffer_exists){

inp_p = inp_p_cpy;

inp_p [curr_inpsiz] = nc;

inp_p [curr_inpsiz + 1] =''\ 0'';

++ curr_inpsiz;

curr_bufsiz - = BUF_DELTA;

no_buf_crop = 1;

休息;

}

其他

休息;

}

else {

inp_p_cpy = inp_p;

inp_p [curr_inpsiz] = nc;

++ curr_inpsiz;

if(!buffer_exists)

buffer_exists = 1;

else {

if(nc ==''\ n''){

inp_p [curr_inpsiz] =''\ 0'';

++ curr_inpsiz;

休息;

}

}

}

}

else {

inp_p [curr_inpsiz] = nc;

++ curr_inpsiz;

if(nc = =''\ n''){

inp_p [curr_inpsiz] =''\ 0'';

++ curr_inpsiz;

休息;

}

}

}


if(inp_p!= NULL& &安培; !no_buf_crop){

if((curr_bufsiz - curr_inpsiz)> = BUF_CROP_THRESHOLD){

if((inp_p = realloc(inp_p,curr_inpsiz))== NULL)

inp_p = inp_p_cpy;

else {

inp_p_cpy = inp_p;

curr_bufsiz = curr_inpsiz;

}

}

}


返回inp_p;

}


int main(void){

char * input = NULL;

int main_RV = 0;


puts(输入一行文字:);

input = getl_stdin();

if(input == NULL){

puts(getl_stdin()返回NULL。;

main_RV = EXIT_FAILURE;

}

else

printf("你写道:\ n%s \ n",输入);


返回main_RV;

}

I''ve written the following function to return a string of arbitrary
length from stdin. So far, it seems to work as it should. Are there any
unportable assumptions and/or logical errors in the code? Would it be
better to return the length of the string? Or an integer value
indicating success or failure, (the type of failure too)?

Thanks.

#include <stdio.h>
#include <stdlib.h>

#define IBUFSIZ 32
#define BUF_DELTA IBUFSIZ
#define BUF_INP_DIFF 3
#define BUF_CROP_THRESHOLD (BUF_INP_DIFF + 1)

char *getl_stdin(void);

char *getl_stdin(void) {
char *inp_p = NULL, *inp_p_cpy;
int nc, buffer_exists = 0, no_buf_crop = 0;
size_t curr_bufsiz = 0, curr_inpsiz = 0;

while((nc = fgetc(stdin)) != EOF) {
if((curr_bufsiz - curr_inpsiz) < BUF_INP_DIFF) {
curr_bufsiz += BUF_DELTA;
if((inp_p = realloc(inp_p, curr_bufsiz)) == NULL) {
if(buffer_exists) {
inp_p = inp_p_cpy;
inp_p[curr_inpsiz] = nc;
inp_p[curr_inpsiz + 1] = ''\0'';
++curr_inpsiz;
curr_bufsiz -= BUF_DELTA;
no_buf_crop = 1;
break;
}
else
break;
}
else {
inp_p_cpy = inp_p;
inp_p[curr_inpsiz] = nc;
++curr_inpsiz;
if(!buffer_exists)
buffer_exists = 1;
else {
if(nc == ''\n'') {
inp_p[curr_inpsiz] = ''\0'';
++curr_inpsiz;
break;
}
}
}
}
else {
inp_p[curr_inpsiz] = nc;
++curr_inpsiz;
if(nc == ''\n'') {
inp_p[curr_inpsiz] = ''\0'';
++curr_inpsiz;
break;
}
}
}

if(inp_p != NULL && !no_buf_crop) {
if((curr_bufsiz - curr_inpsiz) >= BUF_CROP_THRESHOLD) {
if((inp_p = realloc(inp_p, curr_inpsiz)) == NULL)
inp_p = inp_p_cpy;
else {
inp_p_cpy = inp_p;
curr_bufsiz = curr_inpsiz;
}
}
}

return inp_p;
}

int main(void) {
char *input = NULL;
int main_RV = 0;

puts("Enter a line of text:");
input = getl_stdin();
if(input == NULL) {
puts("getl_stdin() returned NULL.");
main_RV = EXIT_FAILURE;
}
else
printf("You wrote:\n%s\n", input);

return main_RV;
}

推荐答案

santosh说:
santosh said:
我写了以下函数给返回一串任意的
lengt来自stdin。到目前为止,它似乎应该工作。是否有任何
不可移植的假设


是 - 您的代码中的标签!发布到Usenet时转换为空格,或者一些

新闻阅读器会删除你的缩进(如我所做的那样)。

if((curr_bufsiz - curr_inpsiz)< BUF_INP_DIFF){
curr_bufsiz + = BUF_DELTA;


坏主意。这意味着你必须继续回到系统内存超过
及以上。更好:curr_bufsiz * = SCALING_FACTOR - 很多人建议

因子为2,虽然我更喜欢newsize = 3 * oldsize / 2;

if((inp_p = realloc(inp_p) ,curr_bufsiz))== NULL){
I''ve written the following function to return a string of arbitrary
length from stdin. So far, it seems to work as it should. Are there any
unportable assumptions
Yes - tabs in your code! Convert to spaces when posting to Usenet, or some
newsreaders will strip out your indentation (as mine did).
if((curr_bufsiz - curr_inpsiz) < BUF_INP_DIFF) {
curr_bufsiz += BUF_DELTA;
Bad idea. It means you have to keep going back to the system for memory over
and over. Better: curr_bufsiz *= SCALING_FACTOR - many people suggest a
factor of 2, although I prefer newsize = 3 * oldsize / 2;
if((inp_p = realloc(inp_p, curr_bufsiz)) == NULL) {




坏主意。如果realloc失败,你只是覆盖了指向

原始数据的唯一指针。使用一个temp,如果它不是NULL则复制它。


我没有检查 - 你在<

一行中间(即不是在''\ n''之后)?


你可能想修复它以取一个FILE *为一个arg,而不是限制它

到stdin。


顺便说一句,你基本上重新发明了Chuck'的ggets()函数 - 而且你的

功能遇到与他相同的问题,它无法重复使用现金缓冲区 - 调用者必须为其分配新的空间

他读的每行。 (我自己的类似例程允许缓冲区重新使用,如果这是程序员所希望的那样。)


-

Richard Heathfield

Usenet是一个奇怪的地方 - dmr 29/7/1999
http://www.cpax.org.uk

电子邮件:rjh在上面的域名(但显然放弃了www)



Bad idea. If the realloc fails, you just overwrote your only pointer to the
original data. Use a temp, and copy it over if it''s not NULL.

I didn''t check - how forgiving is your routine of hitting end-of-file in the
middle of a line (i.e. not immediately after a ''\n'')?

You might want to fix it to take a FILE * as an arg, rather than limiting it
to stdin.

You''ve basically re-invented Chuck''s ggets() function, by the way - and your
function suffers from the same problem as his, that it has no way to re-use
an existing buffer - the caller is obliged to allocate fresh space for
every line he reads. (My own similar routine allows the buffer to be
re-used if that''s what the programmer desires.)

--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: rjh at above domain (but drop the www, obviously)


santosh写道:
santosh wrote:
我编写了以下函数来从stdin返回一个任意长度的字符串。到目前为止,它似乎应该工作。代码中是否有任何不可移植的假设和/或逻辑错误?返回字符串的长度会更好吗?或整数值
表示成功或失败,(失败的类型)?
I''ve written the following function to return a string of arbitrary
length from stdin. So far, it seems to work as it should. Are there any
unportable assumptions and/or logical errors in the code? Would it be
better to return the length of the string? Or an integer value
indicating success or failure, (the type of failure too)?




它看起来非常复杂,我不能轻易说出来合同是什么。


我猜你可以用大约一半的代码完成它,代价是

提高它的可读性。 br />

-

Chris" electrick hedgehog" Dollin

伸出隐藏在网络中的镜子。 - 文艺复兴,/奔跑/



It looks hellishly complicated, and I can''t easily tell what the contract is.

I''d guess that you could do it in about half the code, at the cost of
improving its readability.

--
Chris "electrick hedgehog" Dollin
"Reaching out for mirrors hidden in the web." - Renaissance, /Running Hard/


Richard Heathfield写道:
Richard Heathfield wrote:
santosh说:
santosh said:
我编写了以下函数来从stdin返回任意长度的字符串。到目前为止,它似乎应该工作。是否有任何不可移植的假设
是 - 您的代码中的标签!发布到Usenet时转换为空格,或者某些
新闻阅读器会删除你的缩进(就像我的那样)。
I''ve written the following function to return a string of arbitrary
length from stdin. So far, it seems to work as it should. Are there any
unportable assumptions
Yes - tabs in your code! Convert to spaces when posting to Usenet, or some
newsreaders will strip out your indentation (as mine did).




好​​的,虽然我使用vim,但是并没有真正了解它的所有选项。



Okay, though I use vim, I haven''t really learnt all it''s options.

if((curr_bufsiz - curr_inpsiz)< BUF_INP_DIFF){
curr_bufsiz + = BUF_DELTA;
if((curr_bufsiz - curr_inpsiz) < BUF_INP_DIFF) {
curr_bufsiz += BUF_DELTA;



糟糕的主意。这意味着你必须继续回到系统以获得内存和/或以上。更好:curr_bufsiz * = SCALING_FACTOR - 很多人建议
因子为2,虽然我更喜欢newsize = 3 * oldsize / 2;



Bad idea. It means you have to keep going back to the system for memory over
and over. Better: curr_bufsiz *= SCALING_FACTOR - many people suggest a
factor of 2, although I prefer newsize = 3 * oldsize / 2;




你们是当输入继续时,方法相对于之前的增加分配越来越多的内存。



You''re method allocates increasingly more memory, relative to the
previous increase, as input continues.

if((inp_p = realloc) (inp_p,curr_bufsiz))== NULL){
if((inp_p = realloc(inp_p, curr_bufsiz)) == NULL) {



不好主意。如果realloc失败,你只是覆盖了指向
原始数据的唯一指针。使用temp,如果它不是NULL则复制它。



Bad idea. If the realloc fails, you just overwrote your only pointer to the
original data. Use a temp, and copy it over if it''s not NULL.




我复制realloc()的返回值,如果成功进入保留

指针。只有第一次分配,这没有完成,

(显然)。

我没有检查 - 你的例行程序是多么宽容在一条线的中间(即不是在''\ n''之后)?


如果它在NL之前达到EOF,则该函数会附加一个空字符并且

将返回部分输入(如果它首先存在)。

您可能想要修复它以将FILE *作为arg,而不是将其限制为stdin。


是的,我想到了这一点,但考虑为

编写另一个函数。

你基本上已经 - 顺便说一句,发明了Chuck'的ggets()函数 - 你的
函数遇到了和他一样的问题,它没有办法重用现有的缓冲区 - 调用者有义务为他读的每一行分配新的空间。 (我自己的类似例程允许缓冲区重新使用,如果那是程序员所希望的。)



I do copy the return value of realloc(), if successful into a reserve
pointer. Only for the very first allocation, this not done,
(obviously).
I didn''t check - how forgiving is your routine of hitting end-of-file in the
middle of a line (i.e. not immediately after a ''\n'')?
If it hits EOF before NL, the function appends a null character and
returns the partial input, if it exists in the first place.
You might want to fix it to take a FILE * as an arg, rather than limiting it
to stdin.
Yes, I thought of that, but considered writing another function for
that.
You''ve basically re-invented Chuck''s ggets() function, by the way - and your
function suffers from the same problem as his, that it has no way to re-use
an existing buffer - the caller is obliged to allocate fresh space for
every line he reads. (My own similar routine allows the buffer to be
re-used if that''s what the programmer desires.)




是的,我应该做的它更灵活,包括

表示在不同类型的运行时故障时要做什么的参数。


我考虑返回一个简单的1表示成功或0表示失败。如果

后者,则将errno设置为特定类型的错误,即malloc()

失败,realloc()失败,EOF等

是否允许用户功能修改errno? errno的整数范围的整数值是否与系统定义的标准不相符

值?


感谢输入。



Yes, I should have made it more flexible, including arguments which
indicate what to do upon different kinds of runtime failures.

I considered returning a simple 1 for success or 0 for failure. If the
latter, then set errno to the specific kind of error, i.e., malloc()
failure, realloc() failure, EOF etc.
Are user functions allowed to modify errno? And what range of integer
values for errno would not conflict with system defined standard
values?

Thanks for the input.


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

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