正在清除文本文件

时间:2014-01-23 16:49:49

标签: c linux file-io

我有一个Linux C程序,它将配置参数存储在文本文件中。我使用

从文本文件中读取

FILE *file = fopen(filename, "r"):

使用以下代码

写入文件

FILE *file = fopen(filename, "w"):

我遇到问题,文本文件被清除,下次我来读它时它是空白的。 据我所知,当文件被打开以进行写入时,它会被覆盖,我的程序在读取文件后将其内容存储起来并将其写回。 它在主要部分正确地写出来,但偶尔我会发现文本文件是空白的。

我最初的想法是,这可能是因为程序被不安全地停止,在写入文件的过程中,将其留空或者有2个程序运行实例,并且打开它进行写入,另一个读取它,意思是它会读取一个空白文件,然后在写出来时用空白文件覆盖它。 经过一些测试后,情况似乎并非如此。

这让我不确定导致文本文件被清除的原因。 有没有人有任何想法?

见下面的代码

char text_lines[200][54]; /* global variable */

void read_in_text_file()
{

  /* this sub reads in the text file */

 //printf("read in file\n");

    /* declares the variables */
    char line[128];
    int counter = 0;
    int length;

/* open a text file and read it in line by line, storing each line in a variable. also returning a value for the number of lines in each section */

    static const char filename[] = "config.txt";
    FILE *file = fopen(filename,"r"); /* opens the config file */
if (file==NULL){ /* checks if the file has successfully opened */
  perror ("Error opening file"); /* displays error message on stderr - that returns reason file did not open */
  printf("Error opening file\n"); /* tells the user that the file has not opened */
  exit(0); /* exits the program if the text file can not be read in */
}
else{

  //printf("the file is open\n");

  while ( fgets ( line, sizeof line, file ) != NULL) /* reads each line of the text file */
  {
sprintf(text_lines[counter],"%s",line); /* puts the line into a variable */

length = zstrlen(text_lines[counter]); /* calculates the length of the text not including \r or \n characters */
if(text_lines[counter][length-1] == '\n') /* checks if the last character is \n (a new line character) */
{
 text_lines[counter][length-1] = '\0';  /* removes this new line character and replaces it with end of line identifier */
}

  counter = counter + 1; /* uses a counter for each line */

  } /* end of while loop */
        number_of_lines = counter; /* puts the number of lines into a integer variable */

  fclose(file); /* closes the file */
}
} /* end of sub for reading in the text file */

/* some changes may be made to the config before it is printed to the file again */

void print_to_text_file()
{

  pthread_mutex_lock(&lock); /* block until thread has ownership */

  /* sub for printing all the lines in the text_lines variable to the text file "config.txt" */
  int counter;
  static const char filename[] = "config.txt";
  FILE *file = fopen(filename,"w"); /* opens the config.txt file, with write privileges */
  if (file==NULL){ /* checks if the file has successfully opened */
      perror ("Error opening file"); /* displays error message on stderr - that returns reason file did not open */
      printf("Error opening file\n"); /* tells the user that the file has not opened */
    }
  else{
    //printf("the file is open\n"); /* prints to the terminal screen the file has opened */
for (counter = 0; counter < number_of_lines; counter++) /* uses a for loop to scroll through all text lines */
{
// printf("%s\n",text_lines[counter]);
  fprintf(file, "%s\n",text_lines[counter]); /* prints current text line to the file */
}

      fclose(file); /* closes the file */
    }

  pthread_mutex_unlock(&lock); /* release blocking on thread */

} /* end of print text to file sub */

1 个答案:

答案 0 :(得分:3)

首先,您应该知道当您使用fopen和模式w打开文件时,文件会立即被截断为零字节(删除其内容)。您可以使用w+wa来阻止此操作。

其次,当您完成文件时,可能会遗漏fclose()来关闭文件。虽然程序退出时,通常会关闭所有文件。但是,如果不关闭该文件,则对其所做的更改可能不会提交到磁盘。

由于您更新了问题以包含一些代码,我可以说您的程序不安全,并且如果文件包含超过200行,则可能会超出text_lines缓冲区。如果您可以提供一个可以编译和运行的实际完整但最小的测试程序,它将帮助您下次获得更多答案。

这是一个可以编译和运行的实际程序。它读入config.txt行,将所有字符转换为大写字母,然后将这些行写回文件。我删除了你的pthread互斥函数调用,因为在这个测试程序中没有必要(没有多线程)。

#include <ctype.h>      /* toupper */
#include <stdio.h>      /* fopen, fclose, fgets, perror */
#include <stdlib.h>     /* exit */
#include <string.h>     /* strlen */

/* Constants */

/* Maximum number of lines to read */
#define TEXT_LINES_CAPACITY 54
/* Maximum length of a line including EOL and NUL */
#define MAX_LINE_LEN 200

/* Global variables */
char text_lines[TEXT_LINES_CAPACITY][MAX_LINE_LEN];  /* text of lines */
int number_of_lines;  /* number of lines in text_lines */

/* Function declarations */
void capitalize_string(char* s);
void strip_eol(char* s);
void read_in_text_file(void);
void print_to_text_file(void);

/* Function definitions */

int main()
{
    int i;

    /* Read in the contents of the file. */
    read_in_text_file();

    /* Modify it by capitalizing the text. */
    for (i = 0; i < number_of_lines; ++i)
    {
        capitalize_string(text_lines[i]);
    }

    /* Write out the modified contents to the same file. */
    print_to_text_file();

    return 0;
}

void capitalize_string(char* s)
{
    while (*s != 0)
    {
        *s = toupper(*s);
        ++s;
    }
}

/* Open a text file and read it in line by line.  The lines are stored in the
 * global variable text_lines and the number of lines in number_of_lines. */
void read_in_text_file(void)
{
    static const char filename[] = "config.txt";
    FILE *file = fopen(filename,"r"); /* opens the config file */

    if (file == NULL)
    {
        /* Print error message after the file name. */
        perror(filename);
        exit(1);  /* Exit with failure code (nonzero) */
    }
    else
    {
        /* Read each line of the text file. */
        while (number_of_lines < TEXT_LINES_CAPACITY &&
                fgets(text_lines[number_of_lines], MAX_LINE_LEN, file) != NULL)
        {
            strip_eol(text_lines[number_of_lines]);
            ++number_of_lines;
        }

        fclose(file);
    }
}

/* Remove LF and/or CR characters from the end of the string. */
void strip_eol(char* s)
{
    /* Loop while the string ends with a CR or LF character. */
    while (strlen(s) > 0 &&
            (s[strlen(s) - 1] == '\n' ||
             s[strlen(s) - 1] == '\r'))
    {
        /* Erase the last character. */
        s[strlen(s) - 1] = '\0';
    }
}

/* Write all the lines of text_lines to the text file "config.txt" */
void print_to_text_file(void)
{
    static const char filename[] = "config.txt";
    /* open the config.txt file, with write privileges */
    FILE *file = fopen(filename,"w");

    if (file == NULL)
    {
        /* Print error message after the file name. */
        perror(filename);
    }
    else
    {
        int i;

        /* Iterate over all text lines. */
        for (i = 0; i < number_of_lines; i++)
        {
            fprintf(file, "%s\n", text_lines[i]); /* prints current text line to the file */
        }

        fclose(file); /* closes the file */
    }
}