额外减小 发表于 2023-1-15 10:35:21

C语言新手求助:fopen()没法创建文件的问题(大佬勿喷谢谢)

本帖最后由 额外减小 于 2023-1-15 11:00 编辑

如题
我想用fopen函数创建一个.c的文件。
但是按照这个代码运行以后却没有在当前文件夹中创建出相应的文件。
请问这是为什么呢
注.程序可以运行,返回值正常

#include <stdio.h>
#include <conio.h>
#include <string.h>
#include <windows.h>

#define TITLEMAXLEN 128
#define TEXTMAXLEN 65536

int main()
{
        char ch=' ',title={'\0'},*ptr=title;
        printf("输入文件名:");
        do
        {
                ch=getch();
                *ptr=ch;
                ptr++;
                printf("%c",ch);
        }
        while(ch!=13);
        /*输入一行文件名*/
        system("cls");
       
        FILE *fp=fopen(strcat(title,".c"),"w");
        /*以只写打开文件*/
        if(fp=NULL)
        {
                printf("error\n");
        }
        else
        {
                fprintf(fp,"#include <stdio.h>\n\nint main()\n{\n    printf(\"hello?\\n\");\n    return 0;\n}");
        }
        fclose(fp);
        return 0;
}

这个是32行原来的版本。这个他给我漏掉了,不知道为什么

线索:当我把第24行fopen()的第一个参数改为一个字符串常量的时候,就又可以创建文件了,但fprintf()返回的是-1

额外减小 发表于 2023-1-15 10:38:41

等等,这个输入代码的有毒啊?
他给我把反斜杠漏掉了

dolly_yos2 发表于 2023-1-15 11:16:19

这个输入方式看的人心惊肉跳的,有必要这么做吗?会不会有奇怪的字符混进文件名里?
检查所有的返回值,看看是哪个函数失败了,检查错误码( errno )可能会给调查问题提供辅助

额外减小 发表于 2023-1-15 11:22:11

dolly_yos2 发表于 2023-1-15 11:16
这个输入方式看的人心惊肉跳的,有必要这么做吗?会不会有奇怪的字符混进文件名里?
检查所有的返回值,看 ...

好的
我试试

人造人 发表于 2023-1-15 11:23:23

sh-5.1$ ls
main.c
sh-5.1$ cat main.c
#if 0
#include <stdio.h>
#include <string.h>
//#include <conio.h>
//#include <windows.h>
// 上面那两个用不了

#define TITLEMAXLEN 128
//#define TEXTMAXLEN 65536

int main(void) {
    //char ch = ' ', title = {'\0'}, *ptr = title;   // 这样效率不高,因为要全部设置成0,可以的话尽量自己设置一个0
    char title, *ptr = title;
    printf("输入文件名:");
    while(1) {
      char ch = getchar();
      if(ch == '\n' || ch == EOF) break;
      *ptr++ = ch;
    }
    *ptr = '\0';
    /*
    do {
      ch = getch();
      *ptr = ch;
      ptr++;
      printf("%c", ch);
    //} while(ch != 13);      // 13 是什么?换行?应该是换行吧,不去查ascii表了,看这个代码的语义,这里应该是换行
    } while(ch != '\n');      // 直接写 '\n' 不就好了,让编译器去查ascii表
                              // 这是在ch是char类型的时候,还知道用13这个数字去查ascii表,如果是其他类型而且变量名还比较神奇的话,这个数字也就没办法知道是什么了
                              // 这就是传说中的神奇数字
    */
    /*输入一行文件名*/
    //system("cls");    // 用不了的说

#if 0
    FILE *fp = fopen(strcat(title, ".c"), "w");
    /*以只写打开文件*/
    //if(fp = NULL) {   // 这是什么操作?请你告诉我
    if(fp == NULL) {
      printf("error\n");
    } else {
                fprintf(fp,"#include <stdio.h>\n\nint main()\n{\n    printf("hello?\\n");\n    return 0;\n}");
    }
    fclose(fp);
#endif
    FILE *fp = fopen(strcat(title, ".c"), "w");
    if(!fp) return -1;
    fprintf(fp,"#include <stdio.h>\n\nint main(void) {\n    printf(\"hello world!\\n\");\n    return 0;\n}");
    fclose(fp);
    return 0;
}
#endif

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

int main(void) {
    char filename;
    printf("输入文件名:");
    fgets(filename, 1024, stdin);
    filename = '\0';      // '\n'
    FILE *fp = fopen(filename, "w");
    if(!fp) return -1;
    fprintf(fp,"#include <stdio.h>\n\nint main(void) {\n    printf(\"hello world!\\n\");\n    return 0;\n}");
    fclose(fp);
    return 0;
}
sh-5.1$ gcc -g -Wall -o main main.c
sh-5.1$ ls
mainmain.c
sh-5.1$ ./main
输入文件名:test.c
sh-5.1$ ls
mainmain.ctest.c
sh-5.1$ cat test.c
#include <stdio.h>

int main(void) {
    printf("hello world!\n");
    return 0;
sh-5.1$

额外减小 发表于 2023-1-15 12:02:12

人造人 发表于 2023-1-15 11:23


谢谢大佬

是我脑抽了

真是麻烦您了{:10_254:}

人造人 发表于 2023-1-15 17:42:47

再添加个调用编译器的功能
你可能会问,为什么不用system函数
我想说的是,我就是想再练习一下fork+exec函数,^_^

sh-5.1$ cat main.c
#define _GNU_SOURCE

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/wait.h>
#include <linux/limits.h>

void write_code(const char *filename) {
    FILE *fp = fopen(filename, "w");
    if(!fp) return;
    fprintf(fp, "#include <stdio.h>\n\nint main(void) {\n    printf(\"hello world!\\n\");\n    return 0;\n}");
    fclose(fp);
}

int compile(const char *filename) {
    int fd = open("/tmp", O_TMPFILE | O_RDWR, 0755);
    pid_t pid = fork();
    if(!pid) {
      const char *argv[] = {"gcc", "-g", "-Wall", "-o", "/dev/stdout", filename, NULL};
      dup2(fd, STDOUT_FILENO); close(fd);
      exit(execvp(argv, (void *)argv));
    }
    waitpid(pid, NULL, 0);
    return fd;
}

void run(int fd) {
    char path;
    snprintf(path, PATH_MAX, "/proc/self/fd/%d", fd);
    int new_fd = open(path, O_RDONLY);      // fexecve 要求 fd 是 O_RDONLY
    dup2(new_fd, fd);
    pid_t pid = fork();
    if(!pid) {
      const char *argv[] = {NULL};
      const char *envp[] = {NULL};
      exit(fexecve(fd, (void *)argv, (void *)envp));
    }
    waitpid(pid, NULL, 0);
}

int main(void) {
    char filename;
    printf("输入文件名:");
    fgets(filename, PATH_MAX, stdin);
    filename = '\0';
    write_code(filename);
    int fd = compile(filename);
    run(fd);
    close(fd);
    return 0;
}
sh-5.1$ gcc -g -Wall -o main main.c
sh-5.1$ ./main
输入文件名:test.c
hello world!
sh-5.1$

额外减小 发表于 2023-1-15 17:48:27

人造人 发表于 2023-1-15 17:42
再添加个调用编译器的功能
你可能会问,为什么不用system函数
我想说的是,我就是想再练习一下fork+exec ...

这个是只有linux才可以使用的吗?

人造人 发表于 2023-1-15 17:54:12

额外减小 发表于 2023-1-15 17:48
这个是只有linux才可以使用的吗?

可以试试dev-cpp能不能用
还可以试试,cygwin

人造人 发表于 2023-1-15 18:15:17

既然gcc生成的是一个临时文件,那么直接把C代码也写到临时文件算了
我感觉这样更好

sh-5.1$ cat main.c
#define _GNU_SOURCE

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/wait.h>
#include <linux/limits.h>

int write_code(const char *code) {
    int fd = open("/tmp", O_TMPFILE | O_RDWR, 0644);
    write(fd, code, strlen(code));
    return fd;
}

void compile(int fd) {
    int o_fd = open("/tmp", O_TMPFILE | O_RDWR, 0755);
    pid_t pid = fork();
    if(!pid) {
      const char *argv[] = {"gcc", "-g", "-Wall", "-x", "c", "-o", "/dev/stdout", "/dev/stdin", NULL};
      dup2(fd, STDIN_FILENO); close(fd);
      dup2(o_fd, STDOUT_FILENO); close(o_fd);
      exit(execvp(argv, (void *)argv));
    }
    waitpid(pid, NULL, 0);
    dup2(o_fd, fd); close(o_fd);
}

void run(int fd) {
    char path;
    snprintf(path, PATH_MAX, "/proc/self/fd/%d", fd);
    int new_fd = open(path, O_RDONLY);      // fexecve 要求 fd 是 O_RDONLY
    dup2(new_fd, fd);
    pid_t pid = fork();
    if(!pid) {
      //const char *argv[] = {NULL};
      const char *argv[] = {"fexecve", "+", "1234", "5678", "sum", NULL};
      const char *envp[] = {NULL};
      exit(fexecve(fd, (void *)argv, (void *)envp));
    }
    waitpid(pid, NULL, 0);
}

int main(void) {
    char code[] =
      "#include <stdio.h>\n"
      "\n"
      "int main(int argc, char *argv[]) {\n"
      "    for(size_t i = 0; i < argc; ++i) {\n"
      "      puts(argv);\n"
      "    }\n"
      "    return 0;\n"
      "}";
    int fd = write_code(code);
    compile(fd); run(fd); close(fd);
    return 0;
}
sh-5.1$ gcc -g -Wall -o main main.c
sh-5.1$ ./main
fexecve
+
1234
5678
sum
sh-5.1$
页: [1]
查看完整版本: C语言新手求助:fopen()没法创建文件的问题(大佬勿喷谢谢)