У меня есть строка, содержащая числа, например: `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 раза. Ну и надо отдельно хранить количество реально заполненных элементов массива.
А вообще, массив может оказаться не нужен, если взглянуть на задачу целиком.