繁体   English   中英

从 C 中的 int 输入解析 char

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM