сохранить отрицательное число в массиве символов (все еще нет требуемого/желаемого решения)

EDIT:
  platform unix 
  type :  ansi c

У меня есть данные в форме;

1 2 3 -1 2 -9 1 3 + 
-1 2 -3 -4 -
*

целое число в диапазоне от -9 до 9

оператор '+ - *' и показывает, что вы должны взять данные, которые лежат на следующей строке

данные - это двойной указатель char

каждая строка должна храниться в массиве символов с двойным указателем

example :   data[0] :=>  1 2 3 -1 2 -9 1 3 + 
            more precisely :  data[0][3] must store -1 

когда я беру данные и сохраняю, я не могу добиться сохранения -3 (отрицательное целое число) в данных [i] [j], потому что «-» — это символ, поэтому 3 не принимается данными [i] [j]

Что мне делать, чтобы справиться с этой проблемой?

РЕДАКТИРОВАТЬ: МОЙ код;

size_t datalen = sizeof( char ) ;

data = ( char ** ) malloc( sizeof (char * ) ) 
for ( i = 0 ;   ; ++i ) 
   data[i] = (char * ) malloc ( datalen )
   for ( j = 0 ;  ; ++ j )
         signed char ch;
         if j !=  0 
            datalen += 1
            data[i] = ( char * ) realloc ( begin[i], datalen )
         scanf ("%c ", &ch ) 
         begin[i][j] = ch 
         if ch == OP ( op = + , - , * , / )
             break
   if strlen ( begin[i] ) == 1 
           break

РЕДАКТИРОВАТЬ: если вы посмотрите на таблицу ascii, вы поймете, почему я не использую scanf("%d",&ch) http://www.asciitable.com/


person Community    schedule 20.12.2010    source источник
comment
Опубликовать код? Обратите внимание, что знак char определяется реализацией.   -  person ruslik    schedule 20.12.2010
comment
В чем твоя ошибка? Убедитесь, что вы используете подписанные символы.   -  person ughoavgfhw    schedule 20.12.2010
comment
С C99 вы можете использовать %hhd для прямого чтения значения в диапазоне от SCHAR_MIN до SCHAR_MAX. В противном случае сканируйте в int и копируйте в char. Как рекомендует ughoavgfhw, убедитесь, что вы используете signed char, а не обычный символ.   -  person pmg    schedule 20.12.2010


Ответы (4)


Я считаю, что ключ здесь в том, чтобы воспользоваться ограниченным диапазоном ваших входных значений. Поскольку ваши входные числа будут только целыми числами с одной цифрой, найдите несколько невозможных входных значений и зарезервируйте их для операторов. Например, вы можете позволить 64 быть «+», 65 может быть «-» и т. д. Используйте strtol() для считывания чисел по одному, затем проверьте их и убедитесь, что они попадают в указанный вами диапазон, и преобразуйте их в чар. Если вы видите оператор без прикрепленного к нему номера, преобразуйте его в соответствующее зарезервированное значение (создайте функции 'encode_operator' и 'decode_operator' для более чистого кода) и сохраните его.

Недостатком этого метода является то, что вы не можете слепо использовать сохраненное значение как число. Когда вы извлекаете данные из массива, вам придется проверять каждое значение, чтобы увидеть, является ли оно оператором или числом. В вашем случае простой макрос #IS_OPERATOR(x) ((x < -9) || (x > 9)) должен сделать это за вас.

person bta    schedule 20.12.2010

Если вы уверены, что целые числа находятся в диапазоне от -9 до 9, и хотите сохранить их в char по отдельности, есть хитрость, хотя и включено больше числовых вычислений.

Сопоставьте {-9, -8,..., 8, 9} с {0, 1,..., 17, 18}, вычитая -9 для каждого числа. На данный момент у вас есть все неотрицательные целые числа, так что делайте, что хотите. Во время выполнения вы должны преобразовать сохраненные данные в исходное значение, добавив -9.

person Exia    schedule 20.12.2010

char '2' != int 2

почему бы не использовать

int tmp; 
scanf("%d", &tmp);
data[i][j] = tmp;

вместо? Используя

scanf("%c", &ch);

вы читаете только один символ ASCII, который может быть пробелом, знаком минус или цифрой.

РЕДАКТИРОВАТЬ: после просмотра таблицы ASCII символ / с кодом 0x2F будет преобразован в -1 iff читается так:

char c; 
scanf("%c", &c);
data[i][j] = c - '0'; // 0x2F - 0x30 == -1
person ruslik    schedule 20.12.2010
comment
при использовании scanf(%d, ch) / будет равно -1 в data[i][j] или наоборот из-за ascii - person ; 20.12.2010
comment
Но когда я попытался использовать эту цифру и оператор, я столкнулся с новой проблемой, независимо от того, равно ли «/» -1 или нет. - person ; 20.12.2010
comment
Вы не можете хранить числа и символы операторов в одном и том же массиве, если хотите сохранить числа как числа. Это связано с тем, что в массиве хранится несколько объектов одного типа, а числа — это не то же самое, что операторы-символы. Вы можете хранить их все как экземпляры какого-то типа объединения, например, шоу chanchal1987. Но, вероятно, это не то, чем вы действительно хотите заниматься. Что вы на самом деле пытаетесь сделать? Как вы думаете, почему вы хотите хранить эти значения в массиве? Что вы собираетесь делать со значениями массива дальше? - person Karl Knechtel; 20.12.2010
comment
@Karl: вот почему я отказался от поддержки этого ответа. - person ruslik; 20.12.2010

Вместо этого вы можете использовать массив Union.

typedef union
{
  int num;
  char op;
} ABC;

Затем сделайте массив ABC.

person chanchal1987    schedule 20.12.2010
comment
Я не понимаю, почему это было -1'd. Но вы должны включить какие-то данные, чтобы указать, какое поле объединения используется, иначе вам придется угадывать, а неправильное угадывание очень быстро приводит к неопределенному поведению. См., например, en.wikipedia.org/wiki/Tagged_union . - person Karl Knechtel; 20.12.2010
comment
OK. Для этого можно использовать дополнительное поле. - person chanchal1987; 20.12.2010