c - 尝试创建txt文件,但提示无法打开文件

标签 c file text null

编程新手。我正在尝试创建一个txt文件,该文件要求用户提供文件名,然后为该文件输入文本。最初,我收到一个有关null的错误,因此我放入了if语句,似乎代码无法打开具有该名称的文件。试图进行一些研究并最终做出了一些更改,但仍然导致相同的错误。

include <stdio.h>;
include <stdlib.h>;

int main()

{

    char *fileName[100];
    char inputText[100];


    printf("What is the .txt file name? \n");
    scanf_s("%123s", &fileName);

    strcat(fileName, ".txt");

    FILE *textFile;

    textFile = fopen_s(&textFile, fileName, "w");

    if (textFile != 0)
    {
        printf("Cannot get file");
        return -1;
    }


    printf("What should be written in the text file? \n");
    scanf_s("%123s", &inputText);


    fprintf(textFile, "%s", inputText);


    fclose(textFile);

    return 0;
}

最佳答案

学习C语言最重要的事情就是-放慢速度。有很多东西要学习,您一次必须走一步。在猜测,编译,查看是否有任何更改,更改其他内容和(重复)时没有用。查一下

也就是说,您对stdin / stdout的基本输入/输出以及打开的用于写入的文件感兴趣。目前尚不清楚您是在使用scanf_s的窗口还是使用非_s版本的窗口,因为它们在下面混合并匹配。无论如何,主要区别在于必填参数。

在C语言中,您声明数组保存文件名,输入文本保存100个字符。使用字符串时,每个字符串在末尾都需要一个以n结尾的字符('\0' ...或只是0,在数值上相同)。这意味着您最多可以在99+1中存储filename个字符inputtext n个终止字符(注意:C通常避免使用大小写混合的变量名,而是使用所有小写字母,但是你决定)

为了防止在filenameinputtext末尾进行写操作,您需要确保限制试图存储在这两个字符中的字符数。您可以使用格式说明符的field-width选项来执行此操作。例如。,

scanf ("%99s", inputtext);


或对于Windows _s版本:

scanf_s ("%99s", inputtext, 100u);


但是,使用"%99s"格式说明符不允许输入包含空格,因为%s格式说明符将读取到第一个空格或换行符。其次,在按[Enter]生成的用户输入末尾,它不会读取(或无论如何处理)'\n'。如果您的下一个输入是字符输入,这将导致问题,因为scanf会很乐意接受'\n'作为要读取的下一个字符。现在,%s将跳过前导空格('\n'为空格)应该不会出现问题,但这是您形成scanf格式字符串之类的简单内容时必须经过的思考过程。

养成每次都要考虑输入流中所有字符的习惯。这样,您就不会因无法解释的错误而措手不及。

要允许您的输入包含空格,可以对scanf使用字符类格式说明符。例如,您可以使用"%99[^\n]"作为格式字符串。但是,字符类不会自动忽略开头的空格,但是您可以通过在space之前将%保留在格式说明符之前来提供这种灵活性,例如, " %99[^\n]"。这很重要。 (这也是为什么在处理用户输入时,通常首选fgets或POSIX getline优于scanf的原因。

现在如何处理输入缓冲区中剩下的'\n'(例如此处的stdin)?除了离开space,您还可以在格式字符串中使用赋值抑制运算符。 " %99[^\n]%*c" %*c是用于读取字符%c的格式说明符,但是通过包含'*'(赋值抑制运算符),可以告诉scanf读取和丢弃字符。

仅在接受用户输入时仅提供正确的格式说明符是不够的。您必须验证您已实际收到期望的输入。对于任何输入例程,这至少意味着要检查scanf(或fgetsgetline等)的返回值。对于scanf,返回的是“匹配计数”,它是根据格式字符串成功执行转换的次数。例如%s(或%[^\n])构成对单个转换的请求。 (与匹配抑制运算符相关的任何转换都不会包含在匹配计数中),因此,您的预期收益就是格式字符串中的转换次数。放在一起,您可以使用以下命令处理inputtext

    printf ("What should be written in the text file? "); /* prompt */
    /* validate user input -- limit to 99 chars (+1 for nul char)  */
    if (scanf (" %99[^\n]%*c", inputtext) != 1) {
        fprintf (stderr, "error: invalid input (inputtext).\n");
        return 1;
    }


同一件事对filename也不会起作用吗?答:不。为什么?您计划在用户输入后将".txt"附加到filename,对吗? ".txt"中有多少个字符?答案:4(对于组合的字符串,您只能使用1以n-终止的char)。那么,您必须将filename限制为什么? " %95[^\n]%*c"

要执行文件I / O,您有几种选择。到目前为止,fstream缓冲的I / O功能是基本文本I / O最常见的功能。为了读取或写入文件,必须首先打开FILE流。为此,您先声明一个FILE *pointer,然后调用fopen,然后检查返回值(pointer的值)以验证文件是否成功打开。相同的规则,格式说明符等适用于对文件(在磁盘上)进行读/写,就像对stdinstdout进行写操作一样,因为从C的角度来看,所有文件都是简单的文件。

考虑到这一点,您可以执行以下操作:

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

enum { MAXC = 100 };

int main (void) {

    /* declare and initialize variables */
    char filename[MAXC] = "", inputtext[MAXC] = "";
    FILE *fp = NULL;

    printf ("What is the .txt file name? ");    /* prompt */

    /* validate user input -- limit to 95 chars */
    if (scanf (" %95[^\n]%*c", filename) != 1) {
        fprintf (stderr, "error: invalid input (filename).\n");
        return 1;
    }
    strcat (filename, ".txt");  /* +4 chars = 99 chars */

    /* open file/validate file open for reading */
    if (!(fp = fopen (filename, "w"))) {
        fprintf (stderr, "error: file open failed '%s'.\n", filename);
        return 1;
    }

    printf ("What should be written in the text file? "); /* prompt */
    /* validate user input -- limit to 99 chars (+1 for nul char)  */
    if (scanf (" %99[^\n]%*c", inputtext) != 1) {
        fprintf (stderr, "error: invalid input (inputtext).\n");
        return 1;
    }

    /* output status to stdout & inputtext to fp */
    printf ("\nwriting to '%s'\n%s\n", filename, inputtext);
    fprintf (fp, "%s\n", inputtext);

    if (fclose (fp))    /* close file - validate stream close */
        fprintf (stderr, "error: on file stream close.\n");

    return 0;
}


注意:写入文件后,重要的是检查fclose的返回值,以确保在写入过程中未发生流错误。 (对于关闭您从中读取的信息流,无需担心)

使用/输出示例

$ ./bin/inputtext
What is the .txt file name? dat/inputtext
What should be written in the text file? A quick brown fox jumps over the lazy dog.

writing to 'dat/inputtext.txt'
A quick brown fox jumps over the lazy dog.


检查文件内容:

$ cat dat/inputtext.txt
A quick brown fox jumps over the lazy dog.


查看代码,让我知道您是否对代码中的任何字符有疑问。每个人都需要一点帮助,开始学习,我能传达的最重要的一点是,减慢并了解您编写的每个字符,阅读并了解您的编译器警告(修复每个警告),以及如果不确定自己在做什么。 ,查一下。在Linux / Unix上为man function,或在MSDN中搜索Windows(例如scanf_s,...)。它们以合理清晰的术语告诉您每个函数的每个参数有什么类型和要求(很多示例)。

祝您编码顺利。

关于c - 尝试创建txt文件,但提示无法打开文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38602804/

相关文章:

c - PEB(进程环境 block )无效的 DllBase 地址

c - 如何将 8 字节十六进制枚举值添加到 unsigned char 指针?

关于grep的c程序

performance - 通过 Powershell 查找给定文件的完整路径的最快方法?

javascript - 用标签替换文本

最多不能超过 50%。矩阵乘法的理论性能

node.js - 通过 Node 浏览器到 S3 文件传输

php - 检测 stdin 是 PHP 中的 tty 设备(终端)还是管道?

linux - 如何使用 Linux Find 命令查找并打印文档中的重复单词?

c# - 如果文本不存在,如何在文本后添加字符串?