允许用户更改数组函数中“5”的值

Allows the user to change the value of "5" inside array function

正如我的标题所暗示的,我是一个正在玩数组的初学者。尽管我尽力而为,但我无法正确更改数组中的值?如您所见,数组中只有最后 5 位数字正确,而前 3 位数字不正确?为什么会这样?我将 post 我的代码放在下面,这样你们都能明白我的意思:

#include <stdio.h>
#include <stdlib.h>
#define MAX_ARRAY 8
void input_array(char anumber[MAX_ARRAY])
{
    printf("\n\nPlease insert new data to the 1st array with value 5: ");
    fgets(&anumber[0], MAX_ARRAY, stdin);     
    long ret = strtol(&anumber[0], NULL, 10); // Converts char to int
    printf("Converting char anumber = %d to int ret = %d\n", anumber[0], ret);
    printf("\n(Array after): ");
    for (int i = 0; i < MAX_ARRAY; ++i)
    {
        printf("(%d) ", anumber[i]);
    }
}
int main(void)
{
    char arr[MAX_ARRAY] = {5, 8, 2, 9, 1, 7, 4, 3};
    printf("(Array before): ");
    for (int i = 0; i < MAX_ARRAY; ++i)
    {
        printf("(%d) ", arr[i]);
    }
    input_array(arr); // Function that lets the user change value of "5" inside the array
    return 0;
}

如果我作为用户输入值“3”,此代码的输出是:

(Array before): (5) (8) (2) (9) (1) (7) (4) (3) 

Please insert new data to the 1st array with value 5: 3
Converting char anumber = 51 to int ret = 3

(Array after): (51) (10) (0) (9) (1) (7) (4) (3)

你好,我看到你试图将数字数组保存在 char 中,所以它可能会导致这种错误。为字符定义两个变量,为数字定义另一个变量。

开场白:

long ret = strtol(&anumber[0], NULL, 10); // Converts char to int

错了。特别是注释 // Converts char to int 是错误的。函数 strtol 不会将 单个字符 转换为 int。相反,它会将 string(即字符序列)转换为 long.

为了将单个数字字符转换为 int,您可以改为编写以下行:

int number = anumber[0] - '0';

这是可能的,因为 ISO C 要求字符集按顺序存储数字 09

你的程序中发生的事情实际上是这样的:

您正在将数组的 8 个元素初始化为以下值:

(5) (8) (2) (9) (1) (7) (4) (3) 

之后,您使用 fgets 从用户输入字符串 "3\n"。数字'3'对应的ASCII codes51,换行符'\n'对应的10。您用这两个值覆盖数组的前两个元素,并用字符串的终止空字符覆盖第三个元素。

这就是调用 fgets 后数组具有以下值的原因:

(51) (10) (0) (9) (1) (7) (4) (3)

函数 fgets 覆盖前 3 个元素,但保留其余元素不变。

正确的解决方法如下:

您似乎只想覆盖数组的第一个元素。因此,您不应将数组用作 fgets 函数调用的直接目标,因为该函数将始终写入多个字节(正确使用该函数时)。

解决该问题的一种非常简单的方法如下:

void overwrite_first_element_with_input( char arr[MAX_ARRAY] )
{
    //prompt user for input
    printf( "Please enter new data for the first element of the array: " );

    //write input to first element
    if ( scanf( "%hhd", &arr[0] ) != 1 )
    {
        printf( "input error!\n" );
        exit( EXIT_FAILURE );
    }
}

完整的程序看起来像这样(有一些小的改进):

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

#define MAX_ARRAY 8

void overwrite_first_element_with_input( char arr[MAX_ARRAY] )
{
    //prompt user for input
    printf( "Please enter new data for the first element of the array: " );

    //write input to first element
    if ( scanf( "%hhd", &arr[0] ) != 1 )
    {
        printf( "input error!\n" );
        exit( EXIT_FAILURE );
    }
}

void print_array( const char arr[MAX_ARRAY], const char *tag )
{
    printf( "%s", tag );

    for ( int i = 0; i < MAX_ARRAY; i++ )
    {
        printf( "(%d) ", arr[i] );
    }

    printf( "\n" );
}

int main( void )
{
    char arr[MAX_ARRAY] = {5, 8, 2, 9, 1, 7, 4, 3};

    print_array( arr, "(Array before): " );
    overwrite_first_element_with_input( arr );
    print_array( arr, "(Array after): " );

    return 0;
}

这是程序的一些示例输出:

(Array before): (5) (8) (2) (9) (1) (7) (4) (3) 
Please enter new data for the first element of the array: 20
(Array after): (20) (8) (2) (9) (1) (7) (4) (3) 

但是,我不想鼓励您使用 scanf 而不是 fgetsstrtol,因为 scanfmany disadvantages。如果你想解决fgetsstrtol的问题,我推荐如下代码:

void overwrite_first_element_with_input ( char arr[MAX_ARRAY] )
{
    char line[100], *p;
    long ret;

    //prompt user for input
    printf( "Please enter new data for the first element of the array: " );

    //attempt to read one line of input and verify success
    if (
        //verify that fgets was successful
        fgets( line, sizeof line, stdin ) == NULL

        ||

        //verify that input buffer was large enough to store entire line
        strchr( line, '\n' ) == NULL
    )
    {
        printf( "input error!\n" );
        exit( EXIT_FAILURE );
    }

    //attempt to convert input to number
    ret = strtol( line, &p, 10 );
    if ( p == line )
    {
        printf( "conversion failure!\n" );
        exit( EXIT_FAILURE );
    }

    //write the successfully converted number to the array
    arr[0] = ret;
}

请注意,您必须添加 #include <string.h> 才能使上面的代码生效。