[英]Parse char from int input in C
我正在尝试通过获取用户的输入来显示矩阵。 在这里,输入是一个下三角矩阵,用户可以输入必须替换为INT_MAX
的“x”字符。 以下程序无法正常工作,因为 output 与预期不匹配。
#include <limits.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int read_int() {
char input[30] = {0};
int number;
for (int i = 0; i < sizeof(input) - 1; i++){
char c = (char)getc(stdin);
if (c == 'x' || c == 'X')
return INT_MAX;
if (c < '0' || '9' < c){
if (i == 0) continue;
input[i] = 0;
return atoi(input);
}
input[i] = c;
}
input[29] = 0;
return atoi(input);
}
int main() {
int N = read_int();
int matrix[N][N];
memset(matrix, 0, N * N * sizeof(int));
for(int i = 0; i < N; ++i){
for(int j = 0; j <= i; ++j){
int distance = read_int();
matrix[i][j] = distance;
matrix[j][i] = distance;
}
}
printf("\n");
for(int i = 0; i < N; ++i){
for(int j = 0; j < N; ++j){
printf("%d\t", matrix[i][j]);
}
printf("\n");
}
printf("\n");
return 0;
}
对于输入:
3
x 2
x x 2
上面的程序打印:
3 2147483647 2147483647
2147483647 32 2147483647
2147483647 2147483647 32
这不是预期的应该是
3 2147483647 2147483647
2147483647 2 2147483647
2147483647 2147483647 2
更新:下面的答案不适用于所有情况[接受的除外]
一种这样的情况是——
5
10
50 20
30 5 30
100 20 50 40
10 x x 10 50
它只是继续接受输入
您跳过空格的逻辑被破坏了,因为当您在跳过 position 0 后最终分配一个字符时,您将始终在 position i
处写一个“想要的”字符。 这意味着 position 0 中已经存在的任何内容都将保留。
在您的情况下,这是未定义的行为,因为input[0]
最初在第一个输入上填充了 3,没有跳过任何空格,但是在随后对您的 function 的调用中,它未初始化。 然后,您将 go 写入 2 到input[1]
中,因此纯属偶然(您先前调用的数组尚未在堆栈上被覆盖,并且堆栈是相同的),您最终会得到字符串“32” input
。
您需要做的是有一些方法来计算实际需要的字符,以便将它们写入正确的 position 的数组中。 一种天真的方法是:
int pos = 0;
for(...) {
// other logic...
// Actually write a character we want
input[pos++] = c;
}
另一种更像 integer 输入工作方式的方式是:
int c;
int pos = 0;
while(pos < sizeof(input) - 1 && (c = getc(stdin)) != EOF)
{
if (c == 'x' || c == 'X')
return INT_MAX;
else if (pos == 0 && isspace(c))
continue;
else if (!isdigit(c) && !(pos == 0 && (c == '-' || c == '+')))
break;
input[pos++] = c;
}
input[pos] = '\0';
return atoi(input);
我认为问题在于循环的这一部分:
if (c < '0' || '9' < c){
if (i == 0) continue;
input[i] = 0;
return atoi(input);
}
如果您输入了3
输入x 2
作为输入,则3
被成功读取,并且x
按预期返回为INT_MAX
,但在下一次调用read_int
时,输入序列中的下一个字符是空格(即c == ' '
),因此它在这里分支。 由于此时i == 0
,循环继续,这意味着i
递增到 1,但这也意味着input[0]
永远不会改变。 很可能, input[0]
包含与上一次调用read_int
(3) 相同的值,但无论如何,它是未定义的行为。
作为一种快速的替代方法,您可以简单地将此条件更改为:
if (c != ' ' && (c < '0' || '9' < c)){
这意味着input[0]
将被设置为一个空格字符,而atoi
将忽略该字符。
另一种解决方案可能是一次读取整行并标记该行。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.