无法从C程序中的字符串中提取完整数字

时间:2017-06-20 18:43:04

标签: c

用于计算用户给出的n个数字的平均值的程序。

好的,所以我有这个程序的目的是你上面已经读过的。它的输出不太对劲。我弄清楚问题是什么,但找不到解决方案,因为我不是编程的新手(实际上是新手)。这是代码:

#include <stdio.h>

int main(void) {
    char user_data[100];
    long int sum = 0;
    double average;
    unsigned int numbers_count = 0;

    for (int i = 0; i <= 99; ++i)
        user_data[i] = 0;

    unsigned int numbers[100];

    for (int i = 0; i <= 99; ++i)
        numbers[i] = 0;

    printf("Please enter the numbers:");

    fgets(user_data, sizeof(user_data), stdin);

    int i = 0;
    while (user_data[i] != 0) {
        sscanf(user_data, "%u", &numbers[i]);
        ++i;
    }

    i = 0;
    while (numbers[i] != 0) {
        sum += numbers[i];
        ++i;
    }

    i = 0;
    while (numbers[i] != 0) {
        ++numbers_count;
        ++i;
    }

    average = (float)sum / (float)numbers_count;

    printf("\n\nAverage of the entered numbers is: %f",average);

    return 0;
}

现在问题来了。

当我输入一个整数23时,它会以两个单独的字节存储到user_data中。我添加了一个循环来打印user_data[i]的值以找出错误。

    i = 0;
    while (i <= 99) {
        printf("%c\n",user_data[i]);
        ++i;
    }`

结果就是这个

user_data insight

这是第一个问题,这是第二个问题。 我添加了另一个与上面相同的循环来打印存储在数字[100]中的数字并找出错误,这是输出。这是一个样本

numbers stored in numbers[]

现在我的主要问题是

如何从user_data中提取完整数字?

3 个答案:

答案 0 :(得分:2)

我认为在{23}的user_data之后布局fgets()可能会有所帮助(假设Linux或Mac新行):

 +-----+-----+----+----+
 | '2' | '3' | \n | \0 | .....
 +-----+-----+----+----+
    0     1     2    3 

请注意,user_data[0] 包含2(数字2)!它包含'2'(字符'2'),其代码(再次,假设Linux)0x32(十六进制或十进制50)。

这就是为什么您尝试打印user_data[]的值并不富有成效的原因:您试图打印数字的表示,而不是数字本身。

要将该字符串转换为它所代表的整数,您可以执行以下操作:

 num = atoi(user_data)

函数atoi()为您完成工作。一个更灵活的函数是strtol(),它对long int执行相同的操作(并且还可以处理表示基数中不是10的数字的字符串)。

我希望这能回答您的问题:如何从user_data中提取完整数字?

还有一些其他要点应该清理和简化代码,但是如果需要帮助,可以打开另一个问题。

答案 1 :(得分:0)

试试这个:

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


int main(void)
{
   int i;

   char user_data[100];

   long int sum = 0;

   double average;

   unsigned int numbers_count = 0;

   for( i=0; i<= 99; ++i)
   user_data[i] = 0;

   unsigned int numbers[100];

   for( i=0; i<= 99; ++i)
        numbers[i] = 0;

   printf("Please enter the numbers:");

   fgets(user_data,sizeof(user_data),stdin);
    //int p=0;//use with strtol(see further code)
    i = 0;
    int j;//this will store each number in numbers array.. so this is also the count of numbers stored - 1


    for(j=0;;){

        for(i=0;i<strlen(user_data);i++)
        {
            if(user_data[i]=='\n'){
                    break;
            }
            if(user_data[i]==' '){
                    j++;
                    i++;
                    //p=i;//to be used with strtol
            }
            numbers[j]=(numbers[j]*10)+((user_data[i]-48));//alternatively use => numbers[j]=strtol(user_data+p,NULL,10);

        }

        break;
    }

    i = 0;

    while( i<=j)
    {
        sum += numbers[i];
        ++i;
    }

    average = (float)sum/(j+1);


    printf("\n\nAverage of the entered numbers is: %f",average);


    return 0;
}

示例输入

  

10 11 12

示例输出

  

11.00000000

我已经展示了两种方法来解决这个问题:

  • 一个是直接的,从每个字符中减去48并将其添加到数字数组(ASCII操作)。
  • 其他是使用strtol。现在strtol转换char指针指向的数字(在本例中为char数组),直到下一个char不是数字。所以使用指针算法指向更多的数字(就像这里我添加了p(是的,我知道p不是一个好的变量名,所以我和j!)。)。
  • 使用atoi库函数有更多方法可以解决。

答案 2 :(得分:0)

关于发布的代码:

如果其中一个数字为零,会发生什么?

如果数字的总和超过&#39; sum&#39;

的容量,会发生什么
#include <stdio.h>    // sscanf(), fgets(), printf()
#include <stdlib.h>   // strtol()
#include <string.h>   // strtok()

// eliminate the 'magic' number by giving it a meaningful name
#define MAX_INPUTS 100
int main(void) 
{
    // the array can be initialized upon declaration
    // which eliminates the 'for()' loop to initialize it
    // char user_data[100];
    // and
    // initialization not actually needed as 
    // the call to 'fgets()' will overlay the array
    // and 'fgets()' always appends a NUL byte '\0'
    char user_data[ MAX_INPUTS ];
    long int sum = 0;
    double average;

    // following variable not needed
    // unsigned int numbers_count = 0;

    // following code block not needed when
    // 'user_data[]' initialized at declaration
    // for (int i = 0; i <= 99; ++i)
    //    user_data[i] = 0;

    // not needed, see other comments
    //unsigned int numbers[100];

    // not needed, as 'numbers' is eliminated
    // for (int i = 0; i <= 99; ++i)
    //    numbers[i] = 0;

    printf("Please enter the numbers:");

    // should be checking the returned value
    // to assure it is not NULL 
    // And
    // this call to 'fgets()' is expecting 
    // all the numbers to be on a single input line
    // so that could be a problem
    fgets(user_data, sizeof(user_data), stdin);

    // the following two code blocks will not extract the numbers
    // for a number of reasons including that 'sscanf()'
    // does not advance through the 'user_data[]' array
    // int i = 0;
    // while (user_data[i] != 0) {
    //     sscanf(user_data, "%u", &numbers[i]);
    //     ++i;
    // }

    // i = 0;
    // while (numbers[i] != 0) {
    //     sum += numbers[i];
    //     ++i;
    // }

    // suggest the following, 
    // which also eliminates the need for 'numbers[]'
    // note: the literal " \n" has both a space and a newline
    //     because the user is expected to enter numbers, 
    //     separated by a space and 
    //     'fgets()' also inputs the newline
    int i = 0;
    char *token = strtok( user_data, " \n");
    while( token )
    {
        // not everyone likes 'atoi()'
        // mostly because there is no indication of any error event
        // suggest using: 'strtol()'
        //sum += atoi( token );  
        sum += strtol( token, NULL, 10 ) // could add error checking           
        i++;
        token = strtok( NULL, " \n" );
    }

    // the value assigned to 'numbers_count' 
    // is already available in 'i'
    // suggest eliminate the following code block 
    // and 
    // eliminate the 'numbers_count' variable
    // i = 0;
    // while (numbers[i] != 0) {
    //    ++numbers_count;
    //    ++i;
    // }


    // 'average' is declared as a 'double', 
    // so the casting should be to 'double'
    // and 
    // if incorporating the prior comment about 'numbers_count'
    // average = (float)sum / (float)numbers_count;
    average = (double)sum / (double)i'

    // to have the text immediately displayed on the terminal
    // place a '\n' at the end of the format string.
    // without adding the '\n' the text only displays 
    // as the program exits
    // printf("\n\nAverage of the entered numbers is: %f",average);
    printf("\n\nAverage of the entered numbers is: %f\n",average);

    return 0;
} // end function: main