簡體   English   中英

如何從文件中讀取數據然后對其進行編輯並將其打印在同一個文件中?

[英]how can i read data from a file then edit it and print it in the same file?

我要做的是從文件中讀取此文本:

明天,明天,明天, 每天都以這種微小的步伐爬行, 直到記錄時間的最后一個音節; 我們所有的昨天都照亮了傻瓜通往塵土飛揚的死亡之路。 出來,出來,短暫的燭光,生命不過是一個行走的影子。 一個可憐的演奏者在舞台上大搖大擺,然后就再也聽不見了,這是一個白痴講述的故事。 充滿喧囂和憤怒 什么都沒有。

並將其全部更改為大寫字母。

如果我從一個文件中讀取文本並打印到另一個文件,我可以做到這一點。

#include <stdio.h>
#include <ctype.h>
int main() {
    FILE* input_file = fopen("some_text.txt", "a+");

    char c = fgetc(input_file);
    int charc = 0;
    int alpha = 0;
    while(1){
        if(isalpha(c)){
            alpha = alpha + 1;
        }
        charc = charc + 1;

        fprintf(input_file,"%c",toupper(c));
        c = fgetc(input_file);

        if(feof(input_file)){
            break;
        }
    }
    fprintf(input_file,"\nTotal Characters: %d, Total alphabetical characters: %d",charc,alpha);

    fclose(input_file);

    return 0;
}

如果您只是想將文件中的所有字符轉換為大寫並將結果寫回同一個文件,直接的方法是打開文件進行讀取,獲取文件的長度並分配一個緩沖區來保存整個文件並將整個文件讀入緩沖區,然后關閉文件。 然后遍歷緩沖區中的每個字符,對每個字符調用toupper()並將緩沖區轉換為全部大寫。 然后再次打開文件進行寫入,這將截斷文件,然后將整個緩沖區寫回文件,關閉文件並在完成后釋放緩沖區。

將要轉換的文件名作為第一個參數的簡短示例可能是:

"r" (讀取)模式打開文件

...
int main (int argc, char **argv) {

    char *filebuf = NULL;
    long fplen = 0;
    FILE *fp = NULL;

    if (argc < 2) { /* validate argument given for filename */
        fprintf (stderr, "usage: %s filename\n", argv[0]);
        return 1;
    }

    if (!(fp = fopen (argv[1], "r"))) { /* open/validate file open for read */
        perror ("fopen-read");
        return 1;
    }

確定文件長度

    fseek (fp, 0, SEEK_END);            /* seek end of file */
    if ((fplen = ftell (fp)) == -1) {   /* get file length */
        perror ("ftell-length");
        return 1;
    }
    fseek (fp, 0, SEEK_SET);            /* seek beginning */

filebuf分配存儲

    /* allocate memory for file */
    if (!(filebuf = malloc (fplen * sizeof *filebuf))) {
        perror ("malloc-filebuf");
        return 1;
    }

將整個文件讀入filebuf並關閉文件

    /* read file into filebuf */
    if (fread (filebuf, 1, fplen, fp) != (size_t)fplen) {
        perror ("fread-filebuf");
        return 1;
    }
    fclose (fp);                        /* close file after read */

filebuf轉換為大寫

    for (long i = 0; i < fplen; i++)    /* convert all chars toupper */
        filebuf[i] = toupper(filebuf[i]);

打開文件以寫入"w"模式filebuf寫入文件並關閉

    if (!(fp = fopen (argv[1], "w"))) { /* open/validate file open for write */
        perror ("fopen-write");
        return 1;
    }
    /* write filebuf to file */
    if (fwrite (filebuf, 1, fplen, fp) != (size_t)fplen) {
        perror ("fwrite-filebuf");
        return 1;
    }

    if (fclose (fp) == EOF)             /* validate close-after-write */
        perror ("fclose_after-write");

注意:您始終驗證寫后關閉以捕獲與刷新 ZF7B44CFFAFD5C52223D5498196C8A2E7BZ 相關的任何錯誤,這些錯誤不會在您對fwrite的驗證中捕獲)

免費filebuf Memory

    free (filebuf);

簡而言之就是這樣。 總而言之,您可以這樣做:

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

int main (int argc, char **argv) {

    char *filebuf = NULL;
    long fplen = 0;
    FILE *fp = NULL;

    if (argc < 2) { /* validate argument given for filename */
        fprintf (stderr, "usage: %s filename\n", argv[0]);
        return 1;
    }

    if (!(fp = fopen (argv[1], "r"))) { /* open/validate file open for read */
        perror ("fopen-read");
        return 1;
    }

    fseek (fp, 0, SEEK_END);            /* seek end of file */
    if ((fplen = ftell (fp)) == -1) {   /* get file length */
        perror ("ftell-length");
        return 1;
    }
    fseek (fp, 0, SEEK_SET);            /* seek beginning */

    /* allocate memory for file */
    if (!(filebuf = malloc (fplen * sizeof *filebuf))) {
        perror ("malloc-filebuf");
        return 1;
    }
    /* read file into filebuf */
    if (fread (filebuf, 1, fplen, fp) != (size_t)fplen) {
        perror ("fread-filebuf");
        return 1;
    }
    fclose (fp);                        /* close file after read */

    for (long i = 0; i < fplen; i++)    /* convert all chars toupper */
        filebuf[i] = toupper(filebuf[i]);

    if (!(fp = fopen (argv[1], "w"))) { /* open/validate file open for write */
        perror ("fopen-write");
        return 1;
    }
    /* write filebuf to file */
    if (fwrite (filebuf, 1, fplen, fp) != (size_t)fplen) {
        perror ("fwrite-filebuf");
        return 1;
    }

    if (fclose (fp) == EOF)             /* validate close-after-write */
        perror ("fclose_after-write");

    free (filebuf);
}

示例輸入文件

$ cat dat/cj2upper.txt
This is a tale
Of Captain Jack Sparrow
A Pirate So Brave
On the Seven Seas.

示例使用

$ ./bin/fread_file_toupper dat/cj2upper.txt

生成的 Output 文件

$ cat dat/cj2upper.txt
THIS IS A TALE
OF CAPTAIN JACK SPARROW
A PIRATE SO BRAVE
ON THE SEVEN SEAS.

看看事情,如果你有問題,請告訴我。 有不止一種方法可以做到這一點,但這可能是更直接的途徑之一。

幾乎是正確的,這里有一些改變使它工作首先以二進制模式打開文件,這允許您使用 fseek 移動文件。 rb+ 表示您可以讀/寫文件。 如果文件不存在,則添加一些錯誤處理,始終進行錯誤處理。 當您寫回磁盤時,請確保將其刷新到磁盤,因為 fgetc 等人在緩沖區上工作。 在這種情況下 fputc 更好,因為無論如何你只寫一個字符。

#include <stdio.h>
#include <ctype.h>
int main() 
{
  char filename[] = "some_text.txt";
  FILE* input_file = fopen(filename, "rb+"); // open in binary mode
  if ( input_file == NULL ) // some error handling
  {
    perror(filename);
    return -1;
  }

  int c = fgetc(input_file); // return value is int
  int charc = 0;
  int alpha = 0;

  do
  {
    if(isalpha(c))
    {
      alpha = alpha + 1;
    }
    charc = charc + 1;

    // if alpha, then go back one character and rewrite it
    if(isalpha(c)) 
    {
      fseek(input_file, -1, SEEK_CUR);
      fputc(toupper(c),input_file); // use fputc instead of fprintf
      fflush(input_file);
    }
    // read next
    c = fgetc(input_file);
  }
  while (c != EOF);

  // at end of file, add some more
  fprintf(input_file,"\nTotal Characters: %d, Total alphabetical characters: %d",charc,alpha);

  fclose(input_file);
  return 0;
}

出於性能原因,假設大多數字符都需要轉換,利用 STDIO 是有意義的,它將利用應用程序級緩沖

示例消除了可讀性的錯誤檢查。

main(...)
{
   // Open file
   FILE *fp = ... ;
   const int BUFFER_SIZE = 1024 ;
   char buff[BUFFER_SIZE] ;

   while ( 1 ) {
       // Read
       long loc = ftell(fp) ;
       n = fread(buff, 1, sizeof(buff), fp) ;
       if ( n <= 0 ) break ;

       // Convert
       int do_update = 0 ;
       for (int i=0 ; i<n; i++ ) {
           if ( islower(buff[i] ) {
              buff[i] = toupper(buff[i]) 
              do_update = 1 ;
           } ;
           if(isalpha(c)){
               alpha = alpha + 1;
           }
           charc = charc + 1;
        } ;

        // Update, only if anything changed
        if ( do_update ) {
            long next = ftell(fp) ;
            fseek(fp, loc, SEEK_SET) ;
            fwrite(buff, 1, n, fp) ;
            fseek(fp, next, SEEK_SET) ;
        } ;
   } ;
}

暫無
暫無

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

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