首页 > 解决方案 > C:将整数读入动态分配的数组,空格分隔并与其他字符一起忽略/替换

问题描述

基本上我的问题是我正在尝试将 Python3 可以轻松完成的内容手动转换为 C 程序。我的第一个障碍实际上是输入理解。这是示例输入:

5
12
34 10
22 20 55
123 30 x 99

所以我们可以看到,这个输入中有数字、空格和字符。我很容易在 Python 中处理它,如下所示:

n = int(input()) #first line is always a single integer
matrix = [[' ' for i in range(n)] for j in range(n)] #declaring matrix of just space chars

for i in range(1,n):
    line = input().split(' ') #gets rid of all spaces
    for j in range(len(line)):
        try:
            matrix[i][j] = int(line[j])
            matrix[j][i] = int(line[j]) #mirrors same value on opposite part of the matrix
        except:
            matrix[i][j] = 'x'
            matrix[j][i] = 'x'

这导致以下矩阵:

[[' ', 12, 34, 22, 123]
[12, ' ', 10, 20, 30]
[34, 10, ' ', 55, 'x']
[22, 20, 55, ' ', 99]
[123, 30, 'x', 99, ' ']]

所以基本上,我想弄清楚如何在 C 中做到这一点。我看过关于如何动态读取输入、如何接收空格分隔的整数以及如何 malloc 整数空间的帖子,但我不知道如何将所有那些东西在一起。我真的很感激一些帮助。理想情况下,我想将所有这些整数存储到一个二维整数数组中,如上所示。

编辑:据我所知(从其他人的有用答案中截取的代码):

#include <stdlib.h>
#include <string.h>
#include <stdio.h>


int main()
{
    int n; //number of cities
    scanf("%d", &n);
    printf("%d\n", n);
    int *matrix = (int*)malloc(n*n*sizeof(int));
    
    int i=0, j=0; 
    int *line = matrix; 
    char temp; 
    for (int k=0;k<n;k++)
    {
        do { 
                scanf("%d%c", &line[i], &temp); 
                i++; 
        } while(temp != '\n'); 
   
        for(j=0; j<i; j++) { 
                printf("%d ", matrix[j]); 
        } 
        printf("\n");
    }
    free(matrix);
    free(n);
    return 0;
}

此代码的输出:

5
5
12
12
34 10
12 34 10
22 20 55
12 34 10 22 20 55
123 30 x 99

^从上面,第一个'5'是我的输入,第二个'5'是输出,第一个'12'是我的输入,第二个是输出,依此类推。最后一行代码中断。我知道每次它都会转储存储在“缓冲区”中的所有内容,即 int * 矩阵。我不知道如何处理像“x”这样的其他字符。理想情况下,我想用 -1 或其他东西替换矩阵中的“x”。

标签: pythonctranslate

解决方案


我认为将scanf 与getchar 混合使用确实是一个错误,但我相信这里避免scanf 的正确方法是n作为参数传递(例如,从argv[1] 而不是从输入流中读取)。此外,您的 python 并不是一个真正的矩阵,而是一个列表列表,在 C 实现中使用列表列表可能会更干净。但这是使用大型数组的一种方法。

#include <ctype.h>                                                                 
#include <stdio.h>                                                                 
#include <stdlib.h>                                                                
#include <stdarg.h>                                                                
                                                                                   
struct entry {                                                                     
        enum { unknown, number, character } type;                                  
        union {                                                                    
                int v;                                                             
                char x;                                                            
        } value;                                                                   
};                                                                                 
                                                                                   
static int                                                                         
die(const char *fmt, ...)                                                          
{                                                                                  
        va_list ap;                                                                
        va_start(ap, fmt);                                                         
        vfprintf(stderr, fmt, ap);                                                 
        va_end(ap); 
        fputc('\n', stderr);                                                               
        exit(EXIT_FAILURE);                                                        
}                                                                                  
                                                                                   
int                                                                                
main(void) {                                                                       
        int n, c = '\n', p = EOF, row = 0;                                         
        if( scanf("%d", &n) != 1 || n < 1 ) {                                      
                die("Invalid input in row %d (%c)", row, c);                       
        }                                                                          
        struct entry *matrix = calloc(n * n, sizeof *matrix);                      
        struct entry *t = matrix - 1, *e = matrix + n * n;                         
        while( (c = getchar()) != EOF) {                                           
                if( isdigit(c) ) {                                                 
                        if( t->type == character ) {                               
                                die("Invalid input in row %d (%c)", row, c);       
                        }                                                          
                        t->type = number;                                          
                        t->value.v = t->value.v * 10 + c - '0';                    
                } else if( isspace(c) && c != p ) {                                
                        t += 1;                              
                        if( t >= e ) {
                                die("Invalid input in row %d (%c)", row, c);
                        }
                        if( c == '\n' ) {
                                t->type = character;
                                t->value.x = ' ';
                                t = matrix + n * ++row;
                        }
                } else {
                        if( t->type != unknown ) {
                                die("Invalid input in row %d (%c)", row, c);
                        }
                        t->type = character;
                        t->value.x = c;
                }
                p = c;
        }

        /* Display the matrix */
        for( int i = 0; i < n; i++ ) {
                for( int j = 0; j < n; j++ ) {
                        t = matrix + (( j > i ) ? (n * j + i) : (n * i + j));
                        switch( t->type ) {
                        case number:
                                printf("%8d", t->value.v);
                                break;
                        case unknown:
                                printf("%8s", "??");
                                break;
                        case character:
                                printf("     '%c'", t->value.x);
                        }
                }
                putchar('\n');
        }
}

该解决方案对输入中的空白问题的鲁棒性不如 scanf 解决方案,并且不处理空格或混合空格和制表符的运行。修复这个问题留给读者作为练习。


推荐阅读