2016-03-03 2 views
3

Мне нужно создать функцию C, которая возвращает строку, считанную из дескриптора файла. Я должен определить макрос READ_SIZE (который может быть доступен для редактирования). Это READ_SIZE указывает количество символов, которые нужно читать при каждом вызове read(). Число может быть только положительным.Бесконечная петля на Get_Next_Line в C

Я также должен использовать одну или несколько статических переменных для сохранения символов, которые были прочитаны, но не отправлены обратно вызывающей функции. Один файл .C (максимум 5 функций, максимум 25 строк для каждой функции) и только один файл .h.

Моя функция Get_Next_Line должна вернуть свое возвращение без '\ n'. Если больше ничего не читать в дескрипторе файла, или если при чтении возникает ошибка, функция возвращает NULL.

Вот прототип функции:

char *get_next_line(const int fd) 

FUNCTIONS ALLOWED: malloc, free, read, write (to use with my_putchar, my_putstr, etc). 

Вот что у меня есть, но он не работает. Он делает бесконечный цикл, я пытаюсь понять, почему.

char  *my_strcat(char *str1, char *str2) 
{ 
    int  i; 
    int  j; 
    int  s; 
    char  *strfinal; 

    i = 0; 
    j = 0; 
    s = 0; 
    if ((strfinal = malloc(sizeof(char) * (my_strlen(str1) + my_strlen(str2) 
         + 1))) == NULL) 
    return (NULL); 
    while (str1[i] != '\0') 
    { 
     strfinal[j] = str1[i]; 
     i++; 
     j++; 
    } 
    while (str2[s] != '\0') 
    { 
     strfinal[j] = str2[s]; 
     s++; 
     j++; 
    } 
    free(str1); 
    strfinal[j] = '\0'; 
    return (strfinal); 
} 

char  *get_next_line(const int fd) 
{ 
    int  n; 
    int  i; 
    char  *str_to_return; 
    static char buff[READ_SIZE] = {'\0'}; 

    n = 1; 
    i = 0; 
    str_to_return = NULL; 
    while (n) 
    { 
    if (i == 0 && buff == '\0') 
    { 
     if ((read(fd, buff, READ_SIZE)) <= 0) 
     return(str_to_return); 
     if (i == READ_SIZE - 1 || buff[i] == '\n') 
     { 
      n = 0; 
      str_to_return = my_strcat(buff, str_to_return); 
      i = -1; 
     } 
    } 
    i++; 
    } 
    printf("%s\n", str_to_return); 
    return (str_to_return); 
} 
+0

'.C' обычно используется для C++. используйте '.c' для кода C. – Olaf

+1

Использование для циклов сделает это намного проще для вас и для нас. –

+1

так же, как и имена переменных длиной более одной буквы. – interjay

ответ

0

в этом коде:

while (str1[i] != '\0') 
{ 
    strfinal[j] = str1[i]; 
    i++; 
    j++; 
} 

, что гарантия у вас есть, что будет нулевой символ \0 где-то в str1[] ???

то же самое касается str2 while loop. Если нулевой символ встречается, то там будет бесконечный цикл.

проверить функции, которые вы используете для заполнения символов в памяти под str1[] и str2[], включают нулевой символ. Поскольку вы используете только функцию read(), тогда ответ будет отрицательным.

Проблема с двумя циклами while для str1[] и str2[] заключается в том, что вы полагаетесь на нулевой символ, который уже существует в памяти. И тогда возникает вопрос, кто помещает эти данные в память, и было ли им требовалось прекратить символьные данные с нулевым символом? вам необходимо каким-то образом разместить контроль над любым циклом, который вы пишете, чтобы не попасть в бесконечное условие цикла; в этом случае, возможно, используйте счетчик и после стольких авансов i для доступа к str1[i], затем остановите, потому что вам еще нужно увидеть нулевой символ.

например, функция fgets() будет считывать столько символов из потока FILE в массив и всегда заканчивать его нулевым символом.

+0

Бесконечный цикл находится во 2-й функции (get_last_line()) ... * strcat * предполагает, что строка символов, на которые указывает указывает, имеет хвост 0, поэтому справедливо, что * my_strcat * предполагает то же самое. –

+0

Да, я вижу во второй функции get_next_line() проблему. Цикл while (n), который имеет одну большую инструкцию if, за которой следует i ++; после первого вмешательства i увеличивается с нуля, и условие для ввода инструкции if никогда не выполняется. поэтому значение n никогда не изменяется, в результате чего бесконечный цикл с i ++ происходит вечно. этот раздел должен быть исправлен раньше всего. – ron

0
if (i == 0 && buff == '\0') 

всегда ложно, потому что ваше определение нагишом является

static char buff[READ_SIZE] = {'\0'}; 

Вы пытаетесь проверить, если положительный эффект пуст, когда я 0. Однако, как указатель полукокса, бафф адрес и никогда 0. Вы хотите сделать, если

if (i == 0 && buff[0] == '\0') 

, чтобы проверить, является ли первый символ символом Нуль.

Однако после того, как я увеличивается, то он всегда терпит неудачу, даже если вы проверяете против

if (i == 0 && buff[i] == '\0') 

для того, чтобы найти символ NULL в буфере. Поскольку вы вводите while с i = 0 и проверяете, является ли buff пустым, вам не нужно время.

Если вы хотите просто заполнить буфер и продолжить чтение до полного заполнения, вам нужен другой тип теста. Вам также нужен способ проверки, если вам нужно выйти из цикла while, если это не удается (введите другое, чтобы определить, что делать).

Вам также не нужно проверять каждый символ в баффе на «\ 0», потому что ваш код всегда застрахован, чтобы он заканчивался одним (даже для инициализации). Таким образом, strlen (buff) будет действительным.

Другое дело, что при вызове mystrcat() вы уже подтвердили, что буфер пуст.

Кроме того, поскольку вторая строка в вызове - это то, что вы читаете, тогда у mystrcat() не всегда будет '\ 0' в конце str2 (хотя вы гарантируете, что buff (str1) будет) , Вы должны вызвать его с количеством символов в str2 для использования.