используя указатели в программировании на c - PullRequest
0 голосов
/ 29 октября 2019

У меня проблема с указателями в c-программировании. Я хотел бы получить переменные из командной строки в Linux, а затем присвоить значение переменных из командной строки переменной без указателя и распечатать их!

char * argv []

это функция, которая берет все, что написано после имени программы c в командной строке, и сохраняет его в указателе * argv [];Теперь я хотел бы сохранить эти значения указателя в обычной переменной и распечатать его в командной строке. Я получаю ошибку сегментации, когда я выполняю свой код.

int main ( int argc, char *argv[] )
{

    char r1;
    char a = *argv[1];
    char b = *argv[2];
    char c = *argv[3];

    if ( b == '+') {

    r1 = a + c;
    printf("%s", r1);
    }
}

Ответы [ 3 ]

3 голосов
/ 29 октября 2019

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 ", а значением этого выражения будет адрес первого элемента массива.

0 голосов
/ 01 ноября 2019

Наконец я понял! Теперь это мой код!

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

int main ( int argc, char *argv[] )
{
    if(argc < 4) {
        printf("Benötige mindestens 4 Argumente!\n");
        printf("Aufruf: %s <zahl><op><zahl> ...\n", argv[0]);
        return EXIT_FAILURE;
    }

    int  r1;
    int a = strtol (argv[1], NULL, 0);
    int c = strtol (argv[3], NULL, 0);

    if(strcmp(argv[2],"+") == 0) {
        r1 = a + c;
        printf("%d \n", r1);
    }

    return EXIT_SUCCESS; 

}

0 голосов
/ 29 октября 2019

В этом коде много ошибок. Решение, не элегантное, но работающее, состоит в следующем:

int main(int argc, char *argv[])
{
    char r1;
    char *a = argv[1];
    char b = argv[2][0];
    char *c = argv[3];

    if ( b == '+') {
        r1 = atoi(a) + atoi(c);
        printf("%d", r1);
    }
}

Этот код будет работать, как вы ожидаете, но это более элегантный способ сделать это.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...