首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >理解代码文件中的流重定向-从“`stdin`”读取

理解代码文件中的流重定向-从“`stdin`”读取
EN

Stack Overflow用户
提问于 2017-01-28 07:38:34
回答 1查看 826关注 0票数 1

此问题基于以下代码:http://nlp.stanford.edu/projects/glove/

下面的代码,行为与我所期望的一样。它从:stdin回显用户输入。

标准输入流是应用程序的默认数据源。在大多数系统中,默认情况下,它通常指向键盘。

键入文本并按enter,该文本回显返回到控制台。正常的,而且是预期的。

代码语言:javascript
运行
复制
// _CRT_SECURE_NO_WARNINGS:
#pragma warning(disable : 4996)

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

int main()
{

// Char as int:
int ch;

// File Pointer:
FILE *fid;

// Open the File: Stream
fid = fopen("<Path to simple text file>/text.txt", "r");

// Loop through Chars:
while (1)
{

// Check valid Stream:
if (fid == NULL)
{
printf("Stream Error: File was not opened!\n");
break;
}

// If EOF:
if (feof(fid))
{
break;
}

// Get C:
ch = fgetc(fid);

// Print C:
printf("%c", ch);
}

// Close the File:
fclose(fid);


// Open the File: Stream
fid = stdin;

// Loop through Chars:
while (1)
{

// Check valid Stream:
if (fid == NULL)
{
printf("Stream Error: File was not opened!\n");
break;
}

// If EOF:
if (feof(fid))
{
break;
}

// Get C:
ch = fgetc(fid);

// Print C:
printf("%c", ch);
}


int i = 0;

return i;
}

示例源代码: http://nlp.stanford.edu/projects/glove/ --特别来自coocur.c代码文件的第301行

在此代码中:

代码语言:javascript
运行
复制
fid = fopen(vocab_file,"r");
if(fid == NULL) {fprintf(stderr,"Unable to open vocab file %s.\n",vocab_file); return 1;}
while(fscanf(fid, format, str, &id) != EOF) hashinsert(vocab_hash, str, ++j); // Here id is not used: inserting vocab words into hash table with their frequency rank, j
fclose(fid);
vocab_size = j;
j = 0;
if(verbose > 1) fprintf(stderr, "loaded %lld words.\nBuilding lookup table...", vocab_size);

/* Build auxiliary lookup table used to index into bigram_table */
lookup = (long long *)calloc( vocab_size + 1, sizeof(long long) );
if (lookup == NULL) {
    fprintf(stderr, "Couldn't allocate memory!");
    return 1;
}
lookup[0] = 1;
for(a = 1; a <= vocab_size; a++) {
    if((lookup[a] = max_product / a) < vocab_size) lookup[a] += lookup[a-1];
    else lookup[a] = lookup[a-1] + vocab_size;
}
if(verbose > 1) fprintf(stderr, "table contains %lld elements.\n",lookup[a-1]);

/* Allocate memory for full array which will store all cooccurrence counts for words whose product of frequency ranks is less than max_product */
bigram_table = (real *)calloc( lookup[a-1] , sizeof(real) );
if (bigram_table == NULL) {
    fprintf(stderr, "Couldn't allocate memory!");
    return 1;
}

fid = stdin; // <<<--- STDIN Stream Redirect
sprintf(format,"%%%ds",MAX_STRING_LENGTH);
sprintf(filename,"%s_%04d.bin",file_head, fidcounter);
foverflow = fopen(filename,"w");
if(verbose > 1) fprintf(stderr,"Processing token: 0");

/* For each token in input stream, calculate a weighted cooccurrence sum within window_size */
while (1) {
    if(ind >= overflow_length - window_size) { // If overflow buffer is (almost) full, sort it and write it to temporary file
        qsort(cr, ind, sizeof(CREC), compare_crec);
        write_chunk(cr,ind,foverflow);
        fclose(foverflow);
        fidcounter++;
        sprintf(filename,"%s_%04d.bin",file_head,fidcounter);
        foverflow = fopen(filename,"w");
        ind = 0;
    }
    flag = get_word(str, fid); // <<<--- Reading from the Vocab, not STDIN
    if(feof(fid)) break;
    if(flag == 1) {j = 0; continue;} // Newline, reset line index (j)
    counter++;
    if((counter%100000) == 0) if(verbose > 1) fprintf(stderr,"\033[19G%lld",counter);
    htmp = hashsearch(vocab_hash, str); // <<<--- Using the str that was read in the function: 'get_word'
    if (htmp == NULL) continue; // Skip out-of-vocabulary words
    w2 = htmp->id; // Target word (frequency rank)
    for(k = j - 1; k >= ( (j > window_size) ? j - window_size : 0 ); k--) { // Iterate over all words to the left of target word, but not past beginning of line
        w1 = history[k % window_size]; // Context word (frequency rank)
        if ( w1 < max_product/w2 ) { // Product is small enough to store in a full array
            bigram_table[lookup[w1-1] + w2 - 2] += 1.0/((real)(j-k)); // Weight by inverse of distance between words
            if(symmetric > 0) bigram_table[lookup[w2-1] + w1 - 2] += 1.0/((real)(j-k)); // If symmetric context is used, exchange roles of w2 and w1 (ie look at right context too)
        }
        else { // Product is too big, data is likely to be sparse. Store these entries in a temporary buffer to be sorted, merged (accumulated), and written to file when it gets full.
            cr[ind].word1 = w1;
            cr[ind].word2 = w2;
            cr[ind].val = 1.0/((real)(j-k));
            ind++; // Keep track of how full temporary buffer is
            if(symmetric > 0) { // Symmetric context
                cr[ind].word1 = w2;
                cr[ind].word2 = w1;
                cr[ind].val = 1.0/((real)(j-k));
                ind++;
            }
        }
    }

我想知道,如何在方法中将一个单词分配给strflag = get_word(str, fid);,在流被更改为stdin之后,然后使用两行:htmp = hashsearch(vocab_hash, str);

这个代码在大语料库上进行了数百万次的迭代,用户不会坐在那里手动输入每个单词。

如果有人能在:fid = stdin;流更改之后解释这是如何发生的,我将非常感激。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2017-01-28 13:14:45

对一些人来说很简单,但对另一些人却不是这样..。

stdin是一个默认的输入流,因此在代码中可以使用stdin变量直接访问。所以当一个人看到,我现在有几次:

代码语言:javascript
运行
复制
FILE *fid;
fid = stdin;

stdin流已被重定向:如果此流不是默认的,则为“某处”。通常,在大多数机器上,默认的是键盘。

在线:301个fid = fopen(vocab_file,"r"); -- vocab文件成为流数据源,由fopen函数返回。文件将被读取和处理。

在线: 304该流已关闭:fclose(fid);

在线:将329个fid = stdin; stdin指定为fid的输入流。

从那里,没有流变化的迹象,但有分配给str,这是从一个文本文件,和方法:get_word分配str从语料库.

命令行输入的答案是:溢出文件临时流< corpus.txt > cooccurrences.bin

代码语言:javascript
运行
复制
./cooccur -verbose 2 -symmetric 0 -window-size 10 -vocab-file vocab.txt -memory 8.0 -overflow-file tempoverflow < corpus.txt > cooccurrences.bin

使用:cplusplus.com

标准输入流 标准输入流是应用程序的默认数据源。在大多数系统中,默认情况下,它通常指向键盘。 stdin可以用作任何函数的参数,该函数期望输入流(FILE*)作为它的参数之一,例如fget或fscanf。 虽然通常假定stdin的数据源将是键盘,但即使在常规控制台系统中也可能不是这样,因为在调用应用程序时,stdin通常可以在大多数操作系统上被重定向。例如,许多系统,包括DOS/Windows和大多数UNIX,都支持以下命令语法: 我的应用程序< example.txt 若要将文件example.txt的内容用作myapplication的主要数据源,而不是控制台键盘,请执行以下操作。 还可以使用freopen函数将stdin重定向到程序中的其他数据源。 如果stdin已知不引用交互设备,则流将被完全缓冲。否则,默认情况下,流是否缓冲取决于库(请参阅setvbuf)。

就这样,stdin流被命令行参数重定向:-overflow-file tempoverflow < corpus.txt

结果是:corpus.txtstdin流的重定向数据源!

同样值得注意的是,cooccurrences.binstdout流-小瓶线: 232 fout = stdout;的重定向数据源,并写入在线: 270 fwrite(&old, sizeof(CREC), 1, fout);

有关以下内容的更多信息:"标准输入输出重定向

注意:如果您想要运行这段代码,请记住将控制台应用程序设置为64位-它不会以其他方式分配内存!

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/41907459

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档