Итерация по массиву символьных строк, который также содержит неиспользуемые элементы - PullRequest
0 голосов
/ 13 января 2020

Проблема: я хочу напечатать только три элемента, определенных в массиве names без изменения моего определенного размера массива. Эта программа в настоящее время печатает три элемента, но также печатает семнадцать новых строк, поскольку она перебирает все 20 элементов.

Вопрос: Как и где я могу создать условие, которое выходит из l oop, когда он проверяет элемент, который не имеет значения хотя бы с одним символом? Другими словами, как мне не распечатать лишние семнадцать строк?

#include <stdio.h>
#define MAX_I 20
#define MAX_J 20

int main() {
    char names[MAX_I][MAX_J] = {"Foo", "Bar", "Baz"};

    // First example
    printf("Example 1:\n");
    for (int i = 0; i < MAX_I; i++) {
        for (int j = 0; j < MAX_J; j++) {
            printf("%c", names[i][j]);
        }
        printf("\n");
    }

    // Second example
    printf("\nExample 2:\n");
    for (char* iter : names) {
        printf("%s\n", iter);
    }
}

Ответы [ 2 ]

0 голосов
/ 14 января 2020

Каждый элемент (одномерный массив типа char[MAX_I]) двумерного массива

char names[MAX_I][MAX_J] = {"Foo", "Bar", "Baz"};

, который не был явно инициализирован, неявно инициализируется как

{ '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0' }

где число нф равно MAX_I. Таким образом, на самом деле, неявно инициализированные элементы содержат пустые c -строки.

Итак, oop, который выводит явно инициализированные элементы массива, может выглядеть, например, следующим образом

for ( size_t i = 0; i < MAX_I && *names[i]; i++ )
{
    std::cout << names[i] << '\n';
}   

или

for ( size_t i = 0; i < MAX_I && names[i][0] != '\0'; i++ )
{
    std::cout << names[i] << '\n';
}   

Или, если это программа C, то

for ( size_t i = 0; i < MAX_I && *names[i]; i++ )
{
    puts( names[i] );
}   

или

for ( size_t i = 0; i < MAX_I && names[i][0] != '\0'; i++ )
{
    puts( names[i] )
}   

Если среди строк могут присутствовать пустые строки непустые строки, тогда l oop может выглядеть как

for ( size_t i = 0; i < MAX_I; i++ )
{
    if ( *names[i] ) puts( names[i] );
}   

или

for ( size_t i = 0; i < MAX_I; i++ )
{
    if ( names[i][0] != '\0' ) puts( names[i] );
}   

Или если использовать l-1035 *, основанный на диапазоне, то как показано в демонстрационной программе

#include <iostream>

#define MAX_I   20
#define MAX_J   20

int main() 
{

    char names[MAX_I][MAX_J] = {"Foo", "Bar", "Baz"};

    for ( const char *s : names )
    {
        if ( *s ) std::cout << s << '\n';
    }

    return 0;
}
0 голосов
/ 13 января 2020

Пустая строка C имеет свой первый (и единственный!) Элемент, установленный на '\0' (он же 0).

Объявление массива будет инициализировать нулями оставшиеся элементы, поэтому вы можете положиться на это правило.

Таким образом:

#include <stdio.h>
#define MAX_I 20
#define MAX_J 20

int main() {
    char names[MAX_I][MAX_J] = {"Foo", "Bar", "Baz"};

    // First example
    printf("Example 1:\n");
    for (int i = 0; i < MAX_I; i++) {

        // *** This block is new ***
        if (names[i][0] == '\0')
        {
           // Empty string! Skip this, and all following
           break;
        }

        for (int j = 0; j < MAX_J; j++) {

            // *** This block is new ***
            if (names[i][j] == '\0')
            {
               // End of string!
               break;
            }

            printf("%c", names[i][j]);
        }
        printf("\n");
    }

    // Second example
    printf("\nExample 2:\n");
    for (char* iter : names) {

        // *** This block is new ***
        if (iter[0] == '\0')
        {
           // Empty string! Skip this, and all following
           break;
        }

        printf("%s\n", iter);
    }
}

Обратите внимание, что я также позволил вам пропустить печать завершающих нулей, в вашем первом примере.

...