printf ("% s", r1);
Отсюда и происходит ваша ошибка.
Спецификатор преобразования %s
ожидает, что его соответствующий аргумент будет иметь тип char *
и будет адресом первого элемента массива с нулевым символом в конце char
. r1
- это результат добавления значений в a
и c
, которые не будут действительным адресом.
C не является Python или Javascript - значения магически не преобразуются между числами и строками в зависимости от контекста. Если вы хотите работать с числовыми значениями из командной строки, вы должны сначала вручную преобразовать строковые представления этих значений в соответствующие им типы.
Например, если ваша командная строка ./foo 1
, тогда argv[1]
содержит строку "1"
(представленную как последовательность {'1', 0}
). Значение *argv[1]
- это не 1
, это значение кодировки символа '1'
, которое, принимая ASCII, равно 49
. Вам необходимо использовать библиотечную функцию, такую как atoi()
или strtol()
, чтобы преобразовать строку "1"
в целочисленное значение 1
.
Если вы введете что-то вроде
./foo 1 + 2
и вы хотите, чтобы оно напечатало 3
, то вам нужно сделать что-то вроде следующего:
#include <stdlib.h>
#include <stdio.h>
int main( int argc, char **argv )
{
if ( argc < 4 )
{
fprintf( stderr, "USAGE: %s <val> <op> <val>\n", argv[0] );
return EXIT_FAILURE;
}
/**
* strtol() allows you to detect and reject non-numeric input,
* but I'm omitting that here for brevity.
*/
int lhs = (int) strtol( argv[1], NULL, 0 );
int rhs = (int) strtol( argv[3], NULL, 0 );
if ( *argv[2] == '+' )
{
int r1 = lhs + rhs;
printf( "%d\n", r1 );
}
return EXIT_SUCCESS;
}
Запомните:
В Си строка представляет собой последовательность символьных значений, включая терминатор с нулевым значением - строка "Hello"
представляется в виде последовательности {'H', 'e', 'l', 'l', 'o', 0 }
. Этот завершающий 0 необходим для того, чтобы последовательность была строкой.
Строки хранятся в массивах символьного типа (char
для таких кодировок, как ASCII, EBCDIC и UTF-8, wchar_t
для "широкого")кодировки как UTF-16).
За исключением случаев, когда он является операндом операторов sizeof
или унарных &
или является строковым литералом, используемым для инициализации массива символов в объявлении, выражением типа "N-элемент массива T
"будет преобразован (" распад ") в выражение типа" указатель на T
", а значением этого выражения будет адрес первого элемента массива.