为什么我的ASCII编号程序读取相同的读数?

时间:2016-02-07 04:49:31

标签: c

我必须编写一个代码,将我输入的ASCII数字字符转换为整数。第一个代码已被修改,并由教授竖起大拇指:

    #include <stdio.h>
    #include <stddef.h>

    char * ASCIItoInt(char inputString[], int *integerPtr);
    int main() {
       char inputBuffer[1024];
       char *ptr = NULL;
       int integer = 8888;
       while(fgets(inputBuffer, sizeof(inputBuffer), stdin)) {
          ptr = inputBuffer;
          int done = 0;
          while(!done) {
             char *newPtr = ASCIItoInt(ptr, &integer);
             if(newPtr == NULL) {
                if(*ptr != '\0')
                   ++ptr; // Skip over offending character
                else
                   done = 1;
             } else {
                printf("%d\n", integer);
                ptr = newPtr;
             }
          }
       }

       return 0;
    }

此代码将通过读取标准输入来测试下一个代码中的函数,直到它读取所有行并跳过ASCIItoInt的任何错误导致(NULL)字符。

这是ASCIItoInt:

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

     char *ASCIItoInt(char *inputString, int *integerPtr) {
          *integerPtr = 0;
            while (*inputString) {
                 printf("%d\n", *integerPtr);
                 printf("%c\n", *inputString);
            if (*inputString >= '0' && *inputString <= '9') {
                *integerPtr *= 10;
                *integerPtr += (*inputString - '0');
                 inputString++;
                }
                else 
                    inputString++;

            }
           return inputString - *integerPtr;
    }

我们被指示如此编译:

    gcc -Wall ASCIItoInt.c MainASCIItoInt.c -o ASCIItoInt

我不知道它是否有所作为。我只是包含它,因为 MainASCIItoInt (第一个代码)调用第二个代码。说了这么多,我编译并运行,但获得相同的输出不间断。这可能是返回错误,还是其他什么?什么是解决它的最佳方法?这段代码不是很好,但我正在尝试一点一点地工作。任何帮助将不胜感激。

2 个答案:

答案 0 :(得分:1)

您应该更改您的问题以匹配您在评论中提出的问题

在评论中回答你的问题:

您可以像这样使用atoi()

int main ()
{
  int i;
  char buffer[256];
  printf ("Enter a number: ");
  fgets (buffer, 256, stdin);
  i = atoi (buffer);
  printf ("The value entered is %d. Its double is %d.\n",i,i*2);
  return 0;
}

代码将输出:

Enter a number: 73
The value entered is 73. Its double is 146

另一种解决方案是:

char myarray[5] = {'-', '1', '2', '3', '\0'};
int i;
sscanf(myarray, "%d", &i);

i将等于-123

答案 1 :(得分:1)

你非常接近。有些调整只是。这是使用大多数原始逻辑的更正代码。请注意,在解析函数中添加了一个额外的布尔值以及if意义的反转。 [请原谅无偿的风格清理]:

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

char *
ASCIItoInt(char *str, int *integerPtr)
{
    int chr;
    char *cp;
    int valid;

    //printf("ASCIItoInt: ENTER str=%s",str);

    *integerPtr = 0;

    valid = 0;
    cp = str;
    for (chr = *cp;  chr != 0;  chr = *++cp) {
        //printf("ASCIItoInt: chr=%2.2X\n",chr);

        // is char a digit? bug out if not
        if (! ((chr >= '0') && (chr <= '9')))
            break;

        *integerPtr *= 10;
        *integerPtr += (chr - '0');

        //printf("ASCIItoInt: %d\n",*integerPtr);

        // say we found a valid digit
        valid = 1;
    }

    if (! valid)
        cp = NULL;

    //printf("ASCIItoInt: EXIT cp='%s'\n",cp);

    return cp;
}

int
main(int argc,char **argv)
{
    char inputBuffer[1024];
    char *ptr = NULL;
    int integer = 8888;
    FILE *xfin;

    --argc;
    ++argv;

    // need the argv for convenience if using gdb
    if (argc > 0)
        xfin = fopen(*argv,"r");
    else
        xfin = stdin;

    while (fgets(inputBuffer, sizeof(inputBuffer), xfin)) {
        ptr = inputBuffer;
        int done = 0;

        while (!done) {
            char *newPtr = ASCIItoInt(ptr,&integer);

            if (newPtr == NULL) {
                if (*ptr != '\0')
                    ++ptr;              // Skip over offending character
                else
                    done = 1;
            }
            else {
                printf("%d\n", integer);
                ptr = newPtr;
            }
        }
    }

    if (argc > 0)
        fclose(xfin);

    return 0;
}

以下是使用atoi(使用strtol代替错误检查)的方法:

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

int
main(int argc,char **argv)
{
    char inputBuffer[1024];
    char *bp;
    char *cp;
    int integer = 8888;
    FILE *xfin;

    --argc;
    ++argv;

    // need the argv for convenience if using gdb
    if (argc > 0)
        xfin = fopen(*argv,"r");
    else
        xfin = stdin;

    while (fgets(inputBuffer, sizeof(inputBuffer), xfin)) {
        bp = inputBuffer;

        while (1) {
            cp = strtok(bp," \n");
            bp = NULL;

            // nothing more
            if (cp == NULL)
                break;

            integer = strtol(cp,&cp,10);
            if (*cp != 0) {
                printf("syntax error\n");
                continue;
            }

            printf("%d\n",integer);
        }
    }

    if (argc > 0)
        fclose(xfin);

    return 0;
}

<强>更新

根据您的要求,%2.2X的含义如下。请注意,实际解释可能会因转化说明符[X]而异,因此权威引用为man 3 printf

由于正在测试的字符可能是任何[8位]值[特别是换行符],因此我们不希望使用%c输出,因为我们可能会获得半无法打印输出,因此{{1}将输出一个&#34;零填充&#34; 2位十六进制表示。 注意:请参阅下文,了解输出trace printf的更好方法

因此,空格为%2.2X20q610,换行为30

一般情况下,格式为0A

%w.pX是&#34;字段宽度&#34; [该字段应占据的最小字符数]

w是&#34;精度&#34;。对于p转化[和X],这是最小位数。对于换行,因为它的值为d [十进制10],字段宽度为0x0A,所以必须在[左侧]填充零。

对于十六进制,我们可以2%2.2X。它分别控制输出的大写/小写[

]

以下是一些格式及其输出。添加引号以便于查看格式实际使用的空间大小。我添加了一些十进制格式进行比较

%2.2x

如果我没有提供更好的方法来输出调试%X --> 'A' %2X --> ' A' %2.2X --> '0A' %02X --> '0A' %2.2x --> '0a' %d --> '1' %10d --> ' 1' %10.10d --> '0000000001' %10.9d --> ' 000000001' %10.7d --> ' 0000001' %d --> '37' %10d --> ' 37' %10.10d --> '0000000037' %10.9d --> ' 000000037' %10.7d --> ' 0000037' %d --> '289' %10d --> ' 289' %10.10d --> '0000000289' %10.9d --> ' 000000289' %10.7d --> ' 0000289' %d --> '1096' %10d --> ' 1096' %10.10d --> '0000001096' %10.9d --> ' 000001096' %10.7d --> ' 0001096' %d --> '28492' %10d --> ' 28492' %10.10d --> '0000028492' %10.9d --> ' 000028492' %10.7d --> ' 0028492' %d --> '137862923653' %10d --> '137862923653' %10.10d --> '137862923653' %10.9d --> '137862923653' %10.7d --> '137862923653' ,那将是我的疏忽:

printf