You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C语言文件访问参数问题:守护进程开发中的文件读写错误排查

C语言守护进程文件读写参数问题排查

问题背景

正在通过编写基础守护进程学习C语言,文件读写操作上遇到参数相关问题,对照多篇文档和论坛帖子后仍无法解决,以下是代码及编译错误:

原代码

#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<stdbool.h>
#include<stdint.h>
#include<string.h>
#include<signal.h>
#include <libnotify/notify.h>
#define EXIT_SUCCES 0
#define EXIT_FALIURE_READING_FILE 1
#define EXIT_FALIURE_LIBNOTIFY 2

char *ProgramTitle = "styckynotes";
char *messages_array[] = {"this mesage has not yet been set","this mesage has not yet been set","this mesage has not yet been set","this mesage has not yet been set","this mesage has not yet been set","this mesage has not yet been set","this mesage has not yet been set","this mesage has not yet been set","this mesage has not yet been set"};

int change_messgages(int array_number,char* message){
    if (array_number > 10){
        fprintf(stderr,"you are trying to write to a array number that doesnt exist, this would corrupt the memory please do not do that");
    }
    if (array_number < 10){
        char* intended_message= message;
        intended_message =  (char *)malloc(sizeof(char)*(strlen(intended_message)+1));
        messages_array[array_number-1] = intended_message;
        FILE myFile;
        myFile = fopen("messages.txt", "w");
        int i;
        if (myFile == NULL){
            printf("Error Reading File\n");
            exit (EXIT_FALIURE_READING_FILE);
        }
        for (i = 0; i < 16; i++){
            fprintf(myFile, "%d,", &messages_array[i] );
        }
        fclose(myFile);
    }
    return 0;
}

int signal_handler(void){
    //im counting from one since thats how an avarge user would experience it
    rl_bind_keyseq("\\C-e-1",note_pls(0));
    rl_bind_keyseq("\\C-e-2",note_pls(1));
    rl_bind_keyseq("\\C-e-3",note_pls(2));
    rl_bind_keyseq("\\C-e-4",note_pls(3));
    rl_bind_keyseq("\\C-e-5",note_pls(4));
    rl_bind_keyseq("\\C-e-6",note_pls(5));
    rl_bind_keyseq("\\C-e-7",note_pls(6));
    rl_bind_keyseq("\\C-e-8",note_pls(7));
    rl_bind_keyseq("\\C-e-9",note_pls(8));
    // rl_bind_keyseq("\\C-e-0",exit(EXIT_SUCCES));
    return 0;
}

note_pls(int pull_from){
    char* notification = notify_notification_new("reminder", messages_array[pull_from], "dialog-information");
    if (notification == NULL) {
        fprintf(stderr, "Got a null notify handle!\n");
    }
    notify_notification_show(notification, NULL);
    return 0;
}

int main(void){
    signal_handler();
    bool notifyInitStatus = notify_init(ProgramTitle);
    if (!notifyInitStatus) {
        fprintf(stderr, "Error initialising with libnotify!\n");
        exit(EXIT_FALIURE_LIBNOTIFY);
        FILE* myFile;
        myFile = fopen("messages.txt", "r");
        int i;
        if (myFile == NULL){
            printf("Error Reading File\n");
            exit (EXIT_FALIURE_READING_FILE);
        }

        for (i = 0; i < 16; i++){
            fgets(myFile,696969, &messages_array[i] );
        }
        fclose(myFile);
    }
}

编译错误信息

stickynotes.c: In function ‘change_messgages’:
stickynotes.c:25:14: error: incompatible types when assigning to type ‘FILE’ from type ‘FILE *’
   25 |     myFile = fopen("messages.txt", "w");
      |              ^~~~~
stickynotes.c:27:16: error: invalid operands to binary == (have ‘FILE’ and ‘void *’)
   27 |     if (myFile == NULL){
      |                ^~
stickynotes.c:32:17: error: incompatible type for argument 1 of ‘fprintf’
   32 |         fprintf(myFile, "%d,", &messages_array[i] );
      |                 ^~~~~~
      |                 |
      |                 FILE
In file included from stickynotes.c:1:
/usr/include/stdio.h:357:38: note: expected ‘FILE * restrict’ but argument is of type ‘FILE’
  357 | extern int fprintf (FILE *__restrict __stream,
      |                     ~~~~~~~~~~~~~~~~~^~~~~~~~
stickynotes.c:34:16: error: incompatible type for argument 1 of ‘fclose’
   34 |         fclose(myFile);
      |                ^~~~~~
      |                |
      |                FILE
/usr/include/stdio.h:184:26: note: expected ‘FILE *’ but argument is of type ‘FILE’
  184 | extern int fclose (FILE *__stream) __nonnull ((1));
      |                    ~~~~~~^~~~~~~~
stickynotes.c:76:15: warning: passing argument 1 of ‘fgets’ from incompatible pointer type [-Wincompatible-pointer-types]
   76 |         fgets(myFile,696969, &messages_array[i] );
      |               ^~~~~~
      |               |
      |               FILE *
/usr/include/stdio.h:654:38: note: expected ‘char * restrict’ but argument is of type ‘FILE *’
  654 | extern char *fgets (char *__restrict __s, int __n, FILE *__restrict __stream)
      |                     ~~~~~~~~~~~~~~~~~^~~
stickynotes.c:76:30: warning: passing argument 3 of ‘fgets’ from incompatible pointer type [-Wincompatible-pointer-types]
   76 |         fgets(myFile,696969, &messages_array[i] );
      |                              ^~~~~~~~~~~~~~~~~~
      |                              |
      |                              char **
/usr/include/stdio.h:654:69: note: expected ‘FILE * restrict’ but argument is of type ‘char **’
  654 | extern char *fgets (char *__restrict __s, int __n, FILE *__restrict __stream)
      |                                                    ~~~~~~~~~~~~~~~~~^~~~~~~~

错误修正点

1. FILE对象类型错误

fopen返回的是FILE*指针,不是FILE结构体实例,需将change_messgages函数内的FILE myFile;改为FILE* myFile;,后续文件操作均使用指针。

2. fprintf参数错误

  • 第一个参数需为FILE*,修正类型后解决;
  • 第三个参数错误:&messages_array[i]是指针的地址,要写入字符串内容应直接用messages_array[i],同时格式符改为%s,(写入字符串而非整数地址);
  • 循环次数越界:messages_array仅9个元素,循环写16次会访问非法内存,需改为i < sizeof(messages_array)/sizeof(messages_array[0])。

3. fgets参数顺序与内存问题

fgets参数顺序为char* 缓冲区, 最大读取长度, FILE* 文件指针,原代码颠倒了文件指针与缓冲区位置;且messages_array[i]未分配内存,需先调用malloc分配空间再读取内容。

4. main函数逻辑错误

exit(EXIT_FALIURE_LIBNOTIFY);后的代码永远不会执行,需将文件读取代码移到if (!notifyInitStatus)分支外,仅当libnotify初始化成功时才执行文件读取。

5. 其他细节问题

  • note_pls函数缺少返回值类型,需提前声明为int note_pls(int pull_from);;
  • signal_handler中rl_bind_keyseq的第二个参数应为函数指针,不能直接调用note_pls(0),需编写包装函数;
  • 拼写错误:EXIT_SUCCES→EXIT_SUCCESS,EXIT_FALIURE_*→EXIT_FAILURE_*,mesage→message;
  • change_messgages中内存分配逻辑错误:原代码先让intended_message指向传入的message,再用malloc覆盖导致原消息丢失,需改为先分配内存再复制字符串。

修正后的完整代码

#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<stdbool.h>
#include<stdint.h>
#include<string.h>
#include<signal.h>
#include <libnotify/notify.h>
#include <readline/readline.h>

#define EXIT_SUCCESS 0
#define EXIT_FAILURE_READING_FILE 1
#define EXIT_FAILURE_LIBNOTIFY 2

char *ProgramTitle = "stickynotes";
char *messages_array[] = {"this message has not yet been set",
                         "this message has not yet been set",
                         "this message has not yet been set",
                         "this message has not yet been set",
                         "this message has not yet been set",
                         "this message has not yet been set",
                         "this message has not yet been set",
                         "this message has not yet been set",
                         "this message has not yet been set"};

int note_pls(int pull_from);
void note_wrapper_0() { note_pls(0); }
void note_wrapper_1() { note_pls(1); }
void note_wrapper_2() { note_pls(2); }
void note_wrapper_3() { note_pls(3); }
void note_wrapper_4() { note_pls(4); }
void note_wrapper_5() { note_pls(5); }
void note_wrapper_6() { note_pls(6); }
void note_wrapper_7() { note_pls(7); }
void note_wrapper_8() { note_pls(8); }

int change_messages(int array_number, char* message){
    if (array_number > 9 || array_number < 1){
        fprintf(stderr, "Error: array number must be between 1 and 9\n");
        return 1;
    }
    char* intended_message = malloc(strlen(message) + 1);
    if (!intended_message) {
        fprintf(stderr, "Memory allocation failed\n");
        return 1;
    }
    strcpy(intended_message, message);
    free(messages_array[array_number-1]);
    messages_array[array_number-1] = intended_message;

    FILE* myFile = fopen("messages.txt", "w");
    if (!myFile){
        fprintf(stderr, "Error Writing File\n");
        return EXIT_FAILURE_READING_FILE;
    }
    int i;
    size_t array_len = sizeof(messages_array)/sizeof(messages_array[0]);
    for (i = 0; i < array_len; i++){
        fprintf(myFile, "%s\n", messages_array[i]);
    }
    fclose(myFile);
    return 0;
}

int signal_handler(void){
    rl_bind_keyseq("\\C-e-1", note_wrapper_0);
    rl_bind_keyseq("\\C-e-2", note_wrapper_1);
    rl_bind_keyseq("\\C-e-3", note_wrapper_2);
    rl_bind_keyseq("\\C-e-4", note_wrapper_3);
    rl_bind_keyseq("\\C-e-5", note_wrapper_4);
    rl_bind_keyseq("\\C-e-6", note_wrapper_5);
    rl_bind_keyseq("\\C-e-7", note_wrapper_6);
    rl_bind_keyseq("\\C-e-8", note_wrapper_7);
    rl_bind_keyseq("\\C-e-9", note_wrapper_8);
    return 0;
}

int note_pls(int pull_from){
    if (pull_from <0 || pull_from >= sizeof(messages_array)/sizeof(messages_array[0])) {
        fprintf(stderr, "Invalid index\n");
        return 1;
    }
    NotifyNotification* notification = notify_notification_new("reminder", messages_array[pull_from], "dialog-information");
    if (!notification) {
        fprintf(stderr, "Got a null notify handle!\n");
        return 1;
    }
    notify_notification_show(notification, NULL);
    g_object_unref(notification);
    return 0;
}

int main(void){
    bool notifyInitStatus = notify_init(ProgramTitle);
    if (!notifyInitStatus) {
        fprintf(stderr, "Error initialising with libnotify!\n");
        exit(EXIT_FAILURE_LIBNOTIFY);
    }

    FILE* myFile = fopen("messages.txt", "r");
    if (myFile){
        int i;
        size_t array_len = sizeof(messages_array)/sizeof(messages_array[0]);
        for (i = 0; i < array_len; i++){
            free(messages_array[i]);
            messages_array[i] = malloc(1024);
            if (!messages_array[i]) {
                fprintf(stderr, "Memory allocation failed\n");
                exit(EXIT_FAILURE_READING_FILE);
            }
            if (fgets(messages_array[i], 1024, myFile)) {
                size_t len = strlen(messages_array[i]);
                if (len > 0 && messages_array[i][len-1] == '\n') {
                    messages_array[i][len-1] = '\0';
                }
            } else {
                strcpy(messages_array[i], "this message has not yet been set");
            }
        }
        fclose(myFile);
    } else {
        fprintf(stderr, "Warning: messages.txt not found, using default messages\n");
    }

    signal_handler();

    while(1) {
        pause();
    }

    notify_uninit();
    for (int i=0; i<sizeof(messages_array)/sizeof(messages_array[0]); i++){
        free(messages_array[i]);
    }
    return EXIT_SUCCESS;
}

内容的提问来源于stack exchange,提问作者Ibolya Vojtek

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.17 00:47:02