K & R Exercise: мои работы кода, но вонючие чувства; совет для очистки?

async/await - хороший шаблон для использования.

var arr = ["foo","bar","test"];

function oneSecond() {
    return new Promise(resolve => {
        setTimeout(() => {
            resolve('resolved');
        }, 1010);
    });
}
async function writeToDom(arr) {
    console.log("beginning write");
    for (var i = 0; i < arr.length; i++) {
        await oneSecond();
        console.log(arr[i]);
    }
    console.log("done.");
}
writeToDom(arr);

8
задан Deduplicator 23 January 2015 в 11:15
поделиться

9 ответов

Нет никакой причины иметь два буфера, можно обрезать входную строку на месте

int trim(char line[])
{
    int len = 0;
    for (len = 0; line[len] != 0; ++len)
        ;

    while (len > 0 &&
           line[len-1] == ' ' && line[len-1] == '\t' && line[len-1] == '\n')
        line[--len] = 0;

    return len;
}

Путем возврата длины строки можно устранить пустые строки путем тестирования на ненулевые строки длины

if (trim(line) != 0)
    printf("%s\n", line);

Править: Можно сделать цикл с условием продолжения еще более простым, принимающим кодированием ASCII.

while (len > 0 && line[len-1] <= ' ')
    line[--len] = 0;
5
ответ дан 5 December 2019 в 10:44
поделиться

Если Вы придерживаетесь главы 1, которая выглядит довольно хорошей мне. Вот то, что я рекомендовал бы с точки зрения обзора кода:

При проверке равенства в C, всегда помещает константу сначала

if (1 == myvar)

Тем путем Вы никогда не будете случайно делать чего-то вроде этого:

if (myvar = 1)

Вам не может сойти с рук это в C#, но он компилирует прекрасный в C и может быть настоящим дьяволом для отладки.

9
ответ дан 5 December 2019 в 10:44
поделиться

Лично я поместил код как это:

ret[i] != '\0' && ret[i] != '\r' && ret[i] != '\n'

в отдельную функцию (или даже определить макрос)

0
ответ дан 5 December 2019 в 10:44
поделиться

Лично, для в то время как конструкции:

Я предпочитаю следующее:

while( (ret[i] = line[i]) )
        i++;

кому:

while ((ret[i] = line[i]) != '\0')
        ++i;

Они оба проверка по сравнению с! = 0, но первые взгляды, немного более чистые. Если символ будет чем-нибудь другой thah 0, то тело цикла еще выполнится, это убежит из цикла.

Также для 'для' операторов, будучи синтетически допустимым, я нахожу что следующее:

for (  ; i >= 0; --i)

просто выглядит 'нечетным' мне и действительно потенциальное решение для кошмара для потенциальных ошибок. Если бы я рассматривал этот код, то он был бы похож на светящееся красное предупреждение как. Обычно Вы хотите использовать для циклов для итерации известного количества раз, иначе cosider некоторое время цикл. (как всегда существуют исключения из правила, но я нашел, что это обычно сохраняется). Вышеупомянутое для оператора могло стать:

while (i)
{
        if (ret[i] == ' ' || ret[i] == '\t')
        {
            ret[i--] = '\0';
        }
        else if (ret[i] != '\0' && ret[i] != '\r' && ret[i] != '\n')
        {
            break;
        }
}
1
ответ дан 5 December 2019 в 10:44
поделиться
  1. обрезка должна действительно использовать 1 буфер только (как @Ferruccio говорит).
  2. обрежьте должен быть разбит, как говорит @plinth
  3. обрежьте не должен возвращать значение (если Вы хотите проверить на пустую строку, тестовая строка [0] == 0),
  4. для дополнительной разновидности C используйте указатели, а не индексы

- перейдите к концу строки (завершающийся 0; - в то время как не в начале строки и текущего символа пространство, замените его 0. - назад от одного символа

char *findEndOfString(char *string) {
  while (*string) ++string;
  return string; // string is now pointing to the terminating 0
}

void trim(char *line) {
  char *end = findEndOfString(line);
   // note that we start at the first real character, not at terminating 0
  for (end = end-1; end >= line; end--) {
      if (isWhitespace(*end)) *end = 0;
      else return;
  }
}
0
ответ дан 5 December 2019 в 10:44
поделиться

Вот мой удар при осуществлении, не зная то, что находится в Главе 1 или K & R. Я принимаю указатели?

#include "stdio.h"

size_t StrLen(const char* s)
{
    // this will crash if you pass NULL
    size_t l = 0;
    const char* p = s;
    while(*p)
    {
        l++;
        ++p;
    }
    return l;
}

const char* Trim(char* s)
{
    size_t l = StrLen(s);
    if(l < 1)
        return 0;

    char* end = s + l -1;
    while(s < end && (*end == ' ' || *end == '\t'))
    {
        *end = 0;
        --end;
    }

    return s;
}

int Getline(char* out, size_t max)
{
    size_t l = 0;
    char c;
    while(c = getchar())
    {
        ++l;

        if(c == EOF) return 0;
        if(c == '\n') break;

        if(l < max-1)
        {
            out[l-1] = c;
            out[l] = 0;
        }
    }

    return l;
}

#define MAXLINE 1024

int main (int argc, char * const argv[]) 
{
    char line[MAXLINE];
    while (Getline(line, MAXLINE) > 0)
    {
        const char* trimmed = Trim(line);
        if(trimmed)
            printf("|%s|\n", trimmed);

        line[0] = 0;
    }

    return 0;
}
0
ответ дан 5 December 2019 в 10:44
поделиться

В первую очередь:

международное основное (пустота)

Вы знаете параметры к основному (). Они - ничто. (Или argc&argv, но я не думаю, что это - материал Главы 1.)

Stylewise, Вы могли бы хотеть попробовать скобки K&R-style. Они намного легче на вертикальном пространстве:

void trim(char line[], char ret[])
{
    int i = 0;

    while ((ret[i] = line[i]) != '\0')
        ++i;

    if (i == 1) { // Special case to remove entirely blank line
        ret[0] = '\0';
        return;
    }

    for (; i>=0; --i) { //continue backwards from the end of the line
        if ((ret[i] == ' ') || (ret[i] == '\t')) //remove trailing whitespace
            ret[i] = '\0';

        else if ((ret[i] != '\0') && (ret[i] != '\r') && (ret[i] != '\n')) //...until we hit a word character
            break;
    }

    for (i=0; i<MAXLINE-1; ++i) { //-1 because we might need to add a character to the line
        if (ret[i] == '\n') //break on newline
            break;

        if (ret[i] == '\0') { //line doesn't have a \n -- add it
            ret[i] = '\n';
            ret[i+1] = '\0';
            break;
        }
    }
}

(Также добавленные комментарии и исправили одну ошибку.)

Большой проблемой является использование константы MAXLINE - основной (), исключительно использует его для строки и переменных; обрезка (), который только работает над ними, не должна использовать константу. Необходимо передать размер (размеры) в качестве параметра точно так же, как Вы сделали в getline ().

0
ответ дан 5 December 2019 в 10:44
поделиться

обрезка () является слишком большой.

То, что я думаю, что Вам нужно, является функцией strlen-выхода (разрешение, и запишите этому интервал stringlength (символ константы *s)).

Затем Вам нужна функция, вызванная интервал scanback (символ константы *s, символ константы *соответствия, международный запуск), который запускается в запуске, снижается до z, пока символ, просканированный в s идентификаторе, содержавшемся в соответствиях, возвратите последний индекс, где соответствие найдено.

Затем Вам нужна функция, вызванная интервал scanfront (символ константы *s, символ константы *соответствия), который запускается в 0 и сканирует вперед, пока символ, просканированный в s, содержится в соответствиях, возвращая последний индекс, где соответствие найдено.

Затем Вам нужна функция, вызванная интервал charinstring (символ c, символ константы *s), который возвращается ненулевой, если c содержится в s, 0 иначе.

Необходимо смочь записать обрезку с точки зрения их.

1
ответ дан 5 December 2019 в 10:44
поделиться

Другой пример выполнения того же самого. Сделал некоторое незначительное нарушение при помощи C99-определенного материала. это не будет найдено в K&R. также используемый утверждение () функция, которая является частью starndard библиотеки, но вероятно не охвачена в главе один из K&R.

#include <stdbool.h> /* needed when using bool, false and true. C99 specific. */
#include <assert.h> /* needed for calling assert() */

typedef enum {
  TAB = '\t',
  BLANK = ' '
} WhiteSpace_e;

typedef enum {
  ENDOFLINE = '\n',
  ENDOFSTRING = '\0'
} EndofLine_e;

bool isWhiteSpace(
  char character
) {
  if ( (BLANK == character) || (TAB == character ) ) {
    return true;
  } else {
    return false;
  }
}

bool isEndOfLine( 
  char character
) {
 if ( (ENDOFLINE == character) || (ENDOFSTRING == character ) ) {
    return true;
  } else {
    return false;
  }
}   

/* remove blanks and tabs (i.e. whitespace) from line-string */
void removeWhiteSpace(
  char string[]
) {
  int i;
  int indexOutput;

  /* copy all non-whitespace character in sequential order from the first to the last.
    whitespace characters are not copied */
  i = 0;
  indexOutput = 0;
  while ( false == isEndOfLine( string[i] ) ) {
    if ( false == isWhiteSpace( string[i] ) ) {
      assert ( indexOutput <= i );
      string[ indexOutput ] = string[ i ];
      indexOutput++;
    }
    i++; /* proceed to next character in the input string */
  }

  assert( isEndOfLine( string[ i ] ) );
  string[ indexOutput ] = ENDOFSTRING;

}
0
ответ дан 5 December 2019 в 10:44
поделиться
Другие вопросы по тегам:

Похожие вопросы: