#include <stdio.h> #include <stdlib.h> #include <windows.h> #include <malloc.h> int main() { SetConsoleCP(1251); SetConsoleOutputCP(1251); int num; //Ρ€Π°Π·ΠΌΠ΅Ρ€ массива int i = 0; int* index;//Π£ΠΊΠ°Π·Π°Ρ‚Π΅Π»ΠΈ Π½Π° массивы с Π΄Π°Π½Π½Ρ‹ΠΌΠΈ char* user; char* name; printf("К-Π²ΠΎ ?\n"); scanf("%d", &num); printf("Π’Π²Π΅Π΄ΠΈΡ‚Π΅: ВСкст,число,тСкст\n"); //динамичСскоС Π²Ρ‹Π΄Π΅Π»Π΅Π½ΠΈΠ΅ памяти index = (int*) malloc(num * sizeof(int)); user = (char*) malloc(num * sizeof(char)); name = (char*) malloc(num * sizeof(char)); for (i = 0; i < num; i++) { scanf("%s,%d,%s", &name[i], &index[i], &user[i]); } printf("%s", user[0]); free(index); free(user); free(name); return 0; } 

Displays entered results printf("%s", user[0]); crashes the program.

    2 answers 2

    There are two major annoyances in your code.

    1 - incorrect memory allocation. The string in C is a pointer to an array. Those. an array of strings is an array of pointers to arrays . Below I give the corrected code, I think everything will become clearer. Accordingly, a pointer to it is necessary to transfer to scanf for a string, which in our case (an array of pointers to arrays of characters ) is simply a pointer to an array of characters, i.e. just name[i] or just user[i] .

    2 - %s reads everything up to a space, so what do you have when you type, say,

     aa,1,bb 

    as the first line of the name this will all be read. In general, it is considered to be a good form to check what the input function returns ... The easiest way is to request separation by spaces; if this does not suit you - see in the documentation how you can modify the %s format specifier to do what you want. I used spaces for simplicity.

     int main() { SetConsoleCP(1251); SetConsoleOutputCP(1251); int num; //Ρ€Π°Π·ΠΌΠ΅Ρ€ массива int i = 0; int* index;//Π£ΠΊΠ°Π·Π°Ρ‚Π΅Π»ΠΈ Π½Π° массивы с Π΄Π°Π½Π½Ρ‹ΠΌΠΈ char** user; char** name; const int len = 40; // length of string printf("К-Π²ΠΎ ?"); scanf("%d", &num); printf("Π’Π²Π΅Π΄ΠΈΡ‚Π΅: ВСкст число тСкст\n"); //динамичСскоС Π²Ρ‹Π΄Π΅Π»Π΅Π½ΠΈΠ΅ памяти index = (int*) malloc(num * sizeof(int)); user = (char**) malloc(num * sizeof(char*)); name = (char**) malloc(num * sizeof(char*)); for (i = 0; i < num; ++i) { user[i] = (char*) malloc(len); name[i] = (char*) malloc(len); } for (i = 0; i < num; i++) { if (scanf("%s %d %s", name[i], &index[i], user[i]) != 3) printf("Wrong input\n"); } printf("%s", user[0]); for (i = 0; i < num; ++i) { free(user[i]); free(name[i]); } free(index); free(user); free(name); return 0; } 

      scanf("%s,%d,%s",&name[i], &index[i], &user[i]);

      I don’t know what the source data should be, but %s enters the string. In the argument &user[i] and &name[i] - the address of the element line with an offset i . Subsequent characters will be written to user[i+1] , etc. In the second iteration, all characters except the first will be rewritten, etc. I doubt that you need it.

      printf("%s", user[0]);

      Here the format for the string is set, the address is expected, and the number is transferred - the code of the first character of this string. The function attempts to contact this non-existent address and crashes.

      If you need to enter several lines, you need not a single pointer, but an array of pointers, a dynamic char **user or an automatic (stack) char *user[num] .