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);
Нет никакой причины иметь два буфера, можно обрезать входную строку на месте
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;
Если Вы придерживаетесь главы 1, которая выглядит довольно хорошей мне. Вот то, что я рекомендовал бы с точки зрения обзора кода:
При проверке равенства в C, всегда помещает константу сначала
if (1 == myvar)
Тем путем Вы никогда не будете случайно делать чего-то вроде этого:
if (myvar = 1)
Вам не может сойти с рук это в C#, но он компилирует прекрасный в C и может быть настоящим дьяволом для отладки.
Лично я поместил код как это:
ret[i] != '\0' && ret[i] != '\r' && ret[i] != '\n'
в отдельную функцию (или даже определить макрос)
Лично, для в то время как конструкции:
Я предпочитаю следующее:
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;
}
}
- перейдите к концу строки (завершающийся 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;
}
}
Вот мой удар при осуществлении, не зная то, что находится в Главе 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;
}
В первую очередь:
международное основное (пустота)
Вы знаете параметры к основному (). Они - ничто. (Или 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 ().
обрезка () является слишком большой.
То, что я думаю, что Вам нужно, является функцией strlen-выхода (разрешение, и запишите этому интервал stringlength (символ константы *s)).
Затем Вам нужна функция, вызванная интервал scanback (символ константы *s, символ константы *соответствия, международный запуск), который запускается в запуске, снижается до z, пока символ, просканированный в s идентификаторе, содержавшемся в соответствиях, возвратите последний индекс, где соответствие найдено.
Затем Вам нужна функция, вызванная интервал scanfront (символ константы *s, символ константы *соответствия), который запускается в 0 и сканирует вперед, пока символ, просканированный в s, содержится в соответствиях, возвращая последний индекс, где соответствие найдено.
Затем Вам нужна функция, вызванная интервал charinstring (символ c, символ константы *s), который возвращается ненулевой, если c содержится в s, 0 иначе.
Необходимо смочь записать обрезку с точки зрения их.
Другой пример выполнения того же самого. Сделал некоторое незначительное нарушение при помощи 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;
}