得到一个?在c中写入文件名后的文件名末尾(例如writeTo.txt?)

时间:2015-01-29 20:05:52

标签: c file-io

所以我的OS课程的第一个任务是在c中逐字节读取文件,然后将结果写入新文件。我必须获取输入和输出文件的目录。在我运行之后,我得到了一个非常奇怪的结果。创建文件并将文本写入其中。但是,该文件的名称为writeTo.txt?并且文件类型只是Document(我在运行yosemite的mac上运行)。要读取文件,我必须用vim打开它。

编辑:将我的代码更新为工作代码。

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


int main(){
    char * fileText;
    FILE * inFile;
    FILE * outFile;
    // /Users/admin/Documents/School/2014-2015/cs350/sample.txt
    char inFilePath[256];
    char outFilePath[256];
    printf("%s", "Input the directory to the input file:\n");
    fgets(inFilePath, sizeof(inFilePath), stdin);
    printf("%s", "Input the directory to the output file:\n");
    fgets(outFilePath, sizeof(outFilePath), stdin);


    for (int i =0; i < sizeof(inFilePath)/sizeof(char); i++){
        if (inFilePath[i] == '\n'){
            inFilePath[i] = '\0';
            break;
        }
        if (inFilePath[i] == '\r') {
            inFilePath[i] = '\0';
            break;
        }
    }
    for (int i =0; i < sizeof(outFilePath)/sizeof(char); i++){
        if (outFilePath[i] == '\n'){
            outFilePath[i] = '\0';
            break;
        }
        if (outFilePath[i] == '\r'){
             outFilePath[i] = '\0';
             break;
        }
    }


    size_t len;
    inFile = fopen(inFilePath, "r");


    fseek(inFile, 0, SEEK_END);
    len = ftell(inFile);
    rewind(inFile);

    fileText = (char *) malloc((len + 1) * sizeof(char));
    fread(fileText, sizeof(char), len, inFile);
    fileText[len] = '\0';
    fclose(inFile);

    outFile = fopen(outFilePath,"w");
    //fprintf(outFile, "%s", fileText);
    fwrite(fileText, sizeof(char), len, outFile);
    fclose(outFile);
    free(fileText);
    return 0;



}

3 个答案:

答案 0 :(得分:4)

当您重新编写数据时,您隐含地假设该文件没有嵌入的空字符。尾随?的问题在于您无法将您读入fileText的字符串空终止,该字符串未初始化。 fprintf读取缓冲区的末尾,并在文件末尾生成“垃圾”字符。

您已为char分配了额外的'\0',因此缺少的只是将空字符分配给缓冲区的最后char

fread(fileText, sizeof(char), len, inFile);
fileText[len] = '\0'; // <<== Add this

更好的方法是使用fwrite代替fprintf输出。这将解决嵌入的空字符的问题,并防止读取超过缓冲区的末尾:

fwrite(fileText, sizeof(char), len, outFile);
fclose(outFile);
free(fileText); // <<== Don't forget to free the buffer

答案 1 :(得分:2)

fgets读取一行包括换行符,因此换行符成为文件名的一部分。这在Unix上是可能的,但不可打印。哦,然后@ user312023正确观察到为什么你在outfile中替换换行的尝试失败;-)。 更新:@Basile对Mac OS有另一个警告(不确定它适用于OSX,而​​且在Mac上的iirc,EOL序列将是\ n \ r \ n(而不是MS的\ r \ n),这会使你的算法一旦修复了有关输入缓冲区的复制/粘贴错误,则对Mac有效。

答案 2 :(得分:2)

很可能(至少在Linux上),fgets(3)正在获得行尾终止行。在MacOSX OS上,我猜行的结尾可能是两个字符(例如\r&amp; \n)。你只删除一个。另一个仍然存在并且正在成为文件名的一部分。

我会改为读取没有任何空格的文件路径(可能使用sscanf(3))。顺便说一下,文件路径可以是程序参数(赋予int main(int argc, char**argv) ....)