简体   繁体   English

如何在 C 程序中打印序数指标? 无法打印带有 'st'、'nd'、'rd' 的数字。 (初学者)

[英]How do I print ordinal indicators in a C program? Can't print numbers with 'st', 'nd', 'rd'. (Beginner)

#include <stdio.h>

main()
{
    int i, num, sum=0; //declaration
    printf("How many numbers do you want to calculate average of?\n");
    scanf("%d", &num); //how many numbers are to be calculated
    printf("Enter %d numbers\n", num);

    int a[num]; //array to store data
    for(i=1;i<=num;i++) //loop to take input 
    {
        if(i==1) //for 1st
            printf("1st value : ");
        else if (i<=2) //2nd
            printf("2nd value : ");
        else if (i<=3) //3rd
            printf("3rd value : ");
        else //else print th ordinal
            printf("%dth value : ", i);
        scanf("%d", &a[i]);
    }

    for(i=1;i<=num;i++)
        sum+=a[i];

    float avg;
    avg=sum/num;
    printf("Average : %f", avg);

    return 0;
}

A program to take out the average of n numbers.一个程序,用于取出 n 个数字的平均值。 Now, this code does what it should, but if the size of the array goes beyond 20, it prints 21th, 22th, 23th and so on, which is wrong.现在,这段代码做了它应该做的,但是如果数组的大小超过 20,它会打印 21th、22th、23th 等等,这是错误的。 I can't think of how to fix this problem.我想不出如何解决这个问题。 Any help would be great.任何帮助都会很棒。 I am new to programming, so pardon my ignorance.我是编程新手,所以请原谅我的无知。 输出描述需要修复的内容

There isn't a standard function that does that.没有标准的 function 可以做到这一点。 You can write one, or use mine:你可以写一个,或者使用我的:

ordinal.c

#include "ordinal.h"
#include <stdio.h>

static const char *const suffixes[4] = { "th", "st", "nd", "rd" };
enum { NUM_SUFFIXES = sizeof(suffixes) / sizeof(suffixes[0]) };

static unsigned suffix_index(unsigned n)
{
    unsigned x;

    x = n % 100;
    if (x == 11 || x == 12 || x == 13)
        x = 0;
    else if ((x = x % 10) > 3)
        x = 0;
    return x;
}

char *fmt_ordinal(char *buffer, size_t buflen, unsigned n)
{
    unsigned x = suffix_index(n);
    int len = snprintf(buffer, buflen, "%u%s", n, suffixes[x]);
    if (len <= 0 || (size_t)len >= buflen)
        return 0;
    return(buffer);
}

ordinal.h

/* returns buffer or 0 on failure (implausible unless buffer too small) */
extern char *fmt_ordinal(char *buffer, size_t buflen, unsigned n);

Some of that is overkill on its own, but the source file also contains scn_ordinal() which scans ordinal numbers with greater or lesser strictness, and the header declares it.其中一些本身就是矫枉过正,但源文件还包含scn_ordinal() ,它以或多或少的严格性扫描序数,并且 header 声明了它。

int main(void)
{
    char buffer[15];

    /* Test fmt_ordinal() */
    for (unsigned i = 0; i < 35; i++)
        printf("%2u => %4s\n", i, fmt_ordinal(buffer, sizeof(buffer), i));

    return 0;
}

You can mod by 10 to get the last digit.你可以修改 10 来得到最后一个数字。 Then based on that you can use "st", "nd", "rd", or "th".然后基于此,您可以使用“st”、“nd”、“rd”或“th”。 You'll also need special cases for 11, 12, and 13.您还需要 11、12 和 13 的特殊情况。

    if ((i % 10 == 1) && (i % 100 != 11))
        printf("%dst value : ", i);
    else if ((i % 10 == 2) && (i % 100 != 12))
        printf("%dnd value : ", i);
    else if ((i % 10 == 3) && (i % 100 != 13))
        printf("%drd value : ", i);
    else
        printf("%dth value : ", i);

I played with this a bit and this was my minimal 'lookup' except, sadly, for the expense of the modulo division.我玩了一下,这是我最小的“查找”,但遗憾的是,以模除法为代价。 I wasn't fussed about values above 99.我对高于 99 的值并不在意。

if( i > 20 ) i %= 10; // Change 21-99 to 1-10.
if( i >  3 ) i  =  0; // Every other one ends with "th"
//         0   1   2   3 
suffix = &"th\0st\0nd\0rd"[ i * 3 ];  // Acknowledge 3byte regions.

You can use 'suffix' as a pointer to a normal null terminated string.您可以使用“后缀”作为指向普通 null 终止字符串的指针。

It is okay to be a beginner, no need to apologize.初学者没关系,没必要道歉。 You can solve your problem using a combination of a SWITCH statement and the modulus operator (%).您可以结合使用 SWITCH 语句和取模运算符 (%) 来解决问题。 The modulus operator takes two numbers (n1 % n2) and returns the remainder when n1 is divided by n2.模运算符接受两个数字 (n1 % n2) 并在 n1 除以 n2 时返回余数。

You will want to construct an array of ordinals, like this:您将需要构造一个序数数组,如下所示:

char *ordinalList[] = { "st", "nd", "rd", "th" };

This will allow you to simply reference this array to append the correct ordinal to a number.这将允许您简单地将此数组引用到 append 正确的数字序号。 The next step is to create an algorithm to determine which array index should be referenced.下一步是创建一个算法来确定应该引用哪个数组索引。 To do this, you can make a new function and call it in your "main".为此,您可以制作一个新的 function 并在“main”中调用它。

char *determineOrdinal (char **ordinalList, int numValue)
{

    if (3 < numValue && numValue < 21)
        return ordinals[3];

    switch (numValue % 10) {
        case 1 :    return ordinalList[0];
                    break;
        case 2 :    return ordinalList[1];
                    break;
        case 3 :    return ordinalList[2];
                    break;
        default:    return ordinalList[3];
                    break;
}

You can pass a number into this function as the numValue argument.您可以将一个数字作为 numValue 参数传递到此 function 中。 Your "main" function might look something like this:您的“主要” function 可能看起来像这样:

#include <stdio.h>

int main(void)
{
    char *ordinalList[] = { "st", "nd", "rd", "th" };
    char *currentdOrdinal;
    int i, num, sum=0; //declaration
    printf("How many numbers do you want to calculate average of?\n");
    scanf("%d", &num); //how many numbers are to be calculated
    printf("Enter %d numbers\n", num);

    int a[num]; //array to store data
    for(i=1;i<=num;i++) //loop to take input 
    {
        currentdOrdinal = determineOrdinal (ordinalList, i)
        printf("%d%s value : ", i, currentdOrdinal);
        scanf("%d", &a[i]);
    }

    for(i=1;i<=num;i++)
        sum+=a[i];

    float avg;
    avg=sum/num;
    printf("Average : %f", avg);

    return 0;
}

I think that code should work for you.我认为该代码应该适合您。 I hope this helps.我希望这有帮助。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM