Как читать две строки чисел из ввода в 2 массива языка C? Не зная количество номера? в С - PullRequest
0 голосов
/ 19 ноября 2018

Например, ввод:

12 23 32 41 45
22 11 43

строки заканчиваются на '\n',

Я хочу сохранить числа до a[] и b[];

a[] = {12, 23, 32, 41, 45}
b[] = {22, 11, 43}

Дело в том, что я НЕ ЗНАЮ, сколько номеров в каждой строке.

Если я знаю номера строк1 n и номеров строк2 m, я буду использовать «для цикла», и никаких вопросов.

Так же, как,

for(int i = 0; i < n; i++) scanf("%d", a+i);
for(int i = 0; i < m; i++) scanf("%d", b+i);

а я и м не знаю, как это сделать, ребята?

Ответы [ 3 ]

0 голосов
/ 19 ноября 2018

Давайте используем нестандартное getline, общее расширение библиотеки. @ Abbott для чтения всей строки в выделенной памяти.

Если требуется массив и его размер определяется во время выполнения, используйте массив переменной длины доступен в C99 и, необязательно, в C11.

Создайте функцию для подсчета и, возможно, сохранения чисел.Для надежного анализа используйте функции strto...().

size_t count_longs(char *line, long *dest) {
  size_t count = 0;
  char *s = line;
  for (;;) {
    char *endptr;
    long num = strtol(s, &endptr, 10);
    if (s == endptr) {
      break;  /// no conversion
    }
    s = endptr;
    if (dest) {
      dest[count] = num;
    }
    count++;
  }
  return count;
} 

Пример кода

  char *line = NULL;
  size_t len = 0;
  ssize_t nread = getline(&line, &len, stdin);  // read the whole line
  if (nread != -1) {
    // successful read

    long a[count_longs(line, NULL)];  // determine array size and use a 
    count_longs(line, a);             // 2nd pass: assign array elements. 

    nread = getline(&line, &len, stdin);
    if (nread != -1) {
      // successful read

      long b[count_longs(line, NULL)];
      count_longs(line, b);

      // Do something with a and b
    }
  }
  free(line);
  len = 0;
0 голосов
/ 19 ноября 2018

Решение, которое могло бы соответствовать тому, что запрашивал OP, было бы кодом ниже.Решение считывает неопределенное количество целочисленных значений и сохраняет их в arr.чтобы разорвать входной цикл / конец, просто введите нецелое значение.Это может быть дополнительно указано для поиска конкретного ввода и т. Д.

int c = 0;
int *arr = NULL;
int *extArr = NULL;
int i = 0;
for (i = 0; scanf("%d", &c) == 1; i++)
{
    extArr = (int*)realloc(arr, (i+1) * sizeof(int)); 
    arr = extArr;
    arr[i] = c; 

}
free(arr);

Я бы, однако, лично согласился с сочетанием предоставленного мной решения и ответа armitus (если я не могу использовать getline или аналогичный)поскольку перераспределение памяти для каждого значения int кажется мне излишним.

Редактировать Поскольку возник некоторый вопрос о коде, который я предоставил, и о том, как наилучшим образом использовать его для выполнения вопроса ОП.Codenippet должен был продемонстрировать, как можно создать свою собственную функцию в стиле scanf для неопределенного числа целочисленных входов, считывающих один полный массив за один раз (в этом случае free() должен быть опущен, пока один не будет сделан с массивом (очевидно,).

0 голосов
/ 19 ноября 2018

Если вы хотите продолжить использовать метод scanf, я бы порекомендовал спецификатор формата %[^] с отрицанием scanset.

scanf("%[^\n]", pointerToCharArray)

Это должно читать любое количество символов до , но не включая указанный символ (который, в нашем случае, является новой строкой). Если вы хотите отказаться от новой строки, прочитайте ее следующим образом:

scanf("%[^\n]\n", pointerToCharArray)

Ссылку на справочную страницу можно найти ниже. Указатель отрицательного набора сканирования включен в список:

http://www.cplusplus.com/reference/cstdio/scanf/

С этого момента очень просто использовать strtok (), чтобы разбить выходные данные scanf на числовые массивы. Если вы не знакомы со strtok, ниже приведена другая ссылка:

http://www.cplusplus.com/reference/cstring/strtok/

Надеюсь, это поможет!

...