C fgets может быть подключен коаксиальным кабелем для работы со строкой *не* из файла?

А именно, пример кода здесь работает отлично, но только когда строка хранится в файле.

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

Или возможно существует функциональный эквивалент fgets, который может использоваться на строках?

Какие-либо предложения?Спасибо!

8
задан Community 23 May 2017 в 12:24
поделиться

6 ответов

В духе взлома быстрых ответов, вот «Wgets», которые я только что написал. Он пытается эмулировать FGES, но со строковым входом.

Редактировать Исправлена ​​ошибка, которая указывала Монте (спасибо). Безумительно выводя утилиту, полагая, что по крайней мере 15 других людей с той же идеей отчаянно делают то же самое, не приводят к хорошо проверенному коду. Плохо меня. Оригинальная версия была включена в Newline символ в последующем вызове.

char *sgets( char * str, int num, char **input )
{
    char *next = *input;
    int  numread = 0;

    while ( numread + 1 < num && *next ) {
        int isnewline = ( *next == '\n' );
        *str++ = *next++;
        numread++;
        // newline terminates the line but is included
        if ( isnewline )
            break;
    }

    if ( numread == 0 )
        return NULL;  // "eof"

    // must have hit the null terminator or end of line
    *str = '\0';  // null terminate this tring
    // set up input for next call
    *input = next;
    return str;
}


int main( int argc, char* argv[] )
{
    // quick and dirty test
    char *str = "abc\ndefghitjklksd\na\n12345\n12345\n123456\nabc\n\n";
    char buf[5];

    while ( sgets( buf, sizeof( buf ), &str ))
        printf( "'%s'\n", buf );
}
9
ответ дан 5 December 2019 в 07:58
поделиться

SSCANF должен сделать это. Конечно, семантика разные.

3
ответ дан 5 December 2019 в 07:58
поделиться

I второй SpringMVC. Это очень легко понять, и код очень смысловый, если вы используете аннотации . Как и те рекламные ролики Budweiser ... Сервлеты слишком легкие... Стойки слишком тяжелые.

Хотелось бы, чтобы на Яве были строительные леса. Это может с Грайлс, но это еще одна основа для встраивания в рамки.

-121--3096237-

По словам Брэда Абрамса, почти никогда: link

Нет, нет, нет никакой выгоды от обертывания BufferedStream вокруг FileStream. Мы скопировали логику буферизации BufferedStream в FileStream около 4 лет назад, чтобы способствовать улучшению дефолта производительность... На самом деле, я не думаю, что есть какие-либо потоки в .NET Framework, которые требуют его, но он может потребоваться пользовательским Потоковые реализации, если они не выполняют буферизацию по умолчанию.

-121--1073394-

Используйте трубу, а затем откройте трубу с помощью fdopen , чтобы получить FILE * , затем прочитайте это.


#include <stdio.h>

int main (int argc, char *argv[])
{
    int pipes[2];
    FILE *write;
    FILE *read;
    char buffer[1000];

    pipe (pipes);

    read = fdopen (pipes[0], "r");
    write = fdopen (pipes[1], "w");
    fputs ("My\nlong\nstring\nin\nmany\nlines\n", write);
    fclose (write);

    while (fgets (buffer, sizeof(buffer), read) != NULL)
    {
        printf ("Found a line: %s", buffer);
    }

    fclose (read);

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

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

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

typedef struct StringStream StringStream;

struct StringStream {
    const char *data;
    const char *position;
};

StringStream *
stringstream_new(const char *data)
{
    StringStream *self = malloc(sizeof (StringStream));

    self->data = self->position = data;

    return self;
}

void
stringstream_delete(StringStream *self)
{
    free(self);
}

char *
stringstream_gets(char *s, int n, StringStream *self)
{
    const char * eol;
    int i, len;

    if (NULL == self->position || '\0' == *self->position)
        return NULL;

    eol = strchr(self->position, '\n');

    if (eol) {
        len = eol - self->position + 1;
        len = len <= n ? len : n - 1;

        for (i = 0; i < len; ++i)
            s[i] = *self->position++;

    } else {
        for (i = 0; *self->position && i < n; ++i)
            s[i] = *self->position++;
            if ('\0' == *self->position)
                self->position = NULL;
            else
                ++self->position;
    }

    s[i] = '\0';

    return s;
}

int
main(int argc, char * argv[])
{
    static const int LEN = 100;
    static const char TEST_STRING[] =
        "line 0\n"
        "line 1\n"
        "line 2\n"
        "line 3\n"
        "line 4\n"
        "line 5\n"
        "line 6\n"
        "line 7\n"
        "line 8\n"
        "line 9\n";

    StringStream *stream;
    char buf[LEN];

    stream = stringstream_new(TEST_STRING);

    while (stringstream_gets(buf, LEN, stream))
        printf("gets: %s\n", buf);

    stringstream_delete(stream);

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

strip _ тэги () удаляет HTML из значения переменной. Второй параметр полезен, если требуется создать исключения и оставить определенные тэги, например, p aragreh тэга.

$text = '<p>Paragraph.</p> <!-- boo --> <a href="#">Other text</a>';
echo strip_tags($text); // Paragraph. Other text
echo strip_tags($text, '<p><a>'); // <p>Paragraph.</p> <a href="#">Other text</a>

phpQuery

Если вы хотите остаться в стороне от регулярных выражений, можно использовать phpQuery для обработки значения, а затем использовать селекторы и методы в стиле jQuery для получения значения:

// Bring in phpQuery
require("phpQuery-onefile.php");
// Load up our HTML
phpQuery::newDocumentHTML("<a href='http://sampsonresume.com/'>Homepage</a>");
// Print the HREF attribute of the first Anchor
print pq("a:first")->attr("href"); // http://sampsonresume.com/

Regex

Для поиска URL-адреса можно использовать следующее:

$var = "<a href='http://sampsonresume.com/'>Homepage</a>";
preg_match("(https?://([-\w\.]+)+(:\d+)?(/([\w/_\.]*(\?\S+)?)?)?)",$var,$match);
print $match[0]; // http://sampsonresume.com/
-121--4690954-

Проход 1.)

<?xml version="1.0" encoding="UTF-8"?>
  <xsl:stylesheet
   version="1.0"
   xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="xml" indent="yes" encoding="UTF-8"/>

  <xsl:template match="/">
    <xsl:apply-templates />
  </xsl:template>

    <xsl:template match="Detail">
        <Detail>
            <xsl:copy-of select="@*"/>
        <xsl:value-of select="." disable-output-escaping="yes" />
        </Detail>
    </xsl:template>

</xsl:stylesheet>

Произведет:

<?xml version="1.0" encoding="UTF-8"?>
<Detail uid="6"> 
    <div class="heading">welcome to my page</div>
    <div class="paragraph">this is paraph</div>
</Detail>

Pass 2.)

<?xml version="1.0" encoding="UTF-8"?>
  <xsl:stylesheet
   version="1.0"
   xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="xml" indent="yes" encoding="UTF-8"/>

  <xsl:template match="/">
    <xsl:apply-templates />
  </xsl:template>

    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*| node()" />
        </xsl:copy>
    </xsl:template>

    <xsl:template match="div[@class='heading']">
        <h1><xsl:value-of select="."/></h1>
    </xsl:template>

    <xsl:template match="div[@class='paragraph']">
        <p><xsl:value-of select="."/></p>
    </xsl:template>

</xsl:stylesheet>

Производит:

<?xml version="1.0" encoding="UTF-8"?>
<Detail uid="6">
<h1>welcome to my page</h1>
<p>this is paraph</p>
</Detail>
-121--3632201-

Стандартная библиотека C не обеспечивает эту функциональность.

Однако безопасная/быстрая библиотека ввода-вывода AT & T позволяет использовать потоки памяти, а также предоставляет код оболочки для использования файлового API с их расширениями. Последнее обновление от февраля 2005 года, так что либо они наконец-то отработали все ошибки, либо они больше не могут позволить себе поддерживать его сейчас, когда Люк Уилсон находится в зарплате : - (

Пакет можно скачать здесь .

4
ответ дан 5 December 2019 в 07:58
поделиться

Если строка Уже в памяти вы могли бы оставлять в номинальные слова (либо с STRTOK , если вы в порядке с мутацией строки, и если не нужно беспокоиться о повторной заводе или вручную, используя вручную Strchr и копирование на отдельный буфер самостоятельно).

Вы не получите не зависящую от платформы Newline Conversion, что функции Stdio обычно дают вам, поэтому потребуется некоторая дополнительная забота, если ваши строки в использовании памяти, скажем, Terminators Line CRLF.

2
ответ дан 5 December 2019 в 07:58
поделиться
Другие вопросы по тегам:

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