Как мне запросить символы у пользователя, а затем распечатать размер символов?

#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) указывает размер объявленного вами массива, а не размер введенного пользователем.

  1. sizeof(character) задает размер всего массива в байтах
  2. 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. @Крис, еще раз спасибо тебе. Теперь должно быть правильно.