C语言 在同一行上更新 printf 值而不是新值
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/15192441/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Update printf value on same line instead of new one
提问by Yamaha32088
I would like to know if there is a way in Cto overwrite an existing value that has already been printed instead of creating a new line every time or just moving over a space. I need to obtain real time data from a sensor and would like it to just sit there and keep updating the existing values without any scrolling. Is this possible?
我想知道是否有办法C覆盖已经打印的现有值,而不是每次都创建一个新行或只是移动一个空格。我需要从传感器获取实时数据,并希望它只是坐在那里并不断更新现有值而无需任何滚动。这可能吗?
UPDATE: ADDED CODE
更新:添加代码
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdint.h>
#include <time.h>
#include <wiringPi.h>
#include <wiringPiI2C.h>
#define CTRL_REG1 0x20
#define CTRL_REG2 0x21
#define CTRL_REG3 0x22
#define CTRL_REG4 0x23
int fd;
short x = 0;
short y = 0;
short z = 0;
int main (){
fd = wiringPiI2CSetup(0x69); // I2C address of gyro
wiringPiI2CWriteReg8(fd, CTRL_REG1, 0x1F); //Turn on all axes, disable power down
wiringPiI2CWriteReg8(fd, CTRL_REG3, 0x08); //Enable control ready signal
wiringPiI2CWriteReg8(fd, CTRL_REG4, 0x80); // Set scale (500 deg/sec)
delay(200); // Wait to synchronize
void getGyroValues (){
int MSB, LSB;
LSB = wiringPiI2CReadReg8(fd, 0x28);
MSB = wiringPiI2CReadReg8(fd, 0x29);
x = ((MSB << 8) | LSB);
MSB = wiringPiI2CReadReg8(fd, 0x2B);
LSB = wiringPiI2CReadReg8(fd, 0x2A);
y = ((MSB << 8) | LSB);
MSB = wiringPiI2CReadReg8(fd, 0x2D);
LSB = wiringPiI2CReadReg8(fd, 0x2C);
z = ((MSB << 8) | LSB);
}
for (int i=0;i<10;i++){
getGyroValues();
// In following Divinding by 114 reduces noise
printf("Value of X is: %d\r", x/114);
// printf("Value of Y is: %d", y/114);
// printf("Value of Z is: %d\r", z/114);
int t = wiringPiI2CReadReg8(fd, 0x26);
t = (t*1.8)+32;//convert Celcius to Fareinheit
int a = wiringPiI2CReadReg8(fd,0x2B);
int b = wiringPiI2CReadReg8(fd,0x2A);
// printf("Y_L equals: %d\r", a);
// printf("Y_H equals: %d\r", b);
int c = wiringPiI2CReadReg8(fd,0x28);
int d = wiringPiI2CReadReg8(fd,0x29);
// printf("X_L equals: %d\r", c);
// printf("X_H equals: %d\r", d);
int e = wiringPiI2CReadReg8(fd,0x2C);
int f = wiringPiI2CReadReg8(fd,0x2D);
// printf("Z_L equals: %d\r", e);
// printf("Z_H equals: %d\r", f);
// printf("The temperature is: %d\r", t);
delay(2000);
}
};
回答by Yaniv
You're looking for a carriage return. In C, that's \r. This will take the cursor back to the start of the current line without starting a new line (linefeed)
您正在寻找回车。在 C 中,就是\r. 这将使光标回到当前行的开头而不开始新行(换行)
回答by Zaxter
You should add \rto your printf as others have said.
Also, make sure you flush stdout, as stdout stream is buffered & will only display what's in the buffer after it reaches a newline.
您应该\r像其他人所说的那样添加到 printf 中。此外,请确保刷新标准输出,因为标准输出流已缓冲,并且只会在到达换行符后显示缓冲区中的内容。
In your case:
在你的情况下:
for (int i=0;i<10;i++){
//...
printf("\rValue of X is: %d", x/114);
fflush(stdout);
//...
}
回答by Gorbag
You can do it by using "\r" instead of "\n".
您可以使用“\r”而不是“\n”来实现。
回答by AnT
Printed where?
印在哪里?
If your are outputting data to the standard output, you can't generally come back and change anything that has already been written. If your standard output is directed to terminal, you can try outputting \rcharacter that will move the cursor to the beginning of the line on some terminals (the effect is platform-dependent), so that the subsequent output line will overwrite what was printed in that line previously. This will produce a visual effect of old data being replaced with new data. However, this does not really "replace" the old data in the stream, meaning that if you redirect the standard output to file, the file will store everything that was printed. Keep in mind again, that \rwill force you overwrite the entire line on the terminal.
如果您将数据输出到标准输出,您通常无法返回并更改已写入的任何内容。如果您的标准输出被定向到终端,您可以尝试输出\r将光标移动到某些终端上的行首的字符(效果取决于平台),以便后续输出行将覆盖其中打印的内容线之前。这将产生旧数据被新数据替换的视觉效果。但是,这并没有真正“替换”流中的旧数据,这意味着如果您将标准输出重定向到文件,该文件将存储打印的所有内容。再次记住,这\r将迫使您覆盖终端上的整行。
If you output your data to a file, then you can use fseekfunction to go back to some previously visited point and "start over" from there, overwriting the data in the process.
如果您将数据输出到文件,那么您可以使用fseek函数返回到之前访问过的某个点并从那里“重新开始”,覆盖过程中的数据。
回答by Josh Petitt
Have you tested the '\b' character (backspace)? Maybe works depending on your console.
您是否测试过 '\b' 字符(退格)?也许工作取决于你的控制台。
回答by Josh Petitt
回答by parasrish
Refer to the sample code to understand:
参考示例代码了解:
#include <stdio.h>
#include <pthread.h>
void myThread(void* ptr) {
printf("Hello in thread\n");
int i=0;
for(;i<10;i++)
{
sleep(1);
printf(". ");
fflush(stdout); //comment this, to see the difference in O/P
}
printf("sleep over now\n");
}
int main(void) {
pthread_t tid;
printf("creating a new thread\n");
pthread_create(&tid, NULL, (void*)myThread, 0);
printf("going to join with child thread..\n");
pthread_join(tid, NULL);
printf("joined..!!\n");
return 0;
}
回答by Richard Lee
In addition to answers above, \r is actually a code of the terminal. c seems don't provide a way to change whatever program has already put into stdout stream.
除了上面的答案,\r 实际上是终端的代码。c 似乎没有提供一种方法来更改已放入标准输出流中的任何程序。
#include<stdio.h>
int main(){
freopen("output.txt", "w", stdout);
printf("somthing");
printf("\r other thing");
}
in output.txt, something doesn't change, cause \r doesn't mean anything for a txt file. But for the terminal, \r is meaningful. It handles format and displays well.
在 output.txt 中,某些内容没有改变,因为 \r 对 txt 文件没有任何意义。但是对于终端,\r 是有意义的。它处理格式并显示良好。
Using terminal codes could do some fun things. like below
使用终端代码可以做一些有趣的事情。像下面
#include<iostream>
#include<bits/stdc++.h>
#include<unistd.h>
int main(){
std::string processBar[] {
"00%: [ ]",
"05%: [# ]",
"10%: [## ]",
"15%: [### ]",
"20%: [#### ]",
"25%: [##### ]",
"30%: [###### ]",
"35%: [####### ]",
"40%: [######## ]",
"45%: [######### ]",
"50%: [########## ]",
"55%: [########### ]",
"60%: [############ ]",
"65%: [############# ]",
"70%: [############## ]",
"75%: [############### ]",
"80%: [################ ]",
"85%: [################# ]",
"90%: [################### ]",
"95%: [#################### ]",
"100%:[#####################]",
};
int n = sizeof(processBar)/ sizeof(*processBar);
// pretty fanny
for(int i{0}; i<n; ++i){
fprintf(stdout, "\e[%d;1H \e[2K \r \a%s", i, processBar[i].c_str());
fflush(stdout);
sleep(1);
}
}

