我的节目遇到了麻烦。它的目的是从用户读取数字输入,当他们停止输入数字(ctrl-d)时,它收集输入的数字并打印出'奇数是:blah blah' 并且'连数都是:等等等等。
我遇到了如何在EOF退出程序的问题,当我觉得我已经克服了这个问题时,又出现了另一个问题,那就是我的程序没有打印数组中的数字。它只打印'奇数是:'和'偶数是:'。
感谢任何帮助。 感谢
#include<stdio.h>
#include<stdlib.h>
#include<math.h>
int main(void) {
int n, i, array[1000];
i=0;
while (i = getchar() !=EOF) {
scanf("%d", &array[i]);
i++;
}
printf("Odd numbers were:");
i=0 ;
while(i = getchar() != EOF) {
if(array[i]%2!=0) {
printf(" %d", array[i]);
i++;
}
}
printf("\nEven numbers were:");
i=0 ;
while(i = getchar() !=EOF) {
if (array[i]%2==0) {
printf(" %d", array[i]);
i++;
}
}
printf("\n");
return 0;
}
答案 0 :(得分:0)
将输入循环更改为:
n = 0;
while ( 1 == scanf("%d", &array[n]) )
++n;
您实际想要做的是继续阅读数字,直到读取尝试失败;这个循环条件表达了这个逻辑。忘了EOF。 (在n
到达1000
时添加逻辑以避免缓冲区溢出也是一个好主意。
在输出循环中,您不想进行任何输入,因此调用getchar()
不是一个好主意。相反,请使用“正常”循环for (i = 0; i < n; ++i)
。
答案 1 :(得分:0)
执行单数字转换 int
你可能会让自己的事情变得更加艰难。虽然您可以使用while (scanf ("%d", &array[i]) == 1)
来读取空格分隔的整数并避免执行手动转换,但如果您的目的是读取单个数字,那么使用getchar()
就可以了。 (就此而言,您可以使用getchar()
读取任何多位数整数,只需提供从ASCII字符到最终数值的转换。
单位数字符的手动转换是直截了当的吗?当您将数字读取为字符时,您没有读取由数字表示的整数值,您正在读取代表每个数字的字符的 ASCII值。见ASCII Table and Description。要将单个ASCII字符数字转换为它的整数值,必须减去'0'
的ASCII值。 (注意:单引号很重要)
例如,如果您使用int c = getchar();
读取数字,则需要减去'0'
以获得单位数整数值,例如int n = c - '0';
填充数组时,必须始终防止超出数组范围的写入。如果声明int array[1000] = {0};
(其可用的基于零的数组索引为0-999
),那么您必须验证您是否永远不会编写索引999
或未定义的行为结果。要保护数组边界,只需跟踪填充的索引数量并测试它总是低于可用数组元素的数量,例如。
while (n < MAX && (c = getchar()) != EOF) /* always protect array bounds */
if ('0' <= c && c <= '9') /* only handle digits */
array[n++] = c - '0'; /* convert ASCII to int */
接下来,虽然您可以自由地测试n % 2
(使用modulo
运算符),但是没有必要(小端)。由于任何奇数都会将ones-bit
设置为1
,因此您只需进行简单的按位比较,例如(二进制7
为0111
)。
if (array[i] & 1) /* if ones-bit is 1, odd */
printf (" %d", array[i]);
当然,对于偶数,1位将为0
(例如二进制中的8
为1000
),因此相应的测试可以是:
if ((array[i] & 1) == 0) /* if ones-bit is 0, even */
printf (" %d", array[i]);
将所有部分组合在一起,您可以存储在array
中读取的所有单个数字,然后将偶数和奇数数字分开,以便打印出来简单的方式(注意:既不需要stdlib.h
或math.h
),
#include <stdio.h>
#define MAX 1000 /* define a constant rather than use 'magic' numbers in code */
int main (void)
{
int array[MAX] = {0},
c, i, n = 0;
while (n < MAX && (c = getchar()) != EOF) /* always protect array bounds */
if ('0' <= c && c <= '9') /* only handle digits */
array[n++] = c - '0'; /* convert ASCII to int */
printf ("\narray : "); /* output array contents */
for (i = 0; i < n; i++)
printf (" %d", array[i]);
printf ("\narray - odd : ");
for (i = 0; i < n; i++)
if (array[i] & 1) /* if ones-bit is 1, odd */
printf (" %d", array[i]);
printf ("\narray - even : ");
for (i = 0; i < n; i++)
if ((array[i] & 1) == 0) /* if ones-bit is 0, even */
printf (" %d", array[i]);
putchar ('\n'); /* tidy up w/newline */
return 0;
}
启用警告的示例编译
$ gcc -Wall -Wextra -pedantic-std=gnu11 -Ofast -o bin/arrayevenodd arrayevenodd.c
示例使用/输出
$ echo "01234567890123456789" | ./bin/arrayevenodd
array : 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9
array - odd : 1 3 5 7 9 1 3 5 7 9
array - even : 0 2 4 6 8 0 2 4 6 8
仔细看看,如果您有其他问题,请告诉我。
执行手动多位转换 int
如果您需要从字符转换多位整数,最简单的方法是使用为您提供转换的函数(例如scanf
函数族或使用{{1 }或fgets
并使用getline
然后strtok
解析和转换数字字符串,或使用strtol
解析等。)
但是,将sscanf
读取的单个字符手动转换为多位整数是很简单的。您只需检查一个有效字符,而不是可以开始一个整数(包括getchar()
的前缀),并通过在添加之前将总和乘以+/-
,将每个数字相加,从而为数字位置提供适当的偏移量(或实际上减去是否将总和构建为负总和以实现编码效率)每个数字直到达到下一个非数字,然后将最终总和添加到数组并推进数组索引
在构建总和时,您可以在将最终总和添加到数组之前检查整数溢出。 (您可以根据需要处理溢出条件,下面的示例只会抛出错误并退出)
手动转换可能会增加大约20行代码,例如
10
示例使用/输出
#include <stdio.h>
#include <stdint.h> /* exact length types */
#include <limits.h> /* INT_X constants */
#define MAX 1000 /* define constant rather than use 'magic' number in code */
int main (void)
{
int array[MAX] = {0},
c, i, start = 0, sign = 1, n = 0;
int64_t sum = 0;
while (n < MAX && (c = getchar()) != EOF) { /* always protect array bounds */
if (!start) { /* flag to start building int */
start = 1; /* flag - working on int */
if (c == '+') /* handle leading '+' sign */
continue;
else if (c == '-') /* handle leading '-' sign */
sign = -1;
else if ('0' <= c && c <= '9') /* handle digits */
sum = sum * 10 - (c - '0'); /* note: sum always computed */
else /* as negative value */
start = 0; /* reset - char not handled */
}
else if ('0' <= c && c <= '9') { /* handle digits */
sum = sum * 10 - (c - '0'); /* convert ASCII to int */
if (sum < INT_MIN || (sign != -1 && -sum > INT_MAX))
goto err; /* check for overflow, handle error */
}
else { /* non-digit ends conversion */
if (sum) /* if sum has value, add to array */
array[n++] = sign != -1 ? -sum : sum;
sign = 1; /* reset values for next conversion */
start = 0;
sum = 0;
}
}
if (sum) /* add last element to array on EOF */
array[n++] = sign != -1 ? -sum : sum;
printf ("\narray : "); /* output array contents */
for (i = 0; i < n; i++)
printf (" %d", array[i]);
printf ("\narray - odd : ");
for (i = 0; i < n; i++)
if (array[i] & 1) /* if ones-bit is 1, odd */
printf (" %d", array[i]);
printf ("\narray - even : ");
for (i = 0; i < n; i++)
if ((array[i] & 1) == 0) /* if ones-bit is 0, even */
printf (" %d", array[i]);
putchar ('\n'); /* tidy up w/newline */
return 0;
err:
fprintf (stderr, "error: overflow detected - array[%d]\n", n);
return 1;
}
示例&#39; + / - &#39;前缀强>
$ echo "1,2,3,5,76,435" | ./bin/arrayevenodd2
array : 1 2 3 5 76 435
array - odd : 1 3 5 435
array - even : 2 76
查看新示例,如果您有任何其他问题,请与我们联系。