Reputation: 11
I have a little problem with my program I'm trying to code.. Basically I want to enter a symbol one by one inside my loop and when I'm done I just want to press enter in order to exit the loop and then print out the string to the console. However, this doesn't seem to work and I've been trying for hours without getting the grip of it. This is my code
#include <stdio.h>
int main(int argc, char *argv[]){
int i = 0;
char text[i];
char symbol;
while(1){
scanf("%s", &symbol);
if(symbol == 13){ //13 should be the ascii value for enter
break;
}
text[i] = symbol;
i++;
}
printf("%s", text);
getch();
return 0;
}
Upvotes: 1
Views: 7401
Reputation: 44838
On Windows, when you hit Enter, it's read as \r\n
, not simply \r
. So you may want to try this:
while(1){
scanf("%c", &symbol); //use %c to read a character
if(symbol == '\r'){
scanf("%c", &symbol);
if(symbol == '\n') break;
}
text[i] = symbol;
i++;
}
Moreover, you're creating an array of nothing and then trying to place data in it. This won't work. You'd better allocate some memory first and only then read into it:
char text[1024];
int i =0; // then increase i up to 1023
What's more, if your sole intention is to capture the Enter
hit, you won't need text
at all, just symbol
will suit your needs.
Upvotes: 0
Reputation: 1
You might use fgetc(3) but it probably wont work (since stdin is buffered in the C standard library -see setvbuf(3), and in the kernel for ttys, read more about ttys). So the entire line is sent to your program only when the user pressed the return key.
In practice, it is heavily operating system specific; I hope you are on Linux or on some other POSIX system. I strongly suggest using ncurses or readline; see also termios(3)
Upvotes: 0
Reputation: 2120
First, arrays don't increase it's size magically just cause you increase the variable you used to set it's size (the i
in text[i]
in your code), you should allocate memory dynamically (malloc
, realloc
or calloc
), and remember to free it.
Your code should be like this:
int main(int argc, char *argv[]){
int i = 0;
char* text = malloc(sizeof(char));
char symbol;
char* aux;
while(1){
symbol = getchar(); //Use getchar to read only one char, scanf would be more problematic
if(symbol == 13){ //13 should be the ascii value for enter
break;
}
text[i] = symbol;
if ((aux = (char*)realloc(text, sizeof(char)*(i+1))) == NULL){
// Handle error
return -1;
}
text = aux;
i++;
}
text[i] = '\0'; //Remember to set last char in your string to '\0' or printf won't work properly
printf("%s", text);
free(text);
getch();
return 0;
}
Upvotes: 0
Reputation: 96266
%s
reads a word. If you want to read a character with scanf
, use %c
. char text[i]
- i
is zero at this point. You won't be able to store your string here. Either know the max size at compilation time (and check at runtime when appending) or dynamically allocate memory as needed.Note: naked scan from the stream is just asking for a lot of trouble. Prefer to read lines.
Upvotes: 2
Reputation: 193
You can set your terminal in raw mode with termcaps:
term.c_lflag &= ~(ICANON);
term.c_lflag &= ~(ECHO);
term.c_cc[VMIN] = 1;
term.c_cc[VTIME] = 0;
if (tcsetattr(0, TCSADRAIN, &term) == -1)
return (-1);
Then use the function:
int main(int ac, char **av, char **env)
{
char *name_term;
struct termios term;
if ((name_term = getenv("TERM")) == NULL)
return (-1);
if (tgetent(NULL, &name_term) == ERR)
return (-1);
if (tcgetattr(0, term) == -1)
return (-1);
grab_key();
return (0);
}
int grab_key()
{
char buffer[3];
while (1)
{
read(0, buffer, 3);
if (buffer[0] == 13)
printf("Exit !");
}
return (0);
}
And to set your terminal to "normal" mode:
struct termios term;
if (tcgetattr(0, &term) == -1)
return (-1);
term.c_lflag = (ICANON | ECHO);
if (tcsetattr(0, 0, &term) == -1)
return (-1);
Upvotes: 1
Reputation: 223972
Three issues. The first is how you're reading the characters:
scanf("%s", &symbol);
The %s
format specifier is for reading in a string. You're not passing in a string, but the address of a character. This will result in scanf
reading in multiple characters starting with the address of symbol
and continuing into whatever bytes may follow. This is undefined behavior.
For reading in a single character, use the %c
format specifier instead:
scanf("%c", &symbol);
Second issue:
if(symbol == 13){
A newline isn't necessarily ASCII 13 on all systems. Use the escape code for a newline instead:
if(symbol == '\n'){
Third issue:
int i = 0;
char text[i];
This creates an array of 0 size. To keep things simple, give this array some known fixed size:
char text[100];
Your loop would then need to check that you don't enter too many characters.
Upvotes: 0