如何编写接受包含整数和标点字符的用户输入的C程序?

时间:2015-04-04 06:11:56

标签: c linux assembly

解决方案

#include <stdio.h>
#include <string.h>
 int main()
{
    char value[50];
    char *end;
    int sum = 0;
    long conv;
    while(conv != 0 )
    {
            printf("Enter a measurement and unit(Ex: 4' or 3\";0' or 0\" when done): ");
            fgets(value, 50, stdin);
            conv = strtol(value, &end, 10);
            if(strstr(value, "\'") != NULL)
            {
                    conv = strtol(value, &end, 10);
                    sum = sum + (conv*12);
            }
            else if(strstr(value, "\"") != NULL)
            {
                    conv = strtol(value, &end, 10);
                    sum = sum + conv;
            }
    }
    printf("Total: %d, %s\n", sum, "inches" );
    return 0;
}

更新仍有新程序问题..确保从何处开始。它接受数字和引号,但是当我输入单引号来指定英尺时,它只会将我输入的任何数字乘以12。 UPDATE2 以下是我们在编写C程序时应该记住的汇编函数:

void printStr(char *)
 Arguments:
 edi = address of null-terminated string to print
 Returns:
    Nothing

void printUInt(unsigned)
 Arguments:
 edi = Unsigned integer to print
 Returns:
  Nothing

 char getchar()
  Arguments:
  None
  Returns:
   eax = the next character

 uinsigned readUInt()
 Arguments:
 None
 Returns:
  eax = an unsigned int read from stdin.
       (eax is 0 on error)

我必须写一个C程序,提示用户输入一个测量(数字)和单位('或',代表英尺或英寸),然后打印出用户输入长度后的总长度(英寸) 0'作为哨兵值。

这个程序只需要我作为一种方式来构建具有类似结构的汇编程序。问题是,它必须围绕4个函数构建,这些函数将被调用以帮助执行某些操作。

所以我的C程序应该与这些功能类似地构建。这就是我所拥有的:

这是我的计划:

更新:

int main()
{
    char value[50];
    char *end;
    int sum = 0;
    long conv;
    while(conv != 0)
    {
            printf("Enter a measurement and unit: ");
            fgets(value, 50, stdin);
            conv = strtol(value, &end, 10);
            if(value[1]='\'')
            {
                    sum = sum + (conv*12);
            }
            if(value[1]='\"')
            {
                    sum = sum + conv;
            }
    }
    printf("Total: %d\n", sum);
    return 0;
}

OLD:

int main()
{
    int sum = 0;
    int value;
    char symbol;

    while(value != 1)
    {
            printf("Enter measurement and unit: ");
            scanf("%d,%d", &value, &symbol);

            if(symbol == "'")
            {
                    sum = sum + value*12;
            }
            else if(symbol == ''' )
            {
                    sum = sum + value;
            }

            sum = sum + value;
    }
    printf("Total: %d", sum);
    return 0;
}

我希望我有足够的信息可以帮助我,即使我知道我们暂时缺少完整的功能。我知道IA32汇编转换不是我的主要问题,如果我遇到困难,我想我会将其保存为另一个,但我希望这个高级语言程序得到纠正会让我朝着正确的方向前进。提前谢谢!

3 个答案:

答案 0 :(得分:1)

使用%c而非%d获取角色。将行更改为这样。

if ( scanf("%d,%c", &value, &symbol) != 2 )
       continue;

在比较时你必须这样做,

if(symbol == '\"')
{
           sum = sum + value*12;
}
else if(symbol == '\'' )
{
              sum = sum + value;
}

此后的输出,

Enter measurement and unit: 2,"
Enter measurement and unit: 3,'
Enter measurement and unit: 1,"
Total: 45

答案 1 :(得分:1)

当您考虑编写将转换为程序集的程序时,您希望将自己限制为使用与程序集中可用的系统调用具有1对1关联的调用。这意味着离开缓冲输入/输出的高级世界,并使用无缓冲的低级输入/输出方法,您负责计算进出程序的每个字节。即使是C语言中readwrite的低级例程,也提供了一些您必须手动处理的功能。

为了提供这种低级I / O的合理示例,我写了一个简短的例子,以英尺或英寸为单位进行输入测量,并保持输入的英尺和英寸的总计。该代码还将12英寸以上的任何英寸转换为英尺。这个例子提供了一个很好的近似方法,你将在程序集中做同样的事情。花点时间了解每个部分的作用,如果您有疑问,请告诉我。您编写的低级代码,完成看似简单的任务所需的时间越长。你的装配可能会长3倍。

该计划需要输入表格numfeet'numinches"。所以要输入10英尺,输入10',输入10英寸,请输入10"

#include <stdio.h>
#include <unistd.h>

#define STDINFD 0
#define STDOUTFD 1
#define newline write (STDOUTFD, "\n", 1)

#define MAXS 32

int main (void) {

    ssize_t n = 0;              /* number of characters read    */
    size_t i = 0;               /* general iteration variable   */
    size_t digits = 0;          /* digit counter                */
    char buf[MAXS] = {0};       /* buffer to hold input         */
    char *bp = buf;             /* pointer to input buffer      */
    char length[MAXS] = {0};    /* buffer to hold measurement   */
    char *p = length;           /* pointer to measurement       */
    char fbuf[MAXS] = {0};      /* buffer to hold feet          */
    char *fp = fbuf;            /* pointer to feet              */
    char ibuf[MAXS] = {0};      /* buffer to hold inches        */
    char *ip = ibuf;            /* pointer to inches            */
    unsigned feet = 0;          /* total feet entered           */
    unsigned inches = 0;        /* total inches entered         */
    unsigned num = 0;           /* general unsigned value       */
    unsigned mlt = 1;           /* place multiplier value       */
    unsigned incvt = 0;         /* inches to feet conversion    */
    char unit = 0;              /* buffer for ''' or '"'        */
    char const digit[] = "0123456789";  /* conversion string    */

    /* input prompt and labels */
    char prompt[] = "\n Enter measurement with units [feet' or inches\"]: ";
    char nlabel[] = "\n number : ";
    char ulabel[] = "\n   unit : ";
    char flabel[] = "\n   feet : ";
    char ilabel[] = "\n inches : ";

    /* write prompt to stdout */
    write (STDOUTFD, prompt, sizeof prompt);

    /* read length and unit until [CTRL+D] entered */
    while ((n = read (STDINFD, bp, 32)) != 0)
    {
        /* re-initialize values for each loop */
        bp = buf;
        p = length;
        fp = fbuf;
        ip = ibuf;
        i = 0;
        num = 0;
        incvt = 0;
        mlt = 1;
        unit = 0;

        /* parse each character read into buf */
        while (bp[i] != '\n')
        {

            if (bp[i] >= '0' && bp[i] <= '9')   /* is a digit   */
                *p++ = bp[i];

            if (bp[i] == 0x27)                  /* is a '       */
                unit = bp[i];

            if (bp[i] == '"')                   /* is a "       */
                unit = bp[i];

            i++;
        }

        /* null-terminate / decrement length pointer */
        *p = 0;
        p--;

        /* write length and unit to stdout */
        write (STDOUTFD, nlabel, sizeof nlabel);
        write (STDOUTFD, length, p - length + 1);
        write (STDOUTFD, ulabel, sizeof ulabel);
        write (STDOUTFD, &unit, sizeof unit);
        newline;

        /* convert characters in length to number */
        for (i = p - length; p >= length; p--)
        {
            num += (*p - '0') * mlt;
            mlt *= 10;
        }

        /* test unit and add to feet or inches */
        if (unit == '"')
            inches += num;
        if (unit == 0x27)
            feet += num;

        /* convert inches > 12 to feet */
        if (inches > 12)
        {
            incvt = inches / 12;
            inches -= incvt * 12;
            feet += incvt;
        }

        /* write label for total feet to stdout */
        write (STDOUTFD, flabel, sizeof flabel);

            /* determine number of digits in feet */
            i = 1;
            digits = 0;
            while (feet >= i && (1UL << 32))
            {
                digits++;
                i *= 10;
            }

            /* convert number to characters in feet buffer */
            num = feet;
            fp += digits - 1;
            while (fp >= fbuf)
            {
                *fp-- =  digit [num % 10];
                num /= 10;
            }

        /* write the number of feet and label for inches to stdout */
        write (STDOUTFD, fbuf, digits);
        write (STDOUTFD, ilabel, sizeof flabel);

            /* determine number of digits in inches */
            i = 1;
            digits = 0;
            while (inches >= i && (1UL << 32))
            {
                digits++;
                i *= 10;
            }

            /* convert number to characters in inches buffer */
            num = inches;
            ip += digits - 1;
            while (ip >= ibuf)
            {
                *ip-- =  digit [num % 10];
                num /= 10;
            }

        /* write the number of inches and newline to stdout */
        write (STDOUTFD, ibuf, digits);
        newline;

        /* zero all buffers */
        for (i = 0; i < MAXS; i++)
            buf[i] = length[i] = fbuf[i] = ibuf[i] = 0;

        /* prompt for next input ([CTRL+D] to quit) */
        write (STDOUTFD, prompt, sizeof prompt);

    }

    newline;

    return 0;
}

示例/输出

$ ./bin/read_measurement

 Enter measurement with units [feet' or inches"]: 10"

 number : 10
   unit : "

   feet :
 inches : 10

 Enter measurement with units [feet' or inches"]: 10'

 number : 10
   unit : '

   feet : 10
 inches : 10

 Enter measurement with units [feet' or inches"]: 4"

 number : 4
   unit : "

   feet : 11
 inches : 2

 Enter measurement with units [feet' or inches"]:

更新您的高级代码

如果您要继续使用高级功能,请在致电end后使用strtol已指向该号码后面的下一个字符的事实。 e.g:

while (printf ("\nEnter a measurement and unit: ") && fgets (value, 50 - 1, stdin))
{

    errno = 0;
    conv = strtol (value, &end, 10);

    if (errno == 0 && value != end)
    {
        if (*end == '\'')
            sum = sum + (conv*12);
        else if (*end == '\"')
            sum = sum + conv;
        else
            printf ("error: no unit following number.\n");
    }
    else
        printf ("error: no value read.\n");
}

答案 2 :(得分:1)

我在你的&#34;更新&#34;中看到了几个错误。代码:几乎每一行都有一个。

int main()

标头文件丢失。 (如果你给我们一个完整的程序,可以在没有修改的情况下进行编译和测试,我们会更容易帮助你。)

应该是int main(void);空的参数括号是不好的风格。

{
    char value[50];
    char *end;
    int sum = 0;

这很好。

    long conv;
    while(conv != 0)

使用未初始化的变量。我会写一个do-while循环。

    {
            printf("Enter a measurement and unit: ");

不必要地使用printf(更好fputs,因为不需要格式化)。

            fgets(value, 50, stdin);

如果您有getline,请使用它。

            conv = strtol(value, &end, 10);

在使用errno函数之前,必须手动将strto*设置为零,因为某些错误只能以这种方式显示。

            if(value[1]='\'')

您的问题就在这里。 此行有三个错误:

  • 您尚未检查strtol是否返回错误。
  • value[1]是由fgets 读取的第二个字符,而不是紧跟在该数字后面的字符。数字后面的字符为end[0]
  • 比较使用==,而不是=;这个条件是 '\''分配给value[1],然后测试'\''是否为非零;因为'\''必须非零,所以if语句的主体总是执行,这就是为什么你看到它总是乘以12.如果你在{{1}周围加上空格,那就更明显了。 }。如果您在启用了警告的情况下运行了编译器,它就会告诉您这个错误。
=

确定

            {
                    sum = sum + (conv*12);
            }

与早期 if(value[1]='\"') 声明相同的问题;应该是if

else if

此处缺少 { sum = sum + conv; } 子句,您在其中报告错误,因为该号码后面的字符既不是else也不是'

在编号和单位说明符后缺少对垃圾输入的检查。

"

其余的都很好


您可能还可以使用入门来了解如何检查 } printf("Total: %d\n", sum); return 0; } 是否返回错误。这有点挑剔,因为strtol没有指示错误的特殊返回值;如果发生错误,则会设置strtol不使用任何字符。不幸的是,当错误 not 发生时,它不一定清除errno,所以你必须自己做:

errno