簡體   English   中英

C編程輸出文本文件

[英]C Programming output text file

嗨,我剛剛開始編程,並且有一個初學者的問題:我想更好地了解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()我有一個樹的全局節點和一個指向它的節點指針以用於其他功能

為了最方便地將trie寫入磁盤,如果您可以將整個 trie稱為數組,則將大有幫助。 即不要僅僅擁有導致單獨分配的root 所有內容都返回同一數組! 然后,這就像將節點從數組直接寫入磁盤一樣簡單,只要您不需要為其他實現轉換整數,否則就無需為其他實現轉換整數...並且您無需擔心差異在a+w之間。

使用單一分配還有其他好處:

  • 一種分配意味着一種免費,這意味着您的代碼將更快。 (實際上,無需分配,如下所示)
  • 緩存一致性; 單個分配可能會更好地作為一個條目而不是多個分配進行緩存。 這將以可移植的方式減少高速緩存未命中的次數,從而減少所需的非便攜式手動優化。 同樣,您的代碼將更快。
  • 實際有多少C標准函數在后台分配內存? 除了內存分配功能外,沒有其他功能…… 作為這些功能的用戶,這對您有什么好處? 如果您考慮一下,則可以編寫代碼malloc free ,因此調用者可以決定要使用哪種分配類型(自動存儲持續時間,靜態存儲持續時間, malloc / realloc ),類似於scanfstrcatsprintf等讓您選擇...這使測試變得更加容易 ,例如,您可以檢查我的PATRICIA trie測試代碼PATRICIA庫代碼,以查看我不需要使用mallocfree進行測試,這顯然使測試看起來更簡潔。 ..更不用說,在某些情況下, mallocfree不是最佳選擇!

最后一點特別有用,因為它允許調用者將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;
}

給定輸入文件:

elephant
rhinoceros
mouse

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應該仍然不是全局變量,但我尚未將其刪除。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM