在用户输入旁边打印输出

时间:2017-01-16 10:20:15

标签: c printf scanf

我是编码和尝试完成作业的初学者。

根据问题,用户需要输入停放车辆的小时数,并在其旁边打印小时的总费用。

例如:

enter image description here

我创建了这个简单的程序

#include<stdio.h>>
#include<math.h>

float calculateCharges(float hurs);
int main()
{
    float hours;//total no of hours vehicle is parked
    int i;

    printf("%s%10s%10s", "Car", "Hours", "Charges");

    for (i = 1; i <= 3; i++)
    {
        printf("\n%d\t", i);
        scanf("%f", &hours);
        printf("\t%f\n", calculateCharges(hours));
    }




    getch();
    return 0;
}


float calculateCharges(float hurs)
{

    float charges;

    hurs = ceil(hurs);

    if (hurs >= 24) charges = 10; 
    else
    {
        if (hurs <= 3) charges = 2;
        else
        {
            hurs = hurs - 3;
            charges = 2 + 0.5*hurs;

        }

    }

    return charges;
}

但是现在每次我输入时间都会将费用打印在它下面而不是旁边。如图所示:

enter image description here

有没有办法在scanf之后使用换行符?这样费用可以打印在scanf旁边吗?

我也以这种方式修改了我的代码,但它没有任何区别。

printf("%s%10s%10s", "Car", "Hours", "Charges");

    for (i = 1; i <= 3; i++)
    {
        printf("\n%d\t", i);
        printf("\t%f\n",(scanf("%f", &hours),calculateCharges(hours)));
    }

在你投票并埋葬这个问题之前,请考虑我是C的初学者。任何帮助都感激不尽。

如果需要原始问题,请告诉我。我正在使用Visual Studio 2017 RC。

2 个答案:

答案 0 :(得分:2)

您可以使用以下内容:

#include <iostream>
#include <windows.h>

//This will set the position of the cursor
void gotoXY(int x, int y) {
    //Initialize the coordinates
    COORD coord = {x, y};
    //Set the position
    SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), coord);
    return;
}

void getCursorXY(int &x, int&y) {
    CONSOLE_SCREEN_BUFFER_INFO csbi;
    if(GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &csbi)) {
        x = csbi.dwCursorPosition.X;
        y = csbi.dwCursorPosition.Y;

    }
}

我发现它here。 正如其中一个答案所述,此解决方案平台无关。

但我想在其他平台上有类似的解决方案,您可以轻松地将光标设置在您想要的位置。

主要使用示例:

for (i = 1; i <= 3; i++)
{
    printf("\n%d\t", i);
    scanf("%f", &hours);
    gotoXY( 20, i + 1);
    printf("\t%f\n", calculateCharges(hours));
}

可以找到scanf的解决方法here

答案 1 :(得分:1)

scanf_s总是在输入时生成一个新行,不幸的是其他用户输入捕获平台独立的功能我知道(getc&amp; getchar)也这样做。无论如何,在Windows上可以使用conio header中的_getch()来完成。

#include <conio.h>
#include <stdlib.h>
#include <stdio.h>

int getIntFromUser()
{
    char readCharacters[10];

    int index = 0;
    for (int currentChar = _getch(); currentChar != '\r'; currentChar = _getch())
    {
        if (currentChar == EOF)
        {
            // Some error that shouldn't occour in your simple homework program
        }
        if (index > 9)
        {
            // Another possible error case where you would start to write beyond 'readCharacters' array
        }

        // We might as well disallow anything but digits, enter & backspace (You don't need anything else, do you?)
        if ((currentChar < '0' || currentChar > '9') && currentChar != '\b')
        {
            continue;
        }
        else if (currentChar == '\b')
        {
            if (index > 0)
            {
                // Delete last character
                printf("\b \b");
                readCharacters[index] = '\0';
                --index;
            }
        }
        else
        {
            printf("%c", currentChar);
            readCharacters[index] = currentChar;
            ++index;
        }
    }  

    if (index == 0)
    {
        // User pressed enter without having entered a number, let's give him a zero then
        return 0;
    }

    readCharacters[index] = '\0';

    int retVal = atoi(readCharacters);
    // Worth noting that the value of converted user given string shouldn't be greater than what a signed int can hold

    return retVal;
}

int main(int argc, char* argv[])
{
    // Unlike scanf_s this will not generate a new line on enter
    printf("getIntFromUser() sample (enter a number)\n");
    int someValue = getIntFromUser();
    printf(" -- This will be printed on the same line. (someValue is %d)\n\n", someValue);


    // scanf_s sample
    int anotherValue;
    printf("scanf_s() sample (Insert a number.)\n");
    scanf_s("%d", &anotherValue);
    printf("This will be printed on a new line\n\n");


    printf("Press any key to exit.");
    _getch();
    return 0;
}

EDIT
如果我在每个代码行添加注释,我觉得上面的内容会变得不那么容易。相反,我将逐步粘贴一些代码块。

但首先是关于_getch函数:它等待用户在控制台中键入内容然后将给定char的用户作为int返回。 char隐式转换为int,因此您可以将_getch结果与一个字符进行比较,就像我在getIntFromUser中多次执行一样(例如if (currentChar == '\b') { ... })。

您还应该了解char可以容纳的值以及它们作为int的值(查看http://en.cppreference.com/w/cpp/language/ascii)。 在桌子旁边的char&#39; 0&#39;将值48作为int,如果用户键入0,_getch将返回。

首先声明一个包含10个元素的数组/字符串。希望你已经知道了。在这种情况下,数组基本上是10个元素的链,它们都是char类型,也称为字符串。

char readCharacters[10];

需要字符串的索引器。

int index = 0;

下面我们有通常的for循环...
1st:创建一个int类型的变量,并将_getch的结果赋给它 第二:将确定循环是否应继续执行。在这种情况下,当currentChar不是&#39; \ r&#39;时,循环将中断,这是一个表示作为字符输入的转义序列。
第3步:将在内部执行一次,然后使用新的_getch更新currentChar。

for (int currentChar = _getch(); currentChar != '\r'; currentChar = _getch())

检查用户输入(通过_getch检索)是否小于&#39; 0&#39; (值为48为int)且大于&#39; 9&#39; (作为int的值57)。如果它们中的任何一个为真,它将另外检查currentChar的值是否不是&#39; \ b&#39; (值为8作为int),这是反斜杠的转义序列 当该附加检查评估为true时,则使用关键字continue。这意味着循环中的其余块不会被执行,而是循环将通过获取新的用户输入再次从顶部开始,并通过检查是否输入currentChar来评估是否要继续循环。

if ((currentChar < '0' || currentChar > '9') && currentChar != '\b')
{
    continue;
}

注意:在阅读这些内容之前,您可能需要阅读else语句中的注释 当上面的if语句为false时,我们会看到下面的if语句(实际上是if),我们将在下面看到 如上所述:&#39; \ b&#39;是反斜杠,如果这是用户给定的char以及字符串/数组索引大于0,我们在控制台中向后移动一个字符&#34; print&#34; &#39; \ B&#39;然后写一个空字符,以便删除之前在那个地方写的内容。这让我们回到了以前的位置,所以我们打印出另一个反斜杠。此时你可能想知道为什么不回到scanf_s导致的前一行,但这不会起作用。我们还必须忘记用空终止符替换最后一个字符串字符,然后将索引设置为1.

else if (currentChar == '\b')
{
    if (index > 0)
    {
        // Delete last character
        printf("\b \b");
        readCharacters[index] = '\0';
        --index;
    }
}

当我们达到这一点时,我们知道currentChar介于48到57之间(&#39; 0&#39;和&#39; 9&#39;)。 _getch告诉程序用户的输入是什么,但除非我们在那里打印,否则我们无法在控制台中看到它。所以,让我们这样做 同时将用户的给定字符附加到字符串以及将索引递增1.

else
{
    printf("%c", currentChar);
    readCharacters[index] = currentChar;
    ++index;
}

最后我们调用atoi函数将字符串/数组转换为整数。

int retVal = atoi(readCharacters);
相关问题