0

I want to know if there is a more effective way (less lines, less memory) to print the information contained in the string. I was thinking in a cycle with the funtion argument. For example if you need to print the info(name, group and birthdate) of 100 students, I guess there is a better way that write printstudent( studentn) a hundred times. The thing is that I dont know how to create a cycle so calls from student1 to student100. I cannot call it student[i] or can I?.

I am open to any kind of suggestions or ideas Thanks!

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

using namespace std;

void printstudents(struct st student);

struct st {
  char familia[1000];
  char imia[1000];
  char otchestvo[1000];
  int gruppa;
  int grozhdenia;
};

int main() {

  struct st student1;
  struct st student2;
  struct st student3;

  //Информация студентов:

  strcpy(student1.familia, "Putin");
  strcpy(student1.imia, "Vladimir");
  strcpy(student1.otchestvo, "Vladimirovich");
  student1.gruppa = 40040;
  student1.grozhdenia = 1952;

  strcpy(student2.familia, "Gordon");
  strcpy(student2.imia, "Dymitro");
  strcpy(student2.otchestvo, "Aleksandrovich");
  student2.gruppa = 50050;
  student2.grozhdenia = 1953;

  strcpy(student3.familia, "Emelianenko");
  strcpy(student3.imia, "Fedor");
  strcpy(student3.otchestvo, "Olegovich");
  student3.gruppa = 60060;
  student3.grozhdenia = 1950;

  printstudents(student1);
  printstudents(student2);
  printstudents(student3);

  return 0;
}

void printstudents(struct st student) {
  printf("Student: %s %s %s, %d, %d \n", student.imia, student.otchestvo,
         student.familia, student.gruppa, student.grozhdenia);
}
AKX
  • 152,115
  • 15
  • 115
  • 172
  • 4
    Normally you'd use an array for this. – Retired Ninja May 12 '21 at 11:59
  • 4
    You should make `printstudents` accept a pointer to the object – otherwise C will copy the structure as you call the function. – AKX May 12 '21 at 12:00
  • Yes you can declare `struct st student[101];` (not `student[100]` because the index starts from zero) to use `student[1]` to `student[100]`. – MikeCAT May 12 '21 at 12:00
  • 3
    @MikeCAT If OP has 100 students, they should just use `student[0]` through `student[99]` – no need to allocate memory for an extra student just to be able to use nonstandard 1-based indexing. – AKX May 12 '21 at 12:01
  • 2
    You say "C" in your title and tag, but your code is C++ (due to extra `#include ` and `using namespace std;`) Which do you really want to use? – MikeCAT May 12 '21 at 12:02
  • Initialize your array as in this answer https://stackoverflow.com/a/54179893/1216776 to save repeated code and copying. – stark May 12 '21 at 12:10
  • de Egea, Curious why the space before the `'\n'` in `"Student: %s %s %s, %d, %d \n"`? – chux - Reinstate Monica May 12 '21 at 23:57

3 Answers3

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

struct st;
void printstudents(const struct st *student);

struct st {
        char familia[1000];
        char imia[1000];
        char otchestvo[1000];
        int gruppa;
        int grozhdenia;
};

int
main(void)
{
        struct st student[3] = {
                { "Putin", "Vladimir", "Vladimirovich", 40040, 1952 },
                { "Gordon", "Dymitro", "Aleksandrovich", 50050, 1953 },
                { "Emelianenko", "Fedor", "Olegovich", 60060, 1950}
        };
        for( int i = 0; i < 3; i ++ ){
                printstudents(student + i);
        }

        return 0;
}

void
printstudents(const struct st * student)
{
        printf("Student: %s %s %s, %d, %d\n",
                student->imia,
                student->otchestvo,
                student->familia,
                student->gruppa,
                student->grozhdenia
        );
}
William Pursell
  • 204,365
  • 48
  • 270
  • 300
1

If we are talking actual performance in terms of execution speed and memory use, then here are the most obvious bottlenecks:

  • printf with its format string parsing is slow. It is likely quite a bit faster to use repeated puts calls than a single printf.

  • Obviously you shouldn't be passing your huge structs by value to the function. struct st student leads to a several kb large struct getting copied to the stack, in case your compiler fails to inline the function call. As a rule of thumb, never pass structs by value. Use pointers.

  • You make hard copies of constant string literals. You could have just used const char* familia and then do student2.familia = "Gordon"; which is much faster than strcpy. The down-side is that you only get read-only memory if you do like this.

Lundin
  • 195,001
  • 40
  • 254
  • 396
0

Here's a reworking of your code to use a statically stack-allocated array of 3 student structures (and a helper function to initialize students).

You will need to read up on how pointers work to make sense of it, but that's C for you.

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

struct st {
  char familia[1000];
  char imia[1000];
  char otchestvo[1000];
  int gruppa;
  int grozhdenia;
};

static void assign_student(struct st *student, const char *familia, const char *imia, const char *otchestvo, int gruppa, int grozhdenia) {
  // TODO: use strncpy
  strcpy(student->familia, familia);
  strcpy(student->imia, imia);
  strcpy(student->otchestvo, otchestvo);
  student->gruppa = gruppa;
  student->grozhdenia = grozhdenia;
}

static void print_student(struct st *student) {
  printf("Student: %s %s %s, %d, %d \n", student->imia, student->otchestvo,
         student->familia, student->gruppa, student->grozhdenia);
}

int main() {
  struct st students[3];
  assign_student(&students[0], "Putin", "Vladimir", "Vladimirovich", 40040, 1952);
  assign_student(&students[1], "Gordon", "Dymitro", "Aleksandrovich", 50050, 1953);
  assign_student(&students[2], "Emelianenko", "Fedor", "Olegovich", 60060, 1950);
  for (int i = 0; i < 3; i++) {
    print_student(&students[i]);
  }
  return 0;
}
AKX
  • 152,115
  • 15
  • 115
  • 172
  • With such large members like `char familia[1000];` it is questionable to fill the entire array with `TODO: use strncpy`. Other approaches could be used to detect/prevent overfilling, perhaps employing `strncat(), snprintf(), ...` – chux - Reinstate Monica May 13 '21 at 00:01