I made very simple interpreter in C and now, I want to make my code better.
Here is my code:
#define size_t unsigned long long
int printf(const char *format, ...);
int scanf(const char *format, ...);
void *memmove(void *str1, const void *str2, size_t n);
size_t strlen(const char *str);
int main()
{
char ch[50];
do
{
printf(">>> ");
scanf("%s", ch);
if (ch[0] == '"' & ch[strlen(ch) - 1] == '"')
{
memmove(ch, ch + 1, strlen(ch));
ch[strlen(ch) - 1] = '0円';
printf("%s\n", ch);
}
}
while(1);
}
(I don't want to include standard libraries)
-
\$\begingroup\$ Welcome to the Code Review Community. \$\endgroup\$pacmaninbw– pacmaninbw ♦2021年02月28日 12:27:13 +00:00Commented Feb 28, 2021 at 12:27
-
2\$\begingroup\$ Somehow this is not the first post I've seen this year that claims "I don't like to include libraries, so I'll go through the trouble of redeclaring prototypes myself and then linking to the standard libraries". Is there some kind of low-quality tutorial or course advocating for this? \$\endgroup\$Reinderien– Reinderien2021年02月28日 15:37:37 +00:00Commented Feb 28, 2021 at 15:37
-
\$\begingroup\$ @Reinderien No. \$\endgroup\$sbh– sbh2021年02月28日 15:43:06 +00:00Commented Feb 28, 2021 at 15:43
-
1\$\begingroup\$ Where did you get the idea then, that declaring the functions from the standard library might be a good idea? \$\endgroup\$Roland Illig– Roland Illig2021年02月28日 16:23:21 +00:00Commented Feb 28, 2021 at 16:23
2 Answers 2
There are a number of issues in this very short program.
Unless there are coding standards that require otherwise, it is better to use typedef
to define types rather than #define
.
You are calling standard C libraries when you call printf()
, scanf()
, memmove()
and strlen()
unless you have written all of these functions on your own and linking in some sort of special manner.
It is not a good idea to redefine size_t
at any point since it is defined by the system header files and may be different on different platforms (the Windows version of size_t
is different than the Fedora Linux version of size_t
for example).
The code contains a possible buffer overflow when performing the scanf()
. The array ch
is only 50 characters. This can lead to undefined behavior.
You don't need a long long
for an array that is a maximum of 50 characters.
-
3\$\begingroup\$ Actually, even if you write your own
printf()
,scanf()
, etc, you may still be calling Standard C Library functions - the compiler is allowed to ignore such redefinitions. \$\endgroup\$Toby Speight– Toby Speight2021年02月28日 17:14:16 +00:00Commented Feb 28, 2021 at 17:14
- Your
main
function is missing a prototype. You should writeint main(void)
instead to explicitly say that this function does not take any arguments. - What if I enter just a
"
? - What if I enter
"hello"
with some leading spaces? - What if I enter
"hello, world"
? - By using
&
instead of&&
, you force the condition on the right hand to be evaluated, which invokes undefined behavior ifch
is an empty string. - Since you are moving
strlen(ch)
bytes, there is no need to setch[strlen(ch) - 1] = '0円'
anymore, thememmove
does this already. - In a
do { ... } while
loop, thewhile
should not be written at the beginning of a line since it looks as if it were an endless loop there.
From the introduction, it is not clear what exactly your code is supposed to interpret and what the expected results are. In its current state, the code does not feel to implement a good specification at all, so you should start with a specification, make it somewhat good (it doesn't need to be perfect), and then you should start to implement the first prototype.