это программная программа на основе командной строки для проверки строки палиндрома, и мой ответ подходит, но я должен был предоставить аргументы 2 раза в терминале

Это, по-видимому, (недокументированное) расширение «GNU»: [ correction : Наконец, я нашел упоминание в документах. См. Ниже.]

Следующая команда использует параметр -dM для печати всех препроцессоров; поскольку входной «файл» пуст, он показывает точно предопределенные макросы. Он был запущен с gcc-4.7.3 на стандартной установке ubuntu. Вы можете видеть, что препроцессор является стандартным. Всего существует 243 макроса с -std=gnu99 и 240 с -std=c99; Я отфильтровал вывод для релевантности.

$ cpp --std=c89 -dM < /dev/null | grep linux
#define __linux 1
#define __linux__ 1
#define __gnu_linux__ 1

$ cpp --std=gnu89 -dM < /dev/null | grep linux
#define __linux 1
#define __linux__ 1
#define __gnu_linux__ 1
#define linux 1

$ cpp --std=c99 -dM < /dev/null | grep linux
#define __linux 1
#define __linux__ 1
#define __gnu_linux__ 1

$ cpp --std=gnu99 -dM < /dev/null | grep linux
#define __linux 1
#define __linux__ 1
#define __gnu_linux__ 1
#define linux 1

Стандарты «gnu standard» также #define unix. (Использование c11 и gnu11 дает те же результаты.)

Я полагаю, что у них были свои причины, но мне кажется, что я устанавливаю установку gcc по умолчанию (которая компилирует код C с -std=gnu89 если не указано иное) несоответствия, и - как в этом вопросе - удивительно. Загрязнение глобального пространства имен макросами, имена которых не начинаются с символа подчеркивания, не допускается в соответствии с реализацией. (6.8.10p2: «Любые другие предопределенные имена макросов начинаются с верхнего подчеркивания, за которым следует буква верхнего регистра или второй символ подчеркивания», но, как упоминалось в Приложении J.5 (проблемы с переносимостью), такие имена часто предопределены.)

Когда я изначально написал этот ответ, мне не удалось найти какую-либо документацию в gcc об этой проблеме, но я, наконец, обнаружил ее, а не в C, определяемом реализацией поведения и в расширениях C , но в разделе cpp руководства 3.7.3 , где он отмечает, что:

Мы постепенно прекращаем работу предопределенные макросы, которые находятся за пределами зарезервированного пространства имен. Вы никогда не должны использовать их в новых программах & hellip;

blockquote>

-4
задан Vivek Kumar Singh 13 July 2018 в 06:01
поделиться

3 ответа

Я не вижу заданного вопроса, поэтому я также опубликую свою собственную реализацию, которая действительно работает, так как весь ваш код является беспорядком. Не стесняйтесь ничего спрашивать.

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

int isPalindrome(char*);

int main(int argc, char * argv[])
{
    /* Skip filepath (argv[0]); end of command line is marked with NULL. */
    for(int argIndex = 1; argv[argIndex] != NULL; ++argIndex)
    {
        isPalindrome(argv[argIndex])
        ? fprintf(stdout, "%s is a palindrome.\n", argv[argIndex])
        : fprintf(stdout, "%s is NOT a palindrome.\n", argv[argIndex]);
    }

    return 0;
}

int isPalindrome(char* pString)
{
    /* Ignore the terminator. */
    size_t lastIndex = strlen(pString) - 1;
    size_t middle = lastIndex / 2;
    /* Include the middle index in case the string length is an odd number. */
    for (size_t offset = 0; offset <= middle; ++offset) 
    {
        /* No need for flags, stop as soon as you see different letters. */
        if (pString[offset] != pString[lastIndex - offset]) 
        {
            return 0;
        }
    }
    /* Line only reached if all symmetrical letters are not different. */
    return 1;
}

Именован исполняемый файл myNewProgram. Это мой консольный ввод-вывод в Ubuntu. Естественно, кавычки должны явно выражать аргументы, чтобы они не были разделены пробелами.

/home/don/myNewProgram "TEST" "TET" "" "HUH" "OOMPA LOOMPA" "OOOOO"
TEST is NOT a palindrome.
TET is a palindrome.
 is NOT a palindrome.
HUH is a palindrome.
OOMPA LOOMPA is NOT a palindrome.
OOOOO is a palindrome.

Если вы запускаете командную строку в Windows, попробуйте

<path to program>/<name of program>.exe "TEST" "TET" "" "HUH" "OOMPA LOOMPA" "OOOOO"
-1
ответ дан Don Goodman 17 August 2018 в 13:37
поделиться

it is command line based c program to check for palindrome string and my answer is coming right but i had to supply arguments 2 times in the terminal....

Ваша программа не может дать правильные результаты, потому что цикл for используется для определения того, является ли входная строка палиндром или не повторяется не один раз. [подробнее см. ниже]

Я не знаю, что именно означает - i had to supply arguments 2 times in the terminal

By глядя на ваш код, могу только сказать, что вы должны передать строку (чтобы проверить, является ли она палиндром или нет) в качестве аргумента командной строки, и поскольку ваш main() имеет gets(), поэтому он останавливается там и ждет ввода пользователя и там вы должны указывать ту же строку, которую вы передаете в качестве аргумента командной строки для программы. Кажется, это то, что вы подразумеваете под своим утверждением - i had to supply arguments 2 times...

Прежде всего, не используйте gets (). Это небезопасно и, кроме того, оно устарело. Проверьте на этом . Вместо этого используйте fgets (). Проверьте этот .

Есть два способа получить вход -

  • Возьмите его у пользователя во время выполнения (вы можете использовать fgets() для это)
  • Передайте его как аргумент командной строки

Так как в аннотациях вы упомянули - it is command line based c program to check for palindrome string and my answer is... Итак, в моем ответ, я буду принимать ввод как аргумент командной строки.

Если вы используете компилятор gcc, программа компиляции с параметрами -Wall -Wextra и компилятором выдает предупреждающее сообщение для этого оператора

(argv[1]) == string;

warning: statement with no effect

В цикле for функции palindrome() вы прерываете цикл на первой итерации:

for (i = 0; i < strlen(string); i++) {
  if (string[i] == string[strlen(string) - i - 1])
    flag = 1;
  break;  // <--- will break the loop in first iteration
}

И функция palindrome() заканчивает сообщение о палиндроме на основе того, будет ли первый и последний символ входной строки такой же или нет.

Вы должны разбить цикл только тогда, когда любой символ в позиции i в первой половине строки не совпадает с символом в позиции string_len - i -1 во второй половине строки. Кроме того, вам не нужно итерировать всю строку, чтобы проверить, является ли она палиндром или нет:

for (i = 0; i < strlen(string); i++) {
                ^^^^^^^^^^^^^

Вам просто нужно перевести строку в ее середину, чтобы определить, является ли строка палиндром или нет .

Тип возврата strlen() - size_t, который является unsigned integer. Итак, лучше взять итератор цикла одного и того же типа.

Между заголовком файла и скобкой угла открытия и закрытия не должно быть пробелов <,>:

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

Пока ищет заголовочный файл, компилятор также включает пробел в имени и не обрезает ведущее и конечное пространство и сообщит об ошибке ' stdio.h ' заголовочного файла.

Объединяя все это вместе, вы можете сделать :

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

int palindrome(char *p_string) {
    int flag = 0;
    size_t len = strlen(p_string);

    if (len == 1)
        flag = 1;

    for (size_t i = 0; i < (len/2); i++) {
        if (p_string[i] == p_string[len - i - 1])
            flag = 1;
        else
            break;
    }

    if (flag == 1)
        printf("palindrome string\n");
    else
        printf("not palindrome string\n");

    return 0;
}
int main(int argc, char * argv[]) {
    /* Check for number of expected arguments */
    if (argc != 2) {
        fprintf (stderr, "Invalid number of arguments\nUsage:%s <string>\n", argv[0]);
        return -1;
    }

    palindrome(argv[1]);
    return 0;
}

Вы можете использовать его следующим образом:

$ ./a.out abc
not palindrome string
$ ./a.out aba
palindrome string
$ ./a.out abccba
palindrome string
1
ответ дан H.S. 17 August 2018 в 13:37
поделиться
  • 1
    Удивительный человек, ты слишком хорош в объяснении – Vivek Kumar Singh 13 July 2018 в 16:42
  • 2
    Большое спасибо за пошаговое решение, вы бог человек: D – Vivek Kumar Singh 13 July 2018 в 16:55

Как указано в комментариях, строка (argv[1]) == string ничего не делает (gcc, который сказал бы вам warning: statement with no effect [-Wunused-value])

Кроме того, функция gets не используется, даже для тестовых программ, fgets выполнит одно и то же задание более надежно:

/* assuming string is an array: */
fgets(string, sizeof string, stdin); 

/* when string points on at least `size` bytes: */
fgets(string, size, stdin);

Итак, ваш исправленный код main() может быть:

int main(int argc, char * argv[])   
{
  char string[200];
  fgets(string, sizeof string, stdin);

  return palindrome(string); 
}

Но есть логичный проблема в функции palindrome, посмотрите на:

int flag = 0;
for (i = 0; i < strlen(string); i++) {
    if (string[i] == string[strlen(string) - i - 1])
        flag = 1;
    break;
}

При размещенном здесь break вы будете тестировать только i = 0 (вы можете добавить один printf("testing i=%d", i); непосредственно перед if ], чтобы увидеть это.

Итак, каждая строка, которая начинается и заканчивается с той же буквой, будет считаться палиндром ...

А также вы должны инвертировать тест. flag следует установить в 1 и установить на 0, если две проверенные буквы различны.

Ваш цикл for должен выглядеть так:

int flag = 1;
for (i = 0; i < strlen(string); i++) {
    printf("testing %d vs %d\n", i, strlen(string)-i-1);
    if (string[i] != string[strlen(string) - i - 1])
    {
        flag = 0;
        break;
    }
}

Чтобы идти дальше, данный код может быть улучшен:

  • есть много вызовов функции strlen(), где одного вызова будет достаточно,
  • каждая буква проверяется дважды, условие выхода цикла for может быть лучше ...
1
ответ дан purplepsycho 17 August 2018 в 13:37
поделиться
Другие вопросы по тегам:

Похожие вопросы: