C: Как преобразовать строку целых чисел в реальные и сохранить их в массиве? - PullRequest
3 голосов
/ 11 марта 2010

У меня есть строка "14 22 33 48".Мне нужно вставить каждое из значений в строке в соответствующее место в массиве:

int matrix[5];

, чтобы

matrix[0] = 14;
matrix[1] = 22;
matrix[2] = 33;
matrix[3] = 48;

Как это сделать?

Ответы [ 5 ]

8 голосов
/ 11 марта 2010

Вы можете использовать sscanf :

sscanf(val, 
       "%d %d %d %d", 
       &matrix[0], 
       &matrix[1], 
       &matrix[2], 
       &matrix[3]
);
5 голосов
/ 11 марта 2010
const char *p = input;
int i = 0, len;
while (i < sizeof(matrix)/sizeof(matrix[0]) 
   && sscanf(p, "%d%n", &matrix[i], &len) > 0) {
    p += len;
    i++;
}

Для дополнительного кредита, динамически перераспределяемая матрица должна быть настолько большой, насколько это необходимо ...

2 голосов
/ 12 марта 2010

Я бы порекомендовал strtol, что обеспечивает лучшую обработку ошибок, чем atoi или sscanf. Эта версия остановится, если встретится плохой символ или не хватит места в массиве. Конечно, если в строке недостаточно целых чисел для заполнения массива, оставшаяся часть останется неинициализированной.

#include <stdio.h>
#include <stdlib.h>

#define ARRAY_SIZE 5

int main(int argc, char *argv[])
{
   /* string to convert */
   const char * str = "14 22 33 48";

   /* array to place converted integers into */
   int array[ARRAY_SIZE];

   /* this variable will keep track of the next index into the array */
   size_t index = 0;

   /* this will keep track of the next character to convert */
   /* unfortunately, strtol wants a pointer to non-const */
   char * pos = (char *)str;

   /* keep going until pos points to the terminating null character */
   while (*pos && index < ARRAY_SIZE)
   {
      long value = strtol(pos, &pos, 10);

      if (*pos != ' ' && *pos != '\0')
      {
         fprintf(stderr, "Invalid character at %s\n", pos);
         break;
      }

      array[index] = (int)value;
      index++;
   }
}
1 голос
/ 11 марта 2010

Надежная обработка строк в C никогда не бывает простой.

Вот процедура, которая сразу пришла мне в голову. Используйте strtok(), чтобы разбить строку на отдельные токены, затем преобразуйте каждый токен в целочисленное значение, используя strtol().

Что нужно знать: strtok() изменяет свой ввод (записывает 0 через разделители). Это означает, что мы должны передать ему записываемую строку. В приведенном ниже примере я динамически создаю буфер для хранения входной строки, а затем передаю этот динамический буфер в strtok(). Это гарантирует, что strtok() работает на доступной для записи памяти, и в качестве бонуса мы сохраняем наш ввод на случай, если он понадобится нам позже.

Кроме того, strtol() позволяет нам ловить плохо сформированные данные; второй аргумент будет указывать на первый символ в строке, который не был преобразован. Если этот символ является чем-то отличным от пробела или 0, тогда строка не была допустимым целым числом, и мы можем отклонить его, прежде чем назначить его в наш целевой массив.

#include <stdio.h>
#include <string.h>  
#include <stdlib.h>
#include <ctype.h>

/**
 * Convert a space-delimited string of integers to an array of corresponding
 * integer values.
 *
 * @param str     [in]  -- input string
 * @param arr     [in]  -- destination array
 * @param arrSize [in]  -- max number of elements in destination array
 * @param count   [out] -- number of elements assigned to destination array
 */
void stringToIntList(char *str, int *arr, size_t arrSize, size_t *count)
{
  /**
   * The token variable holds the next token read from the input string
   */
  char *token;

  /**
   * Make a copy of the input string since we are going to use strtok(),
   * which modifies its input.
   */
  char *localStr = malloc(strlen(str) + 1);
  if (!localStr)
  {
    /**
     * malloc() failed; we're going to treat this as a fatal error
     */
    exit(-1);
  }
  strcpy(localStr, str);

  /**
   * Initialize our output
   */
  *count = 0;

  /**
   * Retrieve the first token from the input string.
   */
  token = strtok(localStr, " ");
  while (token && *count < arrSize)
  {
    char *chk;
    int val = (int) strtol(token, &chk, 10);
    if (isspace(*chk) || *chk == 0)
    {
      arr[(*count)++] = val;
    }
    else
    {
      printf("\"%s\" is not a valid integer\n", token);
    }

    /**
     * Get the next token
     */
    token = strtok(NULL, " ");
  }

  /**
   * We're done with the dynamic buffer at this point.
   */
  free(localStr);
}

int main(void)
{
  int values[5];
  char *str = "14 22 33 48 5q";
  size_t converted;

  stringToIntList(str, values, sizeof values / sizeof values[0], &converted);

  if (converted > 0)
  {
    size_t i;
    printf("Converted %lu items from \"%s\":\n", (unsigned long) converted, str);
    for (i = 0; i < converted; i++)
      printf("arr[%lu] = %d\n", (unsigned long) i, arr[i]);
  }
  else
  {
    printf("Could not convert any of \"%s\" to equivalent integer values\n", str);
  }

  return 0;
}
0 голосов
/ 10 сентября 2015

лучший способ преобразовать строку целых чисел в реальные и сохранить их в массиве.

#include<stdio.h>
#include<string.h>
#include<ctype.h>
int atoi1(char*,int,int);
void main(){
    char arr1[1000];
    int array[1000];
    gets(arr1);
    int i=0,j,k=0;
    while(i<strlen(arr1)){
        j=i+1;
        while(*(arr1+j)!=' ')
            j++;
        *(array+k)=atoi1(arr1,i,j-1);
        i=j+1;k++;
    }
}
int atoi1(char *arr1,int start,int end){
    char arr2[1000];int j=0,i;
    for(i=start;i<end+1;i++){
        *(arr2+j)=*(arr1+i);
        j++;
    }
    *(arr2+j)='\0';
    return atoi(arr2);
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...