Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

unordered console output #114747

Closed
ghost opened this issue Aug 11, 2023 · 13 comments
Closed

unordered console output #114747

ghost opened this issue Aug 11, 2023 · 13 comments

Comments

@ghost
Copy link

ghost commented Aug 11, 2023

I tried this code:

 1 -   // vars
 2 -   let mut guess = String::new();
 3 -
 4 -   print!("Guess the number!");
 5 -
 6 -   // take user input
 7 -   println!("Please, input your guess ");
 8 -
 9 -   io::stdin()
10 -      .read_line(&mut guess)
11 -      .expect("failed to read line :(");
12 -
13 -   println!("You guessed: {}!", guess);

I expected to see this process:

Guess the number!
Please input your guess:  18
You guessed 18!

Instead, the process is weird, i have done this exercise in another programming languages and i have never seen this order:

1 - Guess the number!
2 - 18
3 - Please, input your guess You guessed: 18
4 - !

Meta

rustc --version --verbose:

rustc 1.71.1 (eb26296b5 2023-08-03)
binary: rustc
commit-hash: eb26296b556cef10fb713a38f3d16b9886080f26
commit-date: 2023-08-03
host: x86_64-unknown-linux-gnu
release: 1.71.1
LLVM version: 16.0.5

I'm a novice using rust, but i consider it is not correct, this may help others novices.

@ghost ghost added the C-bug Category: This is a bug. label Aug 11, 2023
@rustbot rustbot added the needs-triage This issue may need triage. Remove it if it has been sufficiently triaged. label Aug 11, 2023
@workingjubilee
Copy link
Member

@Leandrys-Osorio On the same platform, I get the following output:

./example
Guess the number!Please, input your guess 
18
You guessed: 18
!

The detail here is that the buffer is only flushed by println!, not print!.
Are you sure your output is what you are seeing? What glibc/kernel version are you on? It may be doing odd things due to the buffer not being flushed.

@ghost
Copy link
Author

ghost commented Aug 11, 2023

Sorry, I don't understand to much but I wonder you want this information:

Libc = "0.2.147"

About kernel(I suppose it's my Linux kernel) = 6.2.6

And I'm sure about the output... I have copied the text snippets, and check your exclamation mark, would it be at the next line of the variable value? (check your output)

@workingjubilee
Copy link
Member

glibc is a file on your system, usually it is located at /usr/lib/libc.so.6 so if you put that into your terminal it will tell you its version.

My output is exactly copied from my terminal.

@workingjubilee
Copy link
Member

Are you using a different shell, like the one in VS Code, or emacs, or zsh or fish or nushell?

@workingjubilee
Copy link
Member

Basically, if you can type env and paste the results (if there is any information in there you don't want to share, you can delete it just fine) that would help a lot.

@SkiFire13
Copy link
Contributor

1 - // vars
2 - let mut guess = String::new();
3 -
4 - print!("Guess the number!");
5 -
6 - // take user input
7 - println!("Please, input your guess ");
8 -
9 - io::stdin()
10 - .read_line(&mut guess)
11 - .expect("failed to read line :(");
12 -
13 - println!("You guessed: {}!", guess);

Are you sure this is the code you're actually executing? The output you got would be expected lines 4-7 were:

4 -   println!("Guess the number!");
5 -
6 -   // take user input
7 -   print!("Please, input your guess ");

Notice the swapping of println and print.

In this case it's expected that the second print would not be shown immediately because it doesn't end a line, and stdout is line buffered by default, meaning only full lines are sent to the terminal to be shown. print doesn't end a line, so it gets buffered until println!("You guessed: {}!", guess); gets executed and ends that line.

This happens for performance reasons, but you can control this behaviour by inserting a manual "flush" to stdout (i.e. sending whatever is in the buffer to it immediately) right after the print!("Please, input your guess ");, by doing:

print!("Please, input your guess ");

// `flush` is a method of the `std::io::Write` trait, so bring it into scope.
use std::io::Write;
std::io::stdout().flush().expect("Couldn't flush to stdout");

@ghost
Copy link
Author

ghost commented Aug 12, 2023

i only found this with "whereis" command:
/usr/share/man/man7/libc.7.gz

and i was using bash in vscode.

my env output:
SHELL=/bin/bash
SESSION_MANAGER=local/leandrys-pc:@/tmp/.ICE-unix/1394,unix/leandrys-pc:/tmp/.ICE-unix/1394
QT_ACCESSIBILITY=1
COLORTERM=truecolor
XDG_CONFIG_DIRS=/etc/xdg/xdg-pop:/etc/xdg
SSH_AGENT_LAUNCHER=gnome-keyring
XDG_MENU_PREFIX=gnome-
GNOME_DESKTOP_SESSION_ID=this-is-deprecated
GTK_IM_MODULE=ibus
GNOME_SHELL_SESSION_MODE=pop
SSH_AUTH_SOCK=/run/user/1000/keyring/ssh
XMODIFIERS=@im=ibus
DESKTOP_SESSION=pop
GTK_MODULES=gail:atk-bridge
PWD=/usr/lib
LOGNAME=leandrys
XDG_SESSION_DESKTOP=pop
XDG_SESSION_TYPE=x11
GPG_AGENT_INFO=/run/user/1000/gnupg/S.gpg-agent:0:1
SYSTEMD_EXEC_PID=1575
XAUTHORITY=/run/user/1000/gdm/Xauthority
WINDOWPATH=2
HOME=/home/leandrys
USERNAME=leandrys
LANG=en_US.UTF-8
LS_COLORS=rs=0:di=01;34:ln=01;36:mh=00:pi=40;33:so=01;35:do=01;35:bd=40;33;01:cd=40;33;01:or=40;31;01:mi=00:su=37;41:sg=30;43:ca=30;41:tw=30;42:ow=34;42:st=37;44:ex=01;32:.tar=01;31:.tgz=01;31:.arc=01;31:.arj=01;31:.taz=01;31:.lha=01;31:.lz4=01;31:.lzh=01;31:.lzma=01;31:.tlz=01;31:.txz=01;31:.tzo=01;31:.t7z=01;31:.zip=01;31:.z=01;31:.dz=01;31:.gz=01;31:.lrz=01;31:.lz=01;31:.lzo=01;31:.xz=01;31:.zst=01;31:.tzst=01;31:.bz2=01;31:.bz=01;31:.tbz=01;31:.tbz2=01;31:.tz=01;31:.deb=01;31:.rpm=01;31:.jar=01;31:.war=01;31:.ear=01;31:.sar=01;31:.rar=01;31:.alz=01;31:.ace=01;31:.zoo=01;31:.cpio=01;31:.7z=01;31:.rz=01;31:.cab=01;31:.wim=01;31:.swm=01;31:.dwm=01;31:.esd=01;31:.jpg=01;35:.jpeg=01;35:.mjpg=01;35:.mjpeg=01;35:.gif=01;35:.bmp=01;35:.pbm=01;35:.pgm=01;35:.ppm=01;35:.tga=01;35:.xbm=01;35:.xpm=01;35:.tif=01;35:.tiff=01;35:.png=01;35:.svg=01;35:.svgz=01;35:.mng=01;35:.pcx=01;35:.mov=01;35:.mpg=01;35:.mpeg=01;35:.m2v=01;35:.mkv=01;35:.webm=01;35:.webp=01;35:.ogm=01;35:.mp4=01;35:.m4v=01;35:.mp4v=01;35:.vob=01;35:.qt=01;35:.nuv=01;35:.wmv=01;35:.asf=01;35:.rm=01;35:.rmvb=01;35:.flc=01;35:.avi=01;35:.fli=01;35:.flv=01;35:.gl=01;35:.dl=01;35:.xcf=01;35:.xwd=01;35:.yuv=01;35:.cgm=01;35:.emf=01;35:.ogv=01;35:.ogx=01;35:.aac=00;36:.au=00;36:.flac=00;36:.m4a=00;36:.mid=00;36:.midi=00;36:.mka=00;36:.mp3=00;36:.mpc=00;36:.ogg=00;36:.ra=00;36:.wav=00;36:.oga=00;36:.opus=00;36:.spx=00;36:.xspf=00;36:
XDG_CURRENT_DESKTOP=pop:GNOME
VTE_VERSION=6800
GNOME_TERMINAL_SCREEN=/org/gnome/Terminal/screen/9ee99dcc_acbb_4455_a573_21b8ce74f837
LESSCLOSE=/usr/bin/lesspipe %s %s
XDG_SESSION_CLASS=user
TERM=xterm-256color
LESSOPEN=| /usr/bin/lesspipe %s
USER=leandrys
GNOME_TERMINAL_SERVICE=:1.1756
DISPLAY=:1
SHLVL=1
QT_IM_MODULE=ibus
XDG_RUNTIME_DIR=/run/user/1000
XDG_DATA_DIRS=/usr/share/pop:/usr/share/gnome:/home/leandrys/.local/share/flatpak/exports/share:/var/lib/flatpak/exports/share:/usr/local/share/:/usr/share/
PATH=/home/leandrys/.cargo/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin:.nvim/bin/
GDMSESSION=pop
DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/1000/bus
_=/usr/bin/env
OLDPWD=/home/leandrys

@ghost
Copy link
Author

ghost commented Aug 12, 2023

do you consider that for the use of a simple print i need to use this? sorry but i consider it is a bug, i have never seen any lang that can not show the output correctly, the best part is it ask for the user entry and later show the placeholder... sorry i don't understand it

@saethlin
Copy link
Member

The Rust issue tracker is not a support forum. Rust has an official forum: https://users.rust-lang.org/ a subreddit: https://www.reddit.com/r/rust/ a community Discord: https://discord.com/invite/rust-lang-community and an official Discord: https://discord.com/invite/rust-lang. Those are all better places to seek help in using Rust than the issue tracker.

The code you posted in this issue description does not reproduce the problem. I can say that with total certainty because it doesn't compile, and therefore it is very tempting to explain what you are reporting here as incorrect transcription of what's in your editor or pasting an old version of your code. This program does produce the behavior you reported, but using different code:

use std::io;
use std::io::Read;

fn main() {
    // vars
    let mut guess = String::new();

    println!("Guess the number!");

    // take user input
    print!("Please, input your guess ");

    io::stdin()
        .read_line(&mut guess)
        .expect("failed to read line :(");

    println!("You guessed: {}!", guess);
}

I suggest you double-check that you have code that reproduces the behavior you find problematic, then start a conversation at any of the alternative venues I suggested. You will almost certainly find them more responsive.

@saethlin saethlin removed C-bug Category: This is a bug. needs-triage This issue may need triage. Remove it if it has been sufficiently triaged. labels Aug 12, 2023
@saethlin saethlin closed this as not planned Won't fix, can't repro, duplicate, stale Aug 12, 2023
@ghost
Copy link
Author

ghost commented Aug 12, 2023

I do not consider it professional to treat a person who is trying to help in a certain way with what little they know, if I made this contribution it is because at least I have worked with other languages ​​and I know that this is not a normal way out since it is not correct that first ask for the user input and after the input is entered the "enter a number" message is displayed, but don't worry even if your way of responding to my innocent intention to help is bad I don't plan to take it much more than an answer . If I wanted help from someone to tell me how to write code easily I would have asked anywhere since a console program is something that anyone can understand.

The Rust issue tracker is not a support forum. Rust has an official forum: https://users.rust-lang.org/ a subreddit: https://www.reddit.com/r/rust/ a community Discord: https://discord.com/invite/rust-lang-community and an official Discord: https://discord.com/invite/rust-lang. Those are all better places to seek help in using Rust than the issue tracker.

The code you posted in this issue description does not reproduce the problem. I can say that with total certainty because it doesn't compile, and therefore it is very tempting to explain what you are reporting here as incorrect transcription of what's in your editor or pasting an old version of your code. This program does produce the behavior you reported, but using different code:

use std::io;
use std::io::Read;

fn main() {
    // vars
    let mut guess = String::new();

    println!("Guess the number!");

    // take user input
    print!("Please, input your guess ");

    io::stdin()
        .read_line(&mut guess)
        .expect("failed to read line :(");

    println!("You guessed: {}!", guess);
}

I suggest you double-check that you have code that reproduces the behavior you find problematic, then start a conversation at any of the alternative venues I suggested. You will almost certainly find them more responsive.

I do not consider it professional to treat a person who is trying to help in a certain way with what little they know, if I made this contribution it is because at least I have worked with other languages ​​and I know that this is not a normal way out since it is not correct that first ask for the user input and after the input is entered the "enter a number" message is displayed, but don't worry even if your way of responding to my innocent intention to help is bad I don't plan to take it much more than an answer . If I wanted help from someone to tell me how to write code easily I would have asked anywhere since a console program is something that anyone can understand.

@workingjubilee
Copy link
Member

@Leandrys-Osorio There are very few explanations for your problem, either

  1. you were not reporting the code you actually used
  2. the terminal/shell you were outputting to was modifying the output somehow
  3. somehow, you were using a glibc with a broken write and flush implementation
  4. the kernel, which handles write requests, was broken somehow

...note that I listed these in order of decreasing probability.

We are not trying to be rude, but it can be very challenging to sort out a problem if you modify the reported code in any way. Nonetheless, I benignly assumed that your added line numbers could be removed, and that imports could be added, and everything could be wrapped in fn main() {}, and I could not reproduce your report with the code thus modified to compile. So I assumed that you were telling the truth, and I started to ask about your shell or libc or kernel.

We have also mentioned write-flushing. You say a console program is something anyone can understand, but many people are not aware of streams, buffers, and flushing. Thus they do not necessarily understand the documentation for print! and println!.

Rust quite deliberately offers fairly low-level control of many things, including printing. You mention you have not encountered any difficulty with other programming languages, but most languages deliberately obfuscate and remove control of what is actually quite a complex process.

@SkiFire13
Copy link
Contributor

Looks like this was discussed extensively in #23818

@ghost
Copy link
Author

ghost commented Aug 13, 2023

@Leandrys-Osorio There are very few explanations for your problem, either

1. you were not reporting the code you actually used

2. the terminal/shell you were outputting to was modifying the output somehow

3. somehow, you were using a glibc with a broken `write` and `flush` implementation

4. the kernel, which handles write requests, was broken somehow

...note that I listed these in order of decreasing probability.

We are not trying to be rude, but it can be very challenging to sort out a problem if you modify the reported code in any way. Nonetheless, I benignly assumed that your added line numbers could be removed, and that imports could be added, and everything could be wrapped in fn main() {}, and I could not reproduce your report with the code thus modified to compile. So I assumed that you were telling the truth, and I started to ask about your shell or libc or kernel.

We have also mentioned write-flushing. You say a console program is something anyone can understand, but many people are not aware of streams, buffers, and flushing. Thus they do not necessarily understand the documentation for print! and println!.

Rust quite deliberately offers fairly low-level control of many things, including printing. You mention you have not encountered any difficulty with other programming languages, but most languages deliberately obfuscate and remove control of what is actually quite a complex process.

Thank you very much, at least although I don't think you're exactly right, your answer seems a bit nicer, thanks again for assuming that the numbers in front of the code is just a placeholder put on purpose, obviously no code can compile having numbers in front of it. In any case, my concern was that it asked me to enter the data first and then it showed the text asking me to enter the data. But I am not one to tell you whether to believe my report or not. Thank you again and have a great day

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants