Итак, я кодирую функцию верхнего регистра с использованием указателей. Я пытаюсь сделать сообщение об ОШИБКЕ, когда есть ввод, но, к сожалению, в терминале я не вижу ничего похожего на то, что s==NULL работает не очень хорошо, я не вижу никаких сообщений об ОШИБКЕ.
Вероятно, проблема с типами аргументов и указателем, но я этого не вижу!
Если мои аргументы программы выглядят так:
"Hello 123dsd" "teSting"
Выход:
HELLO 123DSD
TESTING
Если аргументы моей программы пусты:
вывод ничего:
Я хочу показать сообщение об ОШИБКЕ, если аргументы пусты, например:
Please insert a string!
Вот мой код:
#include <stdio.h>
#include <stdlib.h>
#define MAGIC_NUMBER 32
char *uppercase(char *s)
{
if (s == NULL)
{
printf("Please insert a string!");
return 0; //Not working!!
}
else
{
for(char *p = s; *p!=0; ++p)
{
if ('a' <= *p && *p <= 'z')
*p = *p - MAGIC_NUMBER;
}
return s;
}
}
int main(int argc, char *argv[])
{
for(int i=1; i < argc; i++)
{
printf("%s \n", uppercase(argv[i]));
}
return 0;
}
Что именно означает «не очень хорошо работает» или «Не работает!». argv[i]
с i<argc
никогда не должно быть указателем NULL
. Хотя некоторые реализации printf
будут печатать (null)
при передаче указателя NULL
, это поведение undefined. Вы должны проверять возвращаемое значение функции, которая может возвращать NULL
, и передавать его в printf
, только если это не NULL
.
@Bodo Можете ли вы показать с кодом, я был бы так счастлив, большое спасибо за ваше время!
Вместо MAGIC_NUMBER
вы можете сделать его немного менее волшебным, написав 'a' - 'A'
@WilliamPursell Я не могу #define, как будто этот результат портит его, давая мне @ вместо заглавных букв
@Bobamas Во-первых, примените предложение в комментарии Крейга Эсти. Затем, пожалуйста, отредактируйте свой вопрос и покажите командную строку, которую вы используете для запуска своей программы, фактический и ожидаемый результат. Или опишите, чего вы хотите добиться. Без этого непонятно, как модифицировать код под свои нужды. Что именно вы хотите, чтобы я показал? Как избежать передачи указателя NULL
на printf
?
@Bobamas #define MAGIC_NUMBER ('a' - 'A')
должно работать без проблем. В вашем случае это должно работать даже без круглых скобок, но я рекомендую оставить круглые скобки.
@Bodo Большое спасибо, я редактирую свой вопрос, надеюсь, он намного понятнее?
@Bobamas Я намеренно добавил имя программы myprogram
в командную строку, чтобы читателю было более понятно, что это командная строка, а не какой-либо другой тип ввода. Конечно, я не предполагаю, что ваша программа на самом деле называется myprogram
, но это имя не имеет большого значения для примера в вопросе.
Большое спасибо @Bodo
Если вы не вводите никаких параметров в программу, argc
будет равно 1, поэтому цикл for
в функции main
никогда не будет введен. Это также означает, что указатель NULL никогда не будет передан в uppercase
.
Вам нужно переместить проверку отсутствующих аргументов на main
:
int main(int argc, char *argv[])
{
if (argc == 1) {
printf("Please insert a string!");
return 1;
}
for(int i=1; i < argc; i++)
{
printf("%s \n", uppercase(argv[i]));
}
return 0;
}
Большое спасибо! Я боролся с этими аргументами более часа!
Если вы вызовете свою программу без аргументов, она ничего не напечатает, потому что цикл не вызовет printf
или uppercase
, поскольку argc
будет иметь значение 1
.
Вы должны добавить код в main
, чтобы обработать этот случай.
int main(int argc, char *argv[])
{
if (argc < 2)
{
fprintf(stderr, "Please insert a string!\n")
return 1;
}
for(int i=1; i < argc; i++)
{
printf("%s \n", uppercase(argv[i]));
}
return 0;
}
Обратите внимание, что я использую fprintf(stderr, ...)
для сообщения об ошибке, потому что сообщения об ошибках не должны смешиваться с обычным выводом.
С
*s == NULL
вы разыменовываетеs
, поэтому он возвращает значение первого символа массива. Итак, вы хотите проверить значение указателя и хотитеs == NULL
(без*
)