Как удалить 0 из массива и присвоить значения в неровный массив в C - PullRequest
1 голос
/ 04 октября 2019

Мой код изначально заполняет многомерный массив int ([20] [20]) всеми нулями. Затем он читает числа из файла и помещает их обратно в этот массив. Он успешно помещает числа из файла. Однако есть 0, от которых я не могу избавиться.

Я проверил онлайн-решения для зубчатых массивов, но не смог.


//fills the array
for( i = 0; i < 20 ; i++){
        for( j = 0; j < 20; j++){
                newString[i][j] = 0;
        }
}




j = 0;
ctr = 0;   //line number 
int m = 1,num = 1;
int spaceCounter = 0;
bool isMultiDigit = false;
while (fgets(line, sizeof(line), fp) != NULL){
        for(i=0;i<=(strlen(line));i++){
                if(line[i]==' '){
                        spaceCounter++;
                }
                else if(line[i]=='\n'){
                        j = 0;

                }
                else{
                        if(line[i] != '\0'){
                                if(line[i+1] == ' ' || line[i+1] == '\n' || line[i+1] == '\0'){
                                        if(isMultiDigit){
                                                newString[ctr][j] = num;
                                                num = 1;
                                                isMultiDigit = false;
                                        }
                                        else{
                                                printf("line[i] = %c. \n", line[i]);
                                                newString[ctr][j] = line[i] - '0';
                                                printf("newString[%d][%d] = %d\n", i,j, newString[ctr][j]);
                                        }

                                        j++;
                                }
                                else{
                                        if(!isMultiDigit) num = (line[i]-'0') * 10 + (line[i+1] - '0') ;
                                        else num = num * 10 + (line[i+1] - '0') ;
                                        isMultiDigit = true;
                                }
                        }
                }
                spaceCounter = 0;
        }

        ctr++;

}


for( i = 0; i < 20 ; i++){
        for( j = 0; j < 20; j++){
                printf("%d ", newString[i][j]);
        }
        printf("-------\n");
}

Вот содержимое файла

3
9 3 34 4 12 5 2
6 3 2 7 1
256 3 5 7 8 9 1

Вот вывод после заполнения нулей и чтения из файла

3 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -------
9 3 34 4 12 5 2 0 0 0 0 0 0 0 0 0 0 0 0 0 -------
6 3 2 7 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -------
256 3 5 7 8 9 1 0 0 0 0 0 0 0 0 0 0 0 0 0 -------
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -------
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -------
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -------
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -------
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -------
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -------
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -------
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -------
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -------
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -------
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -------
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -------
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -------
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -------
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -------
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -------

Так что в этом случае новыймассив, после избавления от 0, будет

newArray[0] = {3} 
newArray[1] = {9, 3, 34, 4, 12, 5, 2} 
newArray[2] = {6, 3, 2, 7, 1} 
newArray[3] = {256, 3, 5, 7, 8, 9, 1} 

Пожалуйста, предоставьте фрагмент кода, чтобы исправить мою проблему. Спасибо тебе

1 Ответ

1 голос
/ 04 октября 2019

После исправления вашего кода я получил что-то вроде ниже. Я надеюсь, что я получил что-то, что почти правильно. Тем не менее, есть несколько моментов с вашим кодом. Чтобы присвоить всему индексу массива значение ноль, вам не нужно строить этот цикл for. Вы можете просто сделать:

int newString[20][20] = { 0 };

Для вашего случая вы создали двухуровневый массив int размером 20 на 20. Массивы Си не являются гибкими по длине. Таким образом, все эти индексы массивов останутся либо, если их значения равны нулю, либо нет. Таким образом, вы не сможете удалить эти нули, если используете этот тип массива. В вашем случае, если вы хотите сохранить этот стиль, вам придется проверять значения во время печати. Вместо этого я изменил блок печати. ​​

Другие опции, которые вы можете посмотреть в будущем, - это массив указателей на массивы, которые были найдены с помощью malloc, или hashmap и аналогичная структура данных.

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

int main(void) {
    int newString[20][20] = { 0 };
    int j = 0;
    int m = 1,num = 1;
    int ctr = 0;   //line number
    int spaceCounter = 0;
    char line[999];
    bool isMultiDigit = false;
    FILE *fp;

    if ( (fp = fopen( "test.txt", "r" )) == NULL ){
        printf( "Could not open file" ) ;
        return 1;
    }

    while (fgets(line, sizeof(line), fp) != NULL){
        for( int i=0; i<=(strlen(line));i++ ){
            if(line[i]==' '){
                spaceCounter++;
            } else if(line[i]=='\n'){
                j = 0;
            } else{
                if(line[i] != '\0'){
                    if(line[i+1] == ' ' || line[i+1] == '\n' || line[i+1] == '\0'){
                        if(isMultiDigit){
                            newString[ctr][j] = num;
                            num = 1;
                            isMultiDigit = false;
                        } else{
                            printf("line[i] = %c. \n", line[i]);
                            newString[ctr][j] = line[i] - '0';
                             printf("newString[%d][%d] = %d\n", i,j, newString[ctr][j]);
                        }

                        j++;
                    } else {
                        if(!isMultiDigit) num = (line[i]-'0') * 10 + (line[i+1] - '0');
                        else num = num * 10 + (line[i+1] - '0') ;
                        isMultiDigit = true;
                    }
                }
            }
            spaceCounter = 0;
        }
        ctr++;
    }

    for( int i = 0; i < 20 ; i++){
        if ( newString[i][0] == 0 ) continue;
        for( int j = 0; j < 20; j++){
            if ( newString[i][j] != 0 ) printf("%d ", newString[i][j]);
        }
        printf("-------\n");
    }
}

У меня есть немного свободного времени под рукой. Таким образом, я включил этот второй код, из которого, использовал динамический массив int. Код почти точно соответствует вашему коду, просто отличается по структуре типов данных. Кроме того, когда вы конвертируете символ, который наверняка известен как ASCII-код цифры, в значение типа int, вы можете использовать "char ^ 48" вместо "char - '0'".

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

/*
 * An example of a data structure
 * that can hold dynamic length
 * int arrays. 
 */
struct arrayInt {
    int *value;
    int length;
    int size;
};

/*
 * Locating and return an array int structure
 * with its size and its value array to the de
 * defined size.
 */
struct arrayInt newArrayInt( const int size ){
    struct arrayInt output;
    output.value = (int*) malloc(size * sizeof(int));
    output.length = 0;
    output.size = size;
    return output;
}

int main(void) {
    struct arrayInt newString[20];
    int j = 0;
    int m = 1,num = 1;
    int ctr = 0;   //line number
    int spaceCounter = 0;
    char line[999];
    bool isMultiDigit = false;
    FILE *fp;

    if ( (fp = fopen( "test.txt", "r" )) == NULL ){
        printf( "Could not open file" ) ;
        return 1;
    }

    // Locating dynamic length int arrays
    for ( int i = 0; i < 20; i++ ){
        newString[i] = newArrayInt(20);
    }

    while (fgets(line, sizeof(line), fp) != NULL){
        for( int i=0; i<=(strlen(line));i++ ){
            if(line[i]==' '){
                spaceCounter++;
            } else if(line[i]=='\n'){
                j = 0;
            } else{
                if(line[i] != '\0'){
                    if(line[i+1] == ' ' || line[i+1] == '\n' || line[i+1] == '\0'){
                        if(isMultiDigit){
                            newString[ctr].value[j] = num;
                            // Keep track of length
                            newString[ctr].length++;
                            num = 1;
                            isMultiDigit = false;
                        } else{
                            printf("line[i] = %c. \n", line[i]);
                            newString[ctr].value[j] = line[i] - '0';
                            // Keep track of length
                            newString[ctr].length++;
                             printf("newString[%d].value[%d] = %d\n", i,j, newString[ctr].value[j]);
                        }

                        j++;
                    } else {
                        if(!isMultiDigit) num = (line[i]-'0') * 10 + (line[i+1] - '0');
                        else num = num * 10 + (line[i+1] - '0') ;
                        isMultiDigit = true;
                    }
                }
            }
            spaceCounter = 0;
        }
        ctr++;
    }

    for( int i = 0; i < 20 ; i++){
        if ( newString[i].length == 0 ) continue;
        for( int j = 0; j < newString[i].length; j++){
            printf("%d ", newString[i].value[j]);
        }
        printf("-------\n");
    }

    // free memory
    // Probably unnecessary.
    for ( int i = 0; i < 20; i++ ){
        free(newString[i].value);
        newString[i].length = 0;
        newString[i].size = 0;
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...