首页 > 解决方案 > 从C中的int输入解析char

问题描述

我正在尝试通过获取用户的输入来显示矩阵。在这里,输入是一个下三角矩阵,用户可以输入必须替换为 'x' 的字符INT_MAX。以下程序无法正常工作,因为输出与预期不匹配。


#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

它只是继续接受输入

标签: cinput

解决方案


您跳过空格的逻辑被破坏了,因为当您在跳过位置 0 后最终分配一个字符时,您将始终在 position 处写一个“想要的”字符i。这意味着任何已经在位置 0 的东西仍然存在。

在您的情况下,它是未定义的行为,因为input[0]最初在第一个输入上填充了 3 ,其中没有跳过任何空格,但在随后调用您的函数时它未初始化。然后,您继续将 2 写入其中input[1],因此纯属偶然(您先前调用的数组尚未在堆栈上被覆盖,并且堆栈是相同的),您最终会得到字符串“32” input

您需要做的是有一些方法来计算实际需要的字符,以便将它们写入数组中的正确位置。一种天真的方法是:

int pos = 0;

for(...) {
    // other logic...

    // Actually write a character we want
    input[pos++] = c;
}

另一种更像整数输入的工作方式是:

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);

推荐阅读