Как создать одномерный массив в языке Си?

У меня есть строка, содержащая числа, например: `1 2 3 4 5 6 7`, и я хотел бы преобразовать её в массив целых чисел. Я попробовал использовать следующий код: 

```c
while (scanf("%d ", &n) == 1) {
    list[size++] = n;
}
```

Однако, при вводе программа запрашивает ввод еще одного символа, что создает неудобства. Как можно улучшить этот процесс?
  • 30 сентября 2024 г. 11:23
Ответы на вопрос 3
Чтобы создать одномерный массив в языке 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 раза. Ну и надо отдельно хранить количество реально заполненных элементов массива.
А вообще, массив может оказаться не нужен, если взглянуть на задачу целиком.
Похожие вопросы