允许用户更改数组函数中“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 要求字符集按顺序存储数字 0
到 9
。
你的程序中发生的事情实际上是这样的:
您正在将数组的 8 个元素初始化为以下值:
(5) (8) (2) (9) (1) (7) (4) (3)
之后,您使用 fgets
从用户输入字符串 "3\n"
。数字'3'
对应的ASCII codes为51
,换行符'\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
而不是 fgets
和 strtol
,因为 scanf
有 many disadvantages。如果你想解决fgets
和strtol
的问题,我推荐如下代码:
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>
才能使上面的代码生效。
正如我的标题所暗示的,我是一个正在玩数组的初学者。尽管我尽力而为,但我无法正确更改数组中的值?如您所见,数组中只有最后 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 要求字符集按顺序存储数字 0
到 9
。
你的程序中发生的事情实际上是这样的:
您正在将数组的 8 个元素初始化为以下值:
(5) (8) (2) (9) (1) (7) (4) (3)
之后,您使用 fgets
从用户输入字符串 "3\n"
。数字'3'
对应的ASCII codes为51
,换行符'\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
而不是 fgets
和 strtol
,因为 scanf
有 many disadvantages。如果你想解决fgets
和strtol
的问题,我推荐如下代码:
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>
才能使上面的代码生效。