如何使用Xcode去除每行开头的非人类可读字符

hrirmatl  于 2023-02-13  发布在  其他
关注(0)|答案(1)|浏览(94)

我试图设置Xcode,以消除从1986年创建的8英寸软盘中恢复的遗留文本文件中的非人类可读字符。这些文件是在QDOS中创建的,QDOS是一种专有的磁盘操作系统,使用基于文本的音乐创作语言应用程序(又名MCL)。
我的目标是编写一个C程序来读取ascii文件,逐个字符,从源文件中过滤掉不可打印的字符,并将其保存到目标文件中,从而使查看文件内容的格式与 composer 在1986年看到的格式完全相同。
当Xcode读取旧版文本文件时,不需要的字符显示为除第一行之外每行的第一个人类可读字符。

!B=24:Af
    *           BAR 1
    G2,6
     *           BAR 2 & 3
    !G2,1/4:Bf2,1/4:C2,1/4:Ef2,1/4:F3,1/4:G3,35/4:D3:A4
    "*           BAR 4 
    #Bf4:G4,2:D3:A4:Bf4
    $*           BAR 5
    %D4,2:C4,3:F5
    &*           BAR 6
    'D4:Bf4:A4,2:G4:D3:?
    (*           BAR 7 &

上述文本文件的十六进制转储显示两个ASCII字节$0D(回车)后跟$1C(文件分隔符)。这两个字节加上紧跟其后的字节,就是我要删除的字符。

0000: 1C 1D 21 42 3D 32 34 3A 41 66 0A 1C 1E 2A 20 20   ¿¿!B=24:Af¬¿¿*  
    0010: 20 20 20 20 20 20 20 20 20 42 41 52 20 31 0A 1C            BAR 1¬¿
    0020: 1F 47 32 2C 36 0A 1C 20 2A 20 20 20 20 20 20 20   ¿G2,6¬¿ *       
    0030: 20 20 20 20 42 41 52 20 32 20 26 20 33 0A 1C 21       BAR 2 & 3¬¿!
    0040: 47 32 2C 31 2F 34 3A 42 66 32 2C 31 2F 34 3A 43   G2,1/4:Bf2,1/4:C
    0050: 32 2C 31 2F 34 3A 45 66 32 2C 31 2F 34 3A 46 33   2,1/4:Ef2,1/4:F3
    0060: 2C 31 2F 34 3A 47 33 2C 33 35 2F 34 3A 44 33 3A   ,1/4:G3,35/4:D3:
    0070: 41 34 0A 1C 22 2A 20 20 20 20 20 20 20 20 20 20   A4¬¿"*          
    0080: 20 42 41 52 20 34 20 0A 1C 23 42 66 34 3A 47 34    BAR 4 ¬¿#Bf4:G4
    0090: 2C 32 3A 44 33 3A 41 34 3A 42 66 34 0A 1C 24 2A   ,2:D3:A4:Bf4¬¿$*
    00A0: 20 20 20 20 20 20 20 20 20 20 20 42 41 52 20 35              BAR 5
    00B0: 0A 1C 25 44 34 2C 32 3A 43 34 2C 33 3A 46 35 0A   ¬¿%D4,2:C4,3:F5¬
    00C0: 1C 26 2A 20 20 20 20 20 20 20 20 20 20 20 42 41   ¿&*           BA
    00D0: 52 20 36 0A 1C 27 44 34 3A 42 66 34 3A 41 34 2C   R 6¬¿'D4:Bf4:A4,
    00E0: 32 3A 47 34 3A 44 33 3A 3F 0A 1C 28 2A 20 20 20   2:G4:D3:?¬¿(*   
    00F0: 20 20 20 20 20 20 20 20 42 41 52 20 37 20 26 20           BAR 7 &

我创建了一个Xcode Command Line Tool项目。当我在Xcode Inspectors Window中选择Type : Plain TextText Encoding : Unicode (UTF-8)时,同一个可打印字符可见。我选择这些设置是因为我的MacOS需要en_AU.UTF-8
下面的C代码创建了一个文本文件的相同副本,但没有标识单个字符。本质上,它将读取旧文件内容并成功写入新文件。输出文件的十六进制转储与上面的十六进制转储相同。

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

    int main(int argc, const char * argv[]) {

    char filename[] = {"~/Desktop/MCLRead/bell1.ss"} ;

    printf("MCLRead\n\t%s\n", filename);

    FILE* fin = fopen(filename, "r");
    if (!fin) { perror("input error"); return 0; }

    FILE* fout = fopen("output.txt", "w");
    if (!fout) { perror("fout error"); return 0; }

    fseek(fin, 0, SEEK_END); // go to the end of file
    size_t filesize = ftell(fin); // get file size
    fseek(fin, 0, SEEK_SET); // go back to the beginning

    //allocate enough memory
    char* buffer = malloc(filesize * sizeof(char));

    //read one character at a time (or `fread` the whole file)

    size_t i = 0;
    while (1)
    {
        int c = fgetc(fin);
        if (c == EOF) break;

    //save to buffer
        buffer[i++] = (char)c;
    }

但是当我在Xcode中编译、构建和运行时,无论Xcode Inspectors Window中的TypeText Encoding设置如何,字符都无法识别。

error: No such file or directory
    Program ended with exit code: 0

当我在Terminal Window中运行相同的代码时,它生成了一个输出文本文件,但字符无法识别

Desktop % gcc main.c
    Desktop % ./a.out output.txt
    Desktop % cat output.txt

cat会在终端Command Line中生成128个?字符的字符串-即使文件包含的字符总数超过1000个,也总共为128个。
有人能给我任何线索,使这个文本文件可读的格式,允许非人类可读的字符被剥离,从每一行的开始。
请注意,我不是在请求帮助编写C代码,而是请求什么样的文本格式可以使不需要的8位字符可读,这样我就可以删除它们(对我最初提出的问题进行了轻微的改进)。任何进一步的帮助都将是非常感谢的。提前感谢。

    • 注**

已根据评论意见修订了这一员额。
十六进制转储文件是以文本而不是图像的形式完成的。这为任何想要测试我所做的事情的人提供了共享文本文件的最可靠的方式

xoshrz7s

xoshrz7s1#

当使用int而不是char将每个字节读取为7位二进制值时,问题就解决了。

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

    int main(int argc, const char * argv[]) 
    {   
        char fname[] = {"bell1.ss"} ;               // place bell1.ss on desktop
        printf("\n\t%s\n", fname);    
        int a = 0;                                  // init CR holder
        int b = a;                                  // init File Separator holder
        FILE* fin = fopen(fname, "r");              // init read
        if (!fin) 
        { perror("input error"); return 0;
        }    
        FILE* fout = fopen("output.txt", "w");      // init write
        if (!fout) 
        { perror("fout error"); return 0; 
        }
        fseek(fin, 0, SEEK_END);                    // look for end of file
        size_t fsize = ftell(fin);                  // get file size
        fseek(fin, 0, SEEK_SET);                    // go back to the start                                             
        int* buffer = malloc(fsize * sizeof(int));  // allocate buffer                          
        size_t i = 0;
        while (1)
        {
            int c = fgetc(fin);                     // read one byte at a time
            if (c == EOF) break;                    // detect EOF &
            if (c <= 12) break;                     // first 12 control codes
            if (c == 229) break;                    // floppy format pattern
        
            if ((a != 13) && (b != 28))             // detect start of line     
            {       
            buffer[i++] = c;                        // save to buffer   
            }                  
            a = b;
            b = c;
        }   
        for (i = 0; i < fsize; i++)                 // write out int by int
            fputc(buffer[i], fout);
        free(buffer);
        fclose(fin);
        fclose(fout);
        return 0;
    }

相关问题