Не выводит имя двоечника

176
26 ноября 2016, 19:07
#include "stdafx.h"
#include <iostream>
#include <conio.h>
using namespace std;
#define N 4
struct mystruct {
    int pp_num;
    char *fio;
    char *mark;
    int groupe_num;
};
int main() {
    mystruct a[N];
    a[0].pp_num = 1;
    a[0].fio = "Yarmolenko A.A";
    a[0].mark = "4,5,5,3,4";
    a[0].groupe_num = 12;
    a[1].pp_num = 2;
    a[1].fio = "Pyatov A.V";
    a[1].mark = "3,4,5,4,3";
    a[1].groupe_num = 23;
    a[2].pp_num = 3;
    a[2].fio = "Shevchenko A.M";
    a[2].mark = "4,3,4,2,4";
    a[2].groupe_num = 34;
    a[3].pp_num = 4;
    a[3].fio = "Garmash D.H";
    a[3].mark = "3,5,3,4,4";
    a[3].groupe_num = 43;

    for (int i = 0; i < N; i++)
    {
        char c[2] = "2";
        char *b;
        b = strpbrk(a[3].mark,c);
        if (b!=NULL)
        {
            cout << a[i].fio << endl;
            cout << endl;
        }
    }
    _getch();
    return 0;
}

должно вывести фамилию Shevcenko но не работает не могу разобраться

Answer 1

1) Вы перебираете в цикле все элементы массива, но ищете "2" только в четвёртом элементе: strpbrk(a[3].mark,c) :-)

2) Почему strpbrk()?

3) Зачем c[] создаётся и инициализируется на каждой итерации, и вообще - не константа?

const char c[] = "2";
/* ... */
for (size_t i = 0; i < sizeof(a)/sizeof(a[0]); i++)
{
    /* 
      а если ищем только "2", то можно ещё проще:
         const char c = '2';
          ...   
         !strchr(a[i].mark, c)
    */
    if ( !strstr(a[i].mark, c) )
    {
        cout << a[i].fio << "\n\n";
    }
}
Answer 2

Для начала вам следует включить заголовок <cstring>, так как вы используете функции, объявленные в этом заголовке.

#include <cstring>

Строковые литералы в C++ имеют тип константных символьных массивов, то есть const char[N], где N - это количество символов, включая завершающий ноль, в строковом литерале. А потому указатели на строковые литералы также должны иметь квалификатор const, то есть правильно было бы определить вашу структуру как

struct mystruct {
    int pp_num;
    const char *fio;
    const char *mark;
    int groupe_num;
};

В цикле у вас проверяется всегда один и тот же элемент массива с индексом 3

b = strpbrk(a[3].mark,c);

Поэтому в этом случае нет большого смысла использовать цикл. Более того этот элемент не имеет '2' в поле mark

a[3].pp_num = 4;
a[3].fio = "Garmash D.H";
a[3].mark = "3,5,3,4,4";
a[3].groupe_num = 43;

Поэтому правильно было бы записать

char c[] = "2";
for ( int i = 0; i < N; i++ )
{
    if ( strpbrk( a[i].mark, c ) != nullptr )
    {
        cout << a[i].fio << endl;
        cout << endl;
    }
}

Если ищется только одна оценка в поле mark, то альтернативой для функции strpbrk может быть также функция strstr или strchr (так как оценка может быть представлена одним символом). Преимущество функции strpbrk состоит в том, что вы можете искать любую из заданных оценок. Например

char c[] = "23";
^^^^^^^^^^^^^^^
for ( int i = 0; i < N; i++ )
{
    if ( strpbrk( a[i].mark, c ) != nullptr )
    {
        cout << a[i].fio << endl;
        cout << endl;
    }
}
Answer 3

В дополнение к остальным мои 5 копеек :)

Раз уж у вас C++, не надо использовать

#define N 4

Пишите вместо этого куда более безопасное со всех точек зрения

constexpr int N = 4;

или, если компилятор старый и не понимает constexpr,

const int N = 4;

Еще - да, в вашем конкретном случае такой фокус

a[0].fio = "Yarmolenko A.A";

работает, но концептуально так поступать не стоит. Потому что при переделке программы у вас может присваиваться строка, например, вводимая с клавиатуры в какой-то буфер. При таком присвоении вы сохраните только указатель на буфер, в котором после очередного ввода будет уже совсем другая строка. Строку лучше копировать в свой внутренний буфер.

READ ALSO
Сколько разделов может быть в ОС

Сколько разделов может быть в ОС

Использовал функцию GetLogicalDevices и возник вопрос, сколько может быть логических разделов в Windows? 26 - как и количество букв в английском языке...

196
Множественное наследование и VC++

Множественное наследование и VC++

В ходе дискуссии пришли к такой программе:

187
Ошибка с памятью в перегрузке оператора

Ошибка с памятью в перегрузке оператора

Есть вот такая перегрузка оператора ++ (постфиксная)

204
Как нарисовать в терминале линию?

Как нарисовать в терминале линию?

Мне нужно нарисовать 10 линийИз одной точки по одной линии в 10 других точек

271