2012-06-24 3 views
2

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

Например, рассмотрим следующую программу.

char str[50]; 
int i; 
int len; 
printf("Enter name:\n"); 
fgets(str,11,stdin); 
len = strlen(str); 
printf("len : %d\n",len); 
  1. Если я вхожу 123456789, strlen дает 10.

  2. Если я вхожу 1234567890, strlen получили в 10 раз ??

0 думаю, strlen рассматривается новая линия тоже для длина строки. Я прав? (я понимаю fgets, используя новую строку как часть строки)

Что случилось с (2), где я ввожу ровно 10 символов, Здесь длина строки должна быть 11 правильно? 10 + 1 (для перевода строки) = 11

+0

printf ("len:% d", len); \t printf ("str:% s", str); \t printf ("hi"); return 0; } Добавление нескольких отпечатков помогает прояснить ответы, приведенные ниже. Обратите внимание, как печатается «привет». – kumar

ответ

4

fgets читает не более 1 меньше символов, чем длина аргумент заданного, и делает сохраняет новую строку, как часть входных данных - до тех пор, как новая строка является частью первого (длина - 1).

Итак, в вашем первом случае, при условии, что 123456789 следует за новой строкой, fgets прочитал 9 символов, включая новую строку, с длиной строки 10; в вашем втором случае, fgets остановится после прочтения 10 символов 1234567890, получая длину строки 10.

+1

Незначительная коррекция: он не будет * сохранять символ новой строки, если #/characters> = max length. Как показано в примере ниже. – paulsm4

+1

@ paulsm4 Я считаю, что это уже ясно из моей первой строки: _reads не более 1 меньше символов, чем аргумент length given_. – pb2q

1

Вот пример:

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

#define MAX_DIGITS 5 

int 
main() 
{ 
    char buf[80]; 
    char *s = NULL; 
    printf ("\n>>Enter string, %d digits or less: ", MAX_DIGITS); 
    s = fgets (buf, MAX_DIGITS+1, stdin); 
    printf ("strlen(buf)=%d, buf=%s, strlen(s)=%d, s=%s\n", 
    strlen(buf), buf, strlen(s), s); 
    return 0; 
} 

Пример выходных данных, с «MAX_DIGITS» и «MAX_DIGITS + 1 «:

>>Enter string, 5 digits or less: 1 
strlen(buf)=2, buf=1 
, strlen(s)=2, s=1 
. 

>>Enter string, 5 digits or less: 12 
strlen(buf)=3, buf=12 
, strlen(s)=3, s=12 
. 

>>Enter string, 5 digits or less: 123 
strlen(buf)=4, buf=123 
, strlen(s)=4, s=123 
. 

>>Enter string, 5 digits or less: 1234 
strlen(buf)=5, buf=1234 
, strlen(s)=5, s=1234 
. 

>>Enter string, 5 digits or less: 12345 
strlen(buf)=5, buf=12345, strlen(s)=5, s=12345. 

>>Enter string, 5 digits or less: 123456 
strlen(buf)=5, buf=12345, strlen(s)=5, s=12345. 

Вы заметите:

  1. возвращение б uffer сохраняет «\ n», если #/цифры < MAX_DIGITS.

  2. «\ n» УДАЛЕН, когда #/цифры> = MAX_DIGITS.

  3. Ваш буфер должен вместить MAX_DIGITS + 1

+0

<< Ваш буфер должен содержать MAX_DIGITS + 1. Таким образом, буфер должен иметь достаточно места для хранения новой строки, которая равна +1. Спасибо за вашу помощь. – kumar

+0

@kumar Для хранения новой строки должно быть + 2, поскольку fgets уже отбирает один для хранения значения нулевого ограничителя -> '\ 0'; То есть, если вы пройдете его 6, он будет читать не более 5 вещей (4 цифры + CR или 5 цифр). Если вы пройдете его 7, он будет читать 5 цифр плюс возврат каретки. – Scooter

-1

На самом деле fgets требует size спецификации (в вашем случае 11) счета для \0 в конце строки. На странице fgets человек:

fgets() считывает максимум один меньше символов размера из потока и сохраняет их в буфер, на который указывает с. Чтение останавливается после EOF или новой строки. Если считывается новая строка , она сохраняется в буфере. Конечный нуль байт ('\ 0') сохраняется после последнего символа в буфере.

Таким образом, мы знаем, что чтение останавливается на \n, когда вы вводите 123456789\n. Однако, когда вы вводите 1234567890\n, fgets() обрабатывает ввод, но он принимает только 10 символов и затем игнорирует все остальное.

Любой дополнительный ввод вашей строки и вашей строки будет равен size-1 из fget() с последним символом как \0, поэтому выход остается неизменным.