#c #char #scanf #sizeof
Вопрос:
Я очень новичок в C, любая помощь была бы очень признательна. Я не могу использовать библиотеки <string.h>
или <ctype.h>
. Это код, который у меня есть:
int main(void)
{
char character;
printf("Introduce characters: ");
scanf(" %c", amp;character);
printf("nSize of character: %d", sizeof(character)/sizeof(char));
return 0;
}
При этом в качестве размера выводится только 1.
Я прочитал в другом посте, что проблема заключалась в том, что инициализация символа by char character;
позволила бы мне сохранить только 1 отдельный символ. Итак, я изменил его, чтобы он был массивом:
int main(void)
{
char character[10];
printf("Introduce maximum 10 characters: ");
scanf(" %s", character);
printf("nSize of character: %d", sizeof(character)/sizeof(char));
return 0;
}
Проблема сейчас в том , что при этом character[10]
он выводит, что размер равен 10. Как бы я это исправил?
Комментарии:
1.
sizeof
говорит вам о типе, а не о значении какого-либо объекта. Возможно, вы ищете этуstrlen()
функцию?2. Вы используете несовместимый спецификатор формата для
sizeof
. Вам нужно использовать%zu
или какой-либо другой совместимый формат. Ваш компилятор должен был предупредить об этом.3. Размер контейнера не зависит от содержимого этого контейнера.
Ответ №1:
sizeof(character)/sizeof(char)
указывает размер объявленного вами массива, а не размер введенного пользователем.
sizeof(character)
задает размер всего массива в байтахsizeof(char)
задает размер одного символа в байтах
Таким образом, когда вы это сделаете sizeof(character)/sizeof(char)
, вы получите фактический размер (т. Е. Количество элементов) вашего массива. То, чего вы пытаетесь достичь, можно сделать с strlen()
помощью . Но так как вы не можете использовать <string.h>
, вы можете написать его сами:
int strlen2(char *s)
{
int size;
for (size = 0; s[size]; size )
;
return size;
}
Затем используйте его, как:
#include <stdio.h>
int main(void)
{
char character[10];
printf("Introduce maximum 10 characters: ");
scanf("%s", character);
printf("nSize of character: %d", strlen2(character));
}
strlen2()
подсчитывает количество символов в вашей строке, она прекращает подсчет, когда встречает первый
символ (нулевой терминатор).
Избегайте использования scanf()
для чтения входных данных
Ваш код подвержен ошибкам. Если пользователь вводит строку длиной более 9 символов (не забывайте
, что она добавляется в конце вашей строки), вы получите переполнение буфера, потому character
что предполагается, что она содержит только 10 символов. Вы хотели бы ограничить количество символов, считываемых в вашу строку:
scanf("%9s", character); // Read only the first 9 characters and ignore the rest
Более того, scanf()
используется для анализа входных данных, а не для их фактического чтения. Используйте fgets()
вместо этого:
#include <stdio.h>
#include <string.h> // for strcspn()
int main(void)
{
char character[10];
printf("Introduce maximum 10 characters: ");
if(!fgets(character, 10, stdin)) {
fprintf(stderr, "Error reading input.n");
return 1;
}
character[strcspn(character, "n")] = ''; // fgets() reads also `n` so make sure to null-terminate the string
printf("nSize of character: %zu", strlen(character));
}
fgets()
принимает три аргумента:
- Первый — это массив, в котором вы хотите хранить пользовательский ввод
- Второй — это размер вашего массива
- Третий — это поток файлов, из которого вы хотите прочитать
Он возвращается NULL
при сбое, поэтому вы также должны это проверить.
Комментарии:
1. @EricPostpischil Я отредактировал ответ. Спасибо!
Ответ №2:
Ну, если вы не можете использовать какие-либо заголовки, возможно, вы можете создать пользовательскую strlen()
функцию.
strlen()
в значительной степени учитывается весь персонаж, пока ''
он не будет найден. ''
используется для обозначения конца строки и автоматически добавляется scanf("%s",...)
.
#include <stdio.h>
size_t ms_length(const char *s)
{
size_t i = 0;
for (; s[i] != ''; i )
;
return i;
}
int main(void)
{
char *str = "hello";
printf("%zun", ms_length(str));
return 0;
}
И если вы хотите быть педантичным, вы можете даже проверить возвращаемое значение scanf()
на наличие ошибок ввода , а также применить ограничение к считываемому символу, чтобы избежать переполнения буфера.
if (scanf(" %9s", character) != 1) /* 9 characters 1 reserved for */
{
/* handle error */
return 1;
}
Комментарии:
1. Пожалуйста, обратите внимание, что в вашей
ms_length
функции клиентаlen
переменная является посторонней. Вы можете просто вернутьсяi
.2. Это здорово, но он все равно возвращается
len
, и в этом случае фигурные скобки не нужны, как и сравнение, поскольку''
в C. Вы можете просто написатьfor (; s[i]; i );
.3. @Крис, еще раз спасибо тебе. Теперь должно быть правильно.