I know that multiple functions are already available. However, I thought of writing my own because I wanted to learn the logic (and also because I thought there wasn't enough confusion :P). Please review the function I wrote and suggest me efficient changes.
Without further ado, here I go:
scan(string,size)
char** string;
size_t size;
{
string[0]=(char*)malloc(sizeof(char));
char keystroke=' ';
while((keystroke=getc(stdin))!='\n') {
string[0][size++]=keystroke;
string[0]=(char*)realloc(string[0],size+1);
}
string[0][size]='0円';
return size;
}
-
2\$\begingroup\$ Please do not update the code in your question to incorporate feedback from answers, doing so goes against the Question + Answer style of Code Review. This is not a forum where you should keep the most updated version in your question. Please see what you may and may not do after receiving answers . \$\endgroup\$Vogel612– Vogel6122020年01月29日 08:12:07 +00:00Commented Jan 29, 2020 at 8:12
2 Answers 2
Your code is horrible:
- You don't check for end-of-file, which will lead to endless loops
- You don't check for failure of
malloc
orrealloc
- You call
realloc
way too often, which makes the code slow for large lines of input - You cast the result of
malloc
- You use the outdated style of function definition from the 1980s
- The variable
string
is not a string but points to an array of pointers to strings, which is confusing - The
#include
forsize_t
is missing - Using
[0]
instead of*
is extremely confusing - There is no need to initialize
keystroke
to a space character - The parameter
size
is useless since the only possible value that makes sense for it is 0 - The return type of the function is implicitly
int
, which is obsolete - The returned value is of type
size_t
, which doesn't fit into anint
and additionally differs in signedness
-
1\$\begingroup\$ @d4rk4ng31 "why would I check for EOF?" --> to know when
stdin
has no more data to provide. \$\endgroup\$chux– chux2020年01月29日 13:47:34 +00:00Commented Jan 29, 2020 at 13:47 -
3\$\begingroup\$ @d4rk4ng31 what if the input ends before you can read a '\n'? \$\endgroup\$L. F.– L. F.2020年01月29日 13:52:10 +00:00Commented Jan 29, 2020 at 13:52
-
3\$\begingroup\$ @d4rk4ng31, When
stdin
is closed,getc(stdin)
returnsEOF
- that is the true end of input. Your code, instead of stopping, goes into an infinite loop.'\n'
is only the end of a line. \$\endgroup\$chux– chux2020年01月29日 13:53:43 +00:00Commented Jan 29, 2020 at 13:53 -
2\$\begingroup\$ @d4rk4ng31 It does not wait, it loops, consuming memory until an allocation failed and then UB of attempting to de-reference a
NULL
. Loop should quit on either'\n'
andNULL
. \$\endgroup\$chux– chux2020年01月29日 13:57:30 +00:00Commented Jan 29, 2020 at 13:57 -
1\$\begingroup\$ @d4rk4ng31 Because you have not tested it in enough different cases. \$\endgroup\$chux– chux2020年01月29日 13:58:42 +00:00Commented Jan 29, 2020 at 13:58
Code does not handle end-of-file or rare input error well as there is no attempt to detect EOF
.
Perhaps something like
// char keystroke=' ';
int keystroke=' ';
while((keystroke=getc(stdin))!='\n' && keystroke!= EOF) {
string[0][size++]=keystroke;
string[0]=(char*)realloc(string[0],size+1);
}
if (keystroke == EOF && size == 0) {
free(string[0]);
string[0] = NULL;
return -1; // Maybe use (size_t)-1 to indicate EOF.
}
Fuller example code
-
\$\begingroup\$ any particular reason to use
int keystroke
overchar keystroke
? \$\endgroup\$kesarling– kesarling2020年01月29日 14:59:35 +00:00Commented Jan 29, 2020 at 14:59 -
2\$\begingroup\$ @d4rk4ng31
int getc(stdin)
returns typeint
and typically 257 different values. To save inchar
loses information. Usingchar
, cannot distinguishEOF
from a valid character. \$\endgroup\$chux– chux2020年01月29日 15:20:53 +00:00Commented Jan 29, 2020 at 15:20
Explore related questions
See similar questions with these tags.