Reputation: 367
Alright, bear with me because there's some weird stuff here. I'm currently trying to implement a SUPER simple shell with max 20 char commands and no piping, etc. I'm also learning C along with it so please forgive any egregious errors or usage.
Here's my code for a parser:
#include <dirent.h>
#include <stdlib.h>
#include <stdio.h>
int main(void) {
int running = 1;
/* Main loop */
while(running==1) {
// The max size of the input is 20 bytes
char input[20];
// Read string from user
fgets(input, sizeof(input), stdin);
/* ----- PARSE INPUT ----- */
char buffer[20];
for(int i = 0; i < sizeof(input); i++) {
buffer[i] = input[i];
/* ------ CHECK BUFFER AGAINST VARIOUS COMMANDS ----- */
// TALK TO THE HAND
if (strcmp(buffer, "TALK TO THE HAND") == 0) {
// execute TALK TO THE HAND
printf("TALK TO THE HAND\n");
}
else {
printf("WHAT DID I DO WRONG?\n");
}
}
}
}
My expected output when inputting TALK TO THE HAND
is just it echoing that, but what I get is this:
TALK TO THE HAND
WHAT DID I DO WRONG?
WHAT DID I DO WRONG?
WHAT DID I DO WRONG?
WHAT DID I DO WRONG?
WHAT DID I DO WRONG?
WHAT DID I DO WRONG?
WHAT DID I DO WRONG?
WHAT DID I DO WRONG?
WHAT DID I DO WRONG?
WHAT DID I DO WRONG?
WHAT DID I DO WRONG?
WHAT DID I DO WRONG?
WHAT DID I DO WRONG?
WHAT DID I DO WRONG?
WHAT DID I DO WRONG?
TALK TO THE HAND
WHAT DID I DO WRONG?
WHAT DID I DO WRONG?
WHAT DID I DO WRONG?
WHAT DID I DO WRONG?
and I have no idea why it seemingly loops over and over again with different outputs.
Upvotes: 0
Views: 45
Reputation: 302
sizeof
is not a function that returning length of char-array. This is the keyword that returning a count of bytes which needed to allocation into memory any types and structures. Use strlen
instead.
Try to print sizeof(char)
and you will understand
Upvotes: 0
Reputation: 153338
Code iterates too far
Iterate to the length of the string, not the size of the buffer.
// for(int i = 0; i < sizeof(input); i++) {
for(int i = 0; input[i]; i++) {
In any case, this iteration is not needed. Just compare to input
//if (strcmp(buffer, "TALK TO THE HAND") == 0) {
if (strcmp(input, "TALK TO THE HAND") == 0) {
If code wants to copy a string:
strcpy(buffer, input);
Be certain buffer
is adequate in size.
Compares not accounting for '\n'
that was read.
Lop off potential '\n
'
fgets(input, sizeof(input), stdin);
// add
input[strcspn(input, "\n")] = '\0';
Buffer too small
buffer[]
needs to hold 20 characters, '\n'
and '\0'
.
// char input[20];
char input[20 + 1 + 1];
Advanced
fgets()
could return NULL
which indicates stdin
is closed.
User may enter too much text, good to detect that
#define INPUT_N 20
// extra \n \0
char input[INPUT_N + 1 + 1 + 1]; // I'd just go with INPUT_N*2
if (fgets(input, sizeof(input), stdin) == NULL) {
fprintf(stderr, "Input closed\n");
return EXIT_FAILURE;
}
size_t len = strlen(input);
if (len > 0 && input[len-1] == '\n') {
input[--len] = '\0'; // lop off \n
}
if (len > INPUT_N) {
// exit or otherwise cope with too much data
fprintf(stderr, "Excessive long input\n");
return EXIT_FAILURE;
}
...
Upvotes: 2