更新同一行上的printf值而不是新行

时间:2013-03-03 23:56:09

标签: c

我想知道C中是否有办法覆盖已经打印过的现有值,而不是每次创建新行或只是在空格上移动。我需要从传感器获取实时数据,并希望它只是坐在那里并不断更新现有值而无需任何滚动。这可能吗?

更新:添加代码

#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);
}
};

8 个答案:

答案 0 :(得分:23)

你正在寻找回车。在C中,那是\r。这将使光标返回到当前行的开头而不开始新行(换行)

答案 1 :(得分:18)

您应该像其他人所说的那样将\r添加到您的printf中。 此外,请确保刷新stdout,因为stdout流已缓冲&amp;只会在到达换行符后显示缓冲区中的内容。

在你的情况下:

for (int i=0;i<10;i++){
    //...
    printf("\rValue of X is: %d", x/114);
    fflush(stdout);
    //...
}

答案 2 :(得分:5)

您可以使用“\ r”而不是“\ n”来完成。

答案 3 :(得分:2)

印在何处?

如果您正在将数据输出到标准输出,则通常无法返回并更改已编写的任何内容。如果您的标准输出定向到终端,您可以尝试输出\r字符,将光标移动到某些终端上的行的开头(效果取决于平台),以便后续输出行将覆盖以前印在那条线上的东西。这将产生旧数据被新数据替换的视觉效果。但是,这并不真正“替换”流中的旧数据,这意味着如果将标准输出重定向到文件,该文件将存储打印的所有内容。请记住,\r会强制您覆盖终端上的整行。

如果您将数据输出到文件,那么您可以使用fseek函数返回之前访问过的某个点并从那里“重新开始”,覆盖过程中的数据。

答案 4 :(得分:1)

您可以打印出与控制台屏幕一样多的换行符。这将有效地清除屏幕。

这是一个很好的link关于清算屏幕的不同方式。

答案 5 :(得分:1)

您是否测试了'\ b'字符(退格键)?也许取决于您的控制台。

答案 6 :(得分:-1)

请参阅示例代码以了解:

//  Original code created by Daniel Cohen Gindi on 17/3/15.
//
//  Copyright 2015 Daniel Cohen Gindi & Philipp Jahoda
//  A port of MPAndroidChart for iOS
//  Licensed under Apache License 2.0
//
//  https://github.com/danielgindi/ios-charts
//

#import "LineChart2ViewController.h"
#import "ChartsDemo-Swift.h"

@interface LineChart2ViewController () <ChartViewDelegate>

@property (nonatomic, strong) IBOutlet LineChartView *chartView;
@property (nonatomic, strong) IBOutlet UISlider *sliderX;
@property (nonatomic, strong) IBOutlet UISlider *sliderY;
@property (nonatomic, strong) IBOutlet UITextField *sliderTextX;
@property (nonatomic, strong) IBOutlet UITextField *sliderTextY;

@end

@implementation LineChart2ViewController

- (void)viewDidLoad
{
    [super viewDidLoad];

    self.title = @"Line compare";
    _chartView.delegate = self;

    _chartView.descriptionText = @"";
    _chartView.noDataTextDescription = @"You need to provide data for the chart.";

    _chartView.highlightEnabled = YES;
    _chartView.dragEnabled = YES;
    [_chartView setScaleEnabled:YES];
    _chartView.drawGridBackgroundEnabled = NO;
    _chartView.pinchZoomEnabled = YES;

    _chartView.backgroundColor = [UIColor colorWithWhite:204/255.f alpha:1.f];

    _chartView.legend.form = ChartLegendFormLine;
    _chartView.legend.font = [UIFont fontWithName:@"HelveticaNeue-Light" size:11.f];
    _chartView.legend.textColor = UIColor.whiteColor;
    _chartView.legend.position = ChartLegendPositionBelowChartLeft;

    ChartXAxis *xAxis = _chartView.xAxis;
    xAxis.labelFont = [UIFont systemFontOfSize:12.f];
    xAxis.labelTextColor = UIColor.whiteColor;
    xAxis.drawGridLinesEnabled = NO;
    xAxis.drawAxisLineEnabled = NO;
    xAxis.spaceBetweenLabels = 1.0;

    ChartYAxis *leftAxis = _chartView.leftAxis;
    leftAxis.labelTextColor = [UIColor colorWithRed:51/255.f green:181/255.f blue:229/255.f alpha:1.f];
    leftAxis.customAxisMax = 3;
    leftAxis.drawGridLinesEnabled = YES;

    ChartYAxis *rightAxis = _chartView.rightAxis;
    rightAxis.labelTextColor = UIColor.redColor;
    rightAxis.customAxisMax = 20.0;
    rightAxis.startAtZeroEnabled = NO;
    rightAxis.customAxisMin = 0.0;
    rightAxis.drawGridLinesEnabled = NO;
    [rightAxis setEnabled:NO];

    [self setDataCount:20 range:4];

    [_chartView animateWithXAxisDuration:2.5];
}

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

- (void)setDataCount:(int)count range:(double)range
{
    NSMutableArray *xVals = [[NSMutableArray alloc] init];

    for (int i = 0; i < count; i++)
    {
        [xVals addObject:[@(i) stringValue]];
    }

    NSMutableArray *yVals = [[NSMutableArray alloc] init];

    for (int i = 0; i < count; i++)
    {
        //double val = (double) (arc4random_uniform(range));
        double val = 1.0;
        [yVals addObject:[[ChartDataEntry alloc] initWithValue:val xIndex:i]];
    }

    LineChartDataSet *set1 = [[LineChartDataSet alloc] initWithYVals:yVals label:@"Line 1"];
    set1.axisDependency = AxisDependencyLeft;
    [set1 setColor:[UIColor colorWithRed:51/255.f green:181/255.f blue:229/255.f alpha:1.f]];
    [set1 setCircleColor:UIColor.whiteColor];
    set1.lineWidth = 2.0;
    set1.circleRadius = 3.0;
    set1.fillAlpha = 65/255.0;
    set1.fillColor = [UIColor colorWithRed:51/255.f green:181/255.f blue:229/255.f alpha:1.f];
    set1.highlightColor = [UIColor colorWithRed:244/255.f green:117/255.f blue:117/255.f alpha:1.f];
    set1.drawCircleHoleEnabled = NO;

    NSMutableArray *yVals2 = [[NSMutableArray alloc] init];

    for (int i = 0; i < count; i++)
    {
        double val = 2.0;
        ChartDataEntry * dataEntry = [[ChartDataEntry alloc] initWithValue:val xIndex:i];
        [yVals2 addObject:dataEntry];
    }

    LineChartDataSet *set2 = [[LineChartDataSet alloc] initWithYVals:yVals2 label:@"Line 2"];
    set2.axisDependency = AxisDependencyRight;
    [set2 setColor:UIColor.redColor];
    [set2 setCircleColor:UIColor.whiteColor];
    set2.lineWidth = 2.0;
    set2.circleRadius = 3.0;
    set2.fillAlpha = 65/255.0;
    set2.fillColor = UIColor.redColor;
    set2.highlightColor = [UIColor colorWithRed:244/255.f green:117/255.f blue:117/255.f alpha:1.f];
    set2.drawCircleHoleEnabled = NO;

    NSMutableArray *yVals3 = [[NSMutableArray alloc] init];

    for (int i = 0; i < count; i++)
    {
        double val = 3.0;
        [yVals3 addObject:[[ChartDataEntry alloc] initWithValue:val xIndex:i]];
    }

    LineChartDataSet *set3 = [[LineChartDataSet alloc] initWithYVals:yVals3 label:@"Line 3"];
    set3.axisDependency = AxisDependencyRight;
    [set3 setColor:UIColor.blueColor];
    [set3 setCircleColor:UIColor.whiteColor];
    set3.lineWidth = 2.0;
    set3.circleRadius = 3.0;
    set3.fillAlpha = 65/255.0;
    set3.fillColor = UIColor.blueColor;
    set3.highlightColor = [UIColor colorWithRed:244/255.f green:117/255.f blue:117/255.f alpha:1.f];
    set3.drawCircleHoleEnabled = NO;

    NSMutableArray *dataSets = [[NSMutableArray alloc] init];
    [dataSets addObject:set1];
    [dataSets addObject:set2];
    [dataSets addObject:set3];

    LineChartData *data = [[LineChartData alloc] initWithXVals:xVals dataSets:dataSets];
    [data setValueTextColor:UIColor.whiteColor];
    [data setValueFont:[UIFont systemFontOfSize:9.f]];

    _chartView.data = data;
}

Reference Blog

答案 7 :(得分:-2)

除了以上答案外,\ r实际上是终端的代码。 c似乎没有提供一种方法来更改已放入stdout流中的程序。

#include<stdio.h>
int main(){
    freopen("output.txt", "w", stdout);
    printf("somthing");
    printf("\r other thing");
}

在output.txt中,某些内容没有改变,这导致\ r对txt文件没有任何意义。 但是对于终端,\ r是有意义的。它可以处理格式并显示效果很好。

使用终端代码可以做一些有趣的事情。像下面一样

#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);
}

}