У меня есть строка, содержащая числа, например: `1 2 3 4 5 6 7`, и я хотел бы преобразовать её в массив целых чисел. Я попробовал использовать следующий код: ```c while (scanf("%d ", &n) == 1) { list[size++] = n; } ``` Однако, при вводе программа запрашивает ввод еще одного символа, что создает неудобства. Как можно улучшить этот процесс?
Чтобы создать одномерный массив в языке C, вы можете использовать стандартные функции для обработки строк (например, `strtok` для разбивки строки и `atoi` для преобразования строк в целые числа). Использование `scanf` с пробелами может действительно создавать неудобства, поскольку требуется дополнительный ввод после каждого числа. Вот пример того, как можно прочитать строку, содержащую числа, и преобразовать её в массив целых чисел: ```c #include <stdio.h> #include <stdlib.h> #include <string.h> #define MAX_SIZE 100 // Максимальный размер массива int main() { char input[256]; // Массив для хранения входной строки int list[MAX_SIZE]; // Одномерный массив для хранения целых чисел int size = 0; // Текущий размер массива int n; printf("Введите числа через пробел: "); fgets(input, sizeof(input), stdin); // Читаем строку с числами // Разбиваем строку на токены и преобразуем их в числа char *token = strtok(input, " "); while (token != NULL && size < MAX_SIZE) { n = atoi(token); // Преобразуем токен в целое число list[size++] = n; // Сохраняем число в массив token = strtok(NULL, " "); // Переходим к следующему токену } // Вывод результата printf("Вы ввели числа: "); for (int i = 0; i < size; i++) { printf("%d ", list[i]); } printf("\n"); return 0; } ``` ### Объяснение кода: 1. **`fgets`**: Используется для чтения строки из ввода. Она считывает всю строку до символа новой строки или указанного максимального размера. 2. **`strtok`**: Эта функция разбивает строку на токены (в данном случае, по пробелам). Первый вызов получает первый токен, последующие вызовы берут следующий токен до тех пор, пока он не станет `NULL`. 3. **`atoi`**: Преобразует строку (токен) в целое число. 4. **Цикл `while`**: Продолжает обрабатывать токены, пока не исчерпаются все токены или не будет достигнут максимальный размер массива. 5. **Вывод**: После завершения ввода программа выводит все числа, которые были введены. Этот подход позволяет избежать необходимости множественных вводов и делает программу более удобной для пользователя.
Либо заранее просить пользователя ввести размер и использовать for:
int size; scanf("%d", &size); int *list = malloc(sizeof(int) * size); for(int i = 0; i < size; i++) scanf("%d", &list[i]);
Либо как сделали вы.
Такой код, кстати,list[size++] = n;
в какой-то момент приведёт к segfaul, потому что list, очевидно, фиксированного размера, а работа предполагается с массивом переменной длины. Почитайте про malloc/realloc
Если количество цифр фиксировано, то просто перечислите в формате scanf сразу их все.
Если количество цифр может меняться, то ...
Вводить как строку и потом парсить ее с помощью strtol, кода будет, конечно, больше, чем сейчас.
Строку вводить в какой-то достаточно большой буфер длинной в 1 или 4 кб.
При превышении буфера можно выдавать ошибку.
Или ввод оформить в цикл, на случай, если буфер заполнится, а Enter пользователь еще не нажал. Выход из цикла по нахождению символа '/n' в буфере. В таком случае буфер можно делать меньше. Но тут возникает дополнительная проблема с неоконченным вводом, т.е. пользователь вводит число 123456 и допустим 123 прилетело в конец прошлого буфера, а 456 в начало следующего. Это надо будет решать в коде.
Есть проблема с фиксированным размером массива.
Если нужен произвольный размер входных данных, то можно, предварительно выделять массив какого-нибудь начального размера, если в ходе парсинга размер массива превысится, то сделать realloc увеличив размер массива в 2 раза. Ну и надо отдельно хранить количество реально заполненных элементов массива.
А вообще, массив может оказаться не нужен, если взглянуть на задачу целиком.