Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/file/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C编程输出文本文件_C_File_Output - Fatal编程技术网

C编程输出文本文件

C编程输出文本文件,c,file,output,C,File,Output,嗨,我刚开始编程,有一个初学者问题: 我想更好地理解fprint()函数是如何工作的,因为有时当我用它创建文本文件时,我意识到有各种类型的文件,例如(只读、追加和写入)。当我想在我用循环创建的文件上写入时,添加内容的顺序似乎会改变 file = fopen(name,"a+"); 如果是,我不能在循环中添加所有内容 file = fopen(name,"w"); 那么,创建文本文件最方便的方法是什么? 谢谢大家! 假设我想从一个trie树中写入所有单词,文本文件中的顺序将不同于仅用print

嗨,我刚开始编程,有一个初学者问题: 我想更好地理解fprint()函数是如何工作的,因为有时当我用它创建文本文件时,我意识到有各种类型的文件,例如(只读、追加和写入)。当我想在我用循环创建的文件上写入时,添加内容的顺序似乎会改变

file = fopen(name,"a+");
如果是,我不能在循环中添加所有内容

file = fopen(name,"w");
那么,创建文本文件最方便的方法是什么? 谢谢大家!

假设我想从一个trie树中写入所有单词,文本文件中的顺序将不同于仅用print()替换fprint() 我有一个用于树的全局节点和一个用于其他函数的指向它的节点指针

struct node *root = (struct node *)malloc(sizeof(struct node));
其功能是:

void printResult(struct node* r){
struct node *p = r;
FILE *file;
sprintf(name, "man%d.txt", num);
file = fopen(name,"a+");
int i=0;
int temp;
while(i!=26){
 if(p->child[i]==NULL){
  i++;
  continue;}
 if(p->child[i]->isword==1&&p->child[i]->leaf==1){
  word[k]=i+'a';
  word[k+1]='\0';
  fprintf(file,"%s", word);fprintf(file,"%s"," " );
  fprintf(file,"%d", p->child[i]->occurrence);fprintf(file,"%s"," " );
  fprintf(file,"%d\n", p->child[i]->super);
  i++;
  continue;} 
 if(p->child[i]->isword==0){
  word[k]=i+'a';
  temp=k;
  k++;
  p=p->child[i];
  printResult(p);
  k=temp;
  p=p->parent;
  }
 if(p->child[i]->isword==1&&p->child[i]->leaf==0){
  word[k]=i+'a';
  word[k+1]='\0';
  temp=k;
  k++;
  p->child[i]->isword=0;
  fprintf(file,"%s", word);fprintf(file,"%s"," " );
  fprintf(file,"%d", p->child[i]->occurrence);fprintf(file,"%s"," " );
  fprintf(file,"%d\n", p->child[i]->super);
  p=p->child[i];
  printResult(p);
  k=temp;
  p=p->parent;
}
 i++;
}fclose(file);
}
以及节点:

struct node{   
struct node * parent;
int noempty;
int isword;
int super;
int occurrence;
int leaf;
struct node * child[26];
};
最后是插入函数

struct node* insert(struct node *root,char *c){
int i=0;
struct node *temp=root;
int l=length(c);
while(i!=l){
int index=c[i]-'a';
if(temp->child[index]==NULL){
//New Node
struct node *n=(struct node *)malloc(sizeof(struct node)); 
n->parent=temp;
temp->child[index]=n;
temp->noempty=1;}
//Node Exist
if(i!=l&&temp->leaf==1){temp->leaf=0;}
temp=temp->child[index];
i++;}
if(temp->noempty==0){
temp->leaf=1;}
temp->isword=1;
return root;
 };
创建文本文件最方便的方法是什么

我想写一个trie树中的所有单词,文本文件中的顺序不同于用print()替换fprint(),我有一个树的全局节点和一个指向其他函数的节点指针

struct node *root = (struct node *)malloc(sizeof(struct node));
为了最方便地将一个trie写入磁盘,如果您可以将整个trie称为一个数组,这将非常有帮助。i、 e.不要只有一个导致单独分配的
;让所有内容都返回到同一数组!然后,只要将节点直接从阵列写入磁盘即可,前提是您不需要为其他实现转换整数,或者为其他实现转换整数。。。您不必担心
a+
w
之间的差异

使用单一分配还有其他好处:

  • 一次分配意味着一次免费,这意味着您的代码将更快。(实际上,不需要分配,如下所示)
  • 缓存一致性;单个分配很可能作为一个条目缓存,而不是作为多个分配缓存。这将以可移植的方式减少缓存未命中,从而减少所需的非可移植手动优化。同样,您的代码将更快
  • 有多少C标准函数在幕后实际分配内存?没有,当然除了内存分配函数作为这些函数的用户,这对您有什么好处?如果您考虑一下,您可以免费编写代码
    malloc
    ,因此调用方决定使用哪种类型的分配(自动存储持续时间、静态存储持续时间、
    malloc
    /
    realloc
    )类似于
    scanf
    strcat
    sprintf
    等允许您选择。。。这使得测试变得更加容易,例如,您可以检查并查看我不需要使用
    malloc
    free
    进行测试,这使得测试看起来更干净。。。更不用说,
    malloc
    free
    并不是最好的选择
最后一点特别有用,因为它允许调用方将数据作为扩展存储在trie节点中,而不是像您所做的那样指向外部数据。这使得编写文件变得更加容易,因为从技术上讲,如果所有信息都在那里,您可以一次将整个数组转储到文件中。值得思考的是:您认为使用RAM作为缓存级别的基于磁盘的trie可行吗?

在中讨论后,我们得出了以下结论:

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

#define length(x) strlen(x)

struct node
{
    struct node *parent;
    int noempty;
    int isword;
    int super;
    int occurrence;
    int leaf;
    struct node *child[26];
};

static struct node *root = 0;
static char word[1024];
static int k = 0;

static
void printResult(FILE * file, struct node *r)
{
    struct node *p = r;
    int i = 0;
    int temp;
    while (i != 26)
    {
        if (p->child[i] == NULL)
        {
            i++;
            continue;
        }
        if (p->child[i]->isword == 1 && p->child[i]->leaf == 1)
        {
            word[k] = i + 'a';
            word[k + 1] = '\0';
            fprintf(file, "%s", word);
            fprintf(file, "%s", " ");
            fprintf(file, "%d", p->child[i]->occurrence);
            fprintf(file, "%s", " ");
            fprintf(file, "%d\n", p->child[i]->super);
            i++;
            continue;
        }
        if (p->child[i]->isword == 0)
        {
            word[k] = i + 'a';
            temp = k;
            k++;
            p = p->child[i];
            printResult(file, p);
            k = temp;
            p = p->parent;
        }
        if (p->child[i]->isword == 1 && p->child[i]->leaf == 0)
        {
            word[k] = i + 'a';
            word[k + 1] = '\0';
            temp = k;
            k++;
            p->child[i]->isword = 0;
            fprintf(file, "%s", word);
            fprintf(file, "%s", " ");
            fprintf(file, "%d", p->child[i]->occurrence);
            fprintf(file, "%s", " ");
            fprintf(file, "%d\n", p->child[i]->super);
            p = p->child[i];
            printResult(file, p);
            k = temp;
            p = p->parent;
        }
        i++;
    }
}

static
struct node *insert(struct node *root, char *c)
{
    int i = 0;
    struct node *temp = root;
    int l = length(c);
    while (i != l)
    {
        int index = c[i] - 'a';
        if (temp->child[index] == NULL)
        {
// New Node
            struct node *n = (struct node *)malloc(sizeof(struct node));
            n->parent = temp;
            temp->child[index] = n;
            temp->noempty = 1;
        }
// Node Exist
        if (i != l && temp->leaf == 1)
        {
            temp->leaf = 0;
        }
        temp = temp->child[index];
        i++;
    }
    if (temp->noempty == 0)
    {
        temp->leaf = 1;
    }
    temp->isword = 1;
    return root;
}

int main(void)
{
    root = (struct node *)malloc(sizeof(struct node));
    memset(root, '\0', sizeof(*root));

    char line[1024];

    while (fgets(line, sizeof(line), stdin) != 0)
    {
        line[strcspn(line, "\n")] = '\0';
        printf("[%s]\n", line);
        root = insert(root, line);
    }

    FILE *file;
    char name[1024];
    int num = 0;
    sprintf(name, "man%d.txt", num);
    file = fopen(name, "w");

    printResult(file, root);

    fclose(file);

    return 0;
}
man0.txt
中的输出为:

elephant 0 0
mouse 0 0
rhinoceros 0 0
这并不是非常令人兴奋;每个单词都从它自己的节点开始

同样,给定输入:

boo
book
booking
john
tex
text
结果是:

boo 0 0
book 0 0
booking 0 0
john 0 0
tex 0 0
text 0 0
任务似乎指定了
printResults()
不能接受任何参数。这使得递归函数的使用变得异常困难。显示的代码将一个节点传递给函数,以及要写入的文件流。它使用
“w”
打开文件,而不是
“a+”
。由于从未读取该文件,因此不需要
+
;使用
“a”
而不是
“w”
意味着信息是从上一次运行添加到文件中的


有太多的全球性的;当我开始的时候还有很多
k
不应该仍然是全局的,但我还没有删除它。

我不理解你的问题。如果以“a”模式打开文件,则所有写入操作都将转到文件末尾。如果以“w”模式打开,则在执行写入操作时,所有写入操作都将转到当前位置的任何位置。如果以“r”模式打开,则写入将失败。创建文件的“最方便”方式取决于您希望写入的行为方式。可能fopen(name,“w”)
是最方便的。@williampersell如果我想创建一个文件并写入文件顶部,该怎么办?我正在尝试编写一个函数,当我使用print()时,顺序是正确的,但是当我使用fprint()以相同的顺序在文件上写入它们时,它不起作用,而且顺序看起来非常随机。你说的“写入文件顶部”是什么意思?如果您的意思是“重复更改第一行”,那么这是可行的(但不适用于
“a”
模式)。如果您的意思是“在文件的开头插入一行(将前面的行向下推到文件中)”,那么这是不合理的;它很快变得非常昂贵。很抱歉,我在评论中犯了一个错误,我的意思是逐行编写内容-五个调用-
fprintf(file,“%s”,word);fprintf(文件“%s”和“);fprintf(文件“%d”,p->child[i]->出现);fprintf(文件“%s”和“);fprintf(文件“%d\n”,p->child[i]->super)-应该是一个调用:`fprintf(文件,'%s%d%s\n',word,p->child[i]->occurrence,p->child[i]->super)`文件函数通常为缓冲区等分配内存。当然,分配的内存是由
fclose()
在没有其他us的情况下释放的