【问题标题】:How to properly scan a line from input and write an output file如何正确扫描输入中的一行并写入输出文件
【发布时间】:2013-08-16 15:11:43
【问题描述】:

所以我有这个代码:

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

struct tree
{
    char data;
    struct tree *left;
    struct tree *right;
};


int findNode(char temp[], int x, int y, char val);
struct tree *insert(int data);


struct tree *binarytree(char inorder[], char preorder[], int x, int y)
{
    static int index = 0;

    if (x > y)
        return NULL;

    struct tree *new = insert(preorder[index++]);


    if (x == y)
        return new;

    int inIndex = findNode(inorder, x, y, new->data);

    new->left = binarytree(inorder, preorder, x, inIndex - 1);
    new->right = binarytree(inorder, preorder, inIndex + 1, y);

    return new;
}

int findNode(char temp[], int x, int y, char val)
{
    int i;

    for (i = x; i <= y; i++)
    {
        if (temp[i] == val)
            return i;
    }
}


struct tree *insert(int data)
{
    struct tree *tree = (struct tree *)malloc(sizeof(struct tree));
    tree->data = data;
    tree->left = NULL;
    tree->right = NULL;

    return (tree);
}

void postorder(struct tree *tree)
{
    FILE *ofp;
    ofp = fopen("201262480.txt", "w");

    if (tree == NULL)
    {
        return;
    }
    else
    {
        postorder(tree->left);
        postorder(tree->right);
        fprintf(ofp, "%d ", tree->data);
    }

}

int main()
{
    int i = 0, j;
    int temp[100];
    char c, buffer[20];
    FILE *fp;
    fp = fopen("input.txt", "r");

    if (fp != NULL)
    {
        while (1 == fscanf(fp, "%d ", &temp[i]))
        {
            i++;
        }

        char inorder[i / 2];
        char preorder[i / 2];

        for (j = 0; j < i / 2; j++)
        {
            preorder[j] = temp[j];
            inorder[j] = temp[j + (i / 2)];
        }

        int length = sizeof(inorder) / sizeof(inorder[0]);
        struct tree *root = binarytree(inorder, preorder, 0, length - 1);
        postorder(root);
    }
    else
    {
        printf("Cannot open File!\n");
    }

    return 0;
}

我有这样的输入文件:

1 2 3 4 5 6 7
3 2 4 1 6 5 7
***
1 1 2
1 1 2
***end of input***

它向上扫描直到 * 符号。它处理数字并打印输出文件。现在我有两个问题。

  1. 如何扫描下一行数字(1 1 2 和 1 1 2)并再次重复该过程。我可以在 while 循环中使用哪些参数?
  2. 输出文本文件只打印最后一个元素(这可以在 postorder 函数中找到)。它应该打印:3 4 2 6 7 5 1 但相反,它只打印 1。但是当我使用 printf 时,它会打印正确的输出。

注意:整个代码有效。无需编辑二叉树之类的东西,它只是扫描整数并将输出写入文件,这让我抓狂。

请帮忙!

【问题讨论】:

  • fclose(ofp);对于初学者。
  • 假设我想循环直到找到字符 *,那么代码是什么?
  • 如果这些是行,那么也许使用 fgets()。 fgets() 一次读取一行。然后解析该行(查找 *),如果有一个或多个则将其丢弃。
  • @JamesReynaldMase,这是一个令人筋疲力尽的answer with examples。 “文件结尾”或EOF 是在stdio.h 中定义的常量,但您也可以查找'a'、'\0' 或'*'。

标签: c file-io io printf


【解决方案1】:

使用 a 访问模式而不是 w:

w:为输出操作创建一个空文件。
每次调用 postorder() 函数时,都会覆盖 201262480.txt 文件。这就是为什么你的输出是1:postorder() 函数的最后一次调用会覆盖201262480.txt 并在那里写入1。

a:在文件末尾打开文件进行输出。
使用这种访​​问模式,您将获得预期的输出。

void postorder(struct tree *tree)
{
    FILE *ofp;
    ofp = fopen("201262480.txt", "a");  // I've changed "w" to "a". 
                                        // Now the output will be proper. 
    if (tree == NULL)
    {
    fclose(ofp);
    return;
    }
    else
    {
        postorder(tree->left);
        postorder(tree->right);
        fprintf(ofp, "%d ", tree->data);
    }
    fclose(ofp);
}

预期的输出:

3 4 2 6 7 5 1 

更新:

我已经修改了你的 postorder() 函数,所以它会在你每次运行程序时覆盖输出文件。

代码如下:

void postorder(struct tree *tree)
{
    unsigned int pointerValue = 0;  
    static int overwriteFile = 0; // The file hasn't been overwritten yet.
    FILE *ofp = NULL;
    ofp = fopen("201262480.txt", "a");

    fseek(ofp, 0L, SEEK_END);       // Moving the pointer to the end of file.
    pointerValue = ftell(ofp);          // Checking if it is not `0` (the file contains some data)
    if (pointerValue != 0) {
        if (overwriteFile == 0) {
            fclose(ofp);
            ofp = fopen("201262480.txt", "w");  // "w": Create an empty file for output operations.
            fclose(ofp);
            ofp = fopen("201262480.txt", "a");  // "a": Open file for output at the end of a file.   
            overwriteFile = 1;  // The file was overwritten. 
                                // So when you call this function next time, 
                                // it will not overwrite the file. 
                                // It only does it once when you run the program.
        }
    }

    if (tree == NULL)
    {
        return;
    }
    else
    {
        postorder(tree->left);
        postorder(tree->right);
        fprintf(ofp, "%d ", tree->data);
    }
    fclose(ofp);
}

【讨论】:

  • 谢谢@Yulian。但是如何在每次运行程序时覆盖输出?
猜你喜欢
  • 2016-08-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-08-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多