我正在尝试制作一个简单的程序来存储和加载文本,这样我以后只需按三个按钮就可以通过通知显示它,但是我遇到了 fprintf 和 fgets 无法的问题使用数组,任何人都可以建议一种更好的保存和加载方式,我对 C 语言编程非常陌生,所以任何建议将不胜感激 下面的代码和错误
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<stdbool.h>
#include<stdint.h>
#include<string.h>
#include <readline/readline.h>
#include <readline/history.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[9] = {"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* new_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 (sizeof(new_message)>100){
fprintf(stderr,"message too long try keeping it under 100 charachters");
}
if ((array_number < 10) && (sizeof(new_message)<100)){
free(messages_array[array_number]);
messages_array[array_number] = malloc(strlen(new_message) + 1);
messages_array[array_number-1] = new_message;
strcpy(messages_array[array_number], new_message);
FILE *myFile = fopen("messages.txt", "w");
int i;
if (myFile == NULL){
printf("Error Reading File\n");
exit(EXIT_FALIURE_READING_FILE);
}
for (i = 0; i < 8; i++){
fprintf(myFile, &messages_array[i]);
}
fclose(myFile);
}
return 0;
}
int note_pls(int count, int key){
printf("%d", count);
printf("%d", count);
int pull_from=key-1;
NotifyNotification *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);
g_object_unref(G_OBJECT(notification));
notify_uninit();
return 0;
}
int signal_handler(void){
//im counting from one since thats how an avarge user would experience it
rl_command_func_t note_pls;
rl_command_func_t exitrl;
rl_bind_keyseq("\\C-e-1",note_pls);
rl_bind_keyseq("\\C-e-2",note_pls);
rl_bind_keyseq("\\C-e-3",note_pls);
rl_bind_keyseq("\\C-e-4",note_pls);
rl_bind_keyseq("\\C-e-5",note_pls);
rl_bind_keyseq("\\C-e-6",note_pls);
rl_bind_keyseq("\\C-e-7",note_pls);
rl_bind_keyseq("\\C-e-8",note_pls);
rl_bind_keyseq("\\C-e-9",note_pls);
rl_bind_keyseq("\\C-e-0",exitrl);
return 0;
}
int exitrl(int count, int key){
exit(EXIT_SUCCES);
}
int main(void){
bool notifyInitStatus = notify_init(ProgramTitle);
if (!notifyInitStatus) {
fprintf(stderr, "Error initialising with libnotify!\n");
exit(EXIT_FALIURE_LIBNOTIFY);
FILE *myFile = fopen("messages.txt", "r");
int i;
if (myFile == NULL){
printf("Error Reading File\n");
exit (EXIT_FALIURE_READING_FILE);
}
for (i = 0; i < 8; i++){
fgets(&messages_array[i],100,myFile);
}
fclose(myFile);
}
signal_handler(); // for readability
}
tickynotes.c: In function ‘change_messgages’:
stickynotes.c:35:25: warning: passing argument 2 of ‘fprintf’ from incompatible pointer type [-Wincompatible-pointer-types]
35 | fprintf(myFile, &messages_array[i]);
| ^~~~~~~~~~~~~~~~~~
| |
| char **
In file included from stickynotes.c:1:
/usr/include/stdio.h:358:44: note: expected ‘const char * restrict’ but argument is of type ‘char **’
358 | const char *__restrict __format, ...) __nonnull ((1));
| ~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~
stickynotes.c:35:25: warning: format not a string literal and no format arguments [-Wformat-security]
35 | fprintf(myFile, &messages_array[i]);
| ^~~~~~~~~~~~~~~~~~
stickynotes.c: In function ‘main’:
stickynotes.c:86:15: warning: passing argument 1 of ‘fgets’ from incompatible pointer type [-Wincompatible-pointer-types]
86 | fgets(&messages_array[i],100,myFile);
| ^~~~~~~~~~~~~~~~~~
| |
| char **
/usr/include/stdio.h:654:38: note: expected ‘char * restrict’ but argument is of type ‘char **’
654 | extern char *fgets (char *__restrict __s, int __n, FILE *__restrict __stream)
| ~~~~~~~~~~~~~~~~~^~~
/usr/bin/ld: cannot open output file build/stickynotesd: No such file or directory
collect2: error: ld returned 1 exit status
make: *** [makefile:6: stickynotes] Error 1
此消息:
stickynotes.c:35:25: warning: passing argument 2 of ‘fprintf’ from incompatible pointer type [-Wincompatible-pointer-types]
35 | fprintf(myFile, &messages_array[i]);
| ^~~~~~~~~~~~~~~~~~
| |
| char **
In file included from stickynotes.c:1:
/usr/include/stdio.h:358:44: note: expected ‘const char * restrict’ but argument is of type ‘char **’
358 | const char *__restrict __format, ...) __nonnull ((1));
| ~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~
说出问题。
这里:
stickynotes.c:35:25: warning: passing argument 2 of ‘fprintf’ from incompatible pointer type [-Wincompatible-pointer-types]
35 | fprintf(myFile, &messages_array[i]);
| ^~~~~~~~~~~~~~~~~~
| |
| char **
问题描述:“...不兼容的指针类型”
它还会告诉您有问题的线路。它甚至使用类似下划线的符号告诉您行中的位置。它还告诉您
^~~~~~~~~~~~~~~~~~
的类型为 &messages_array[i]
。所以归根结底,您将 char **
传递给
char **
,但 fprintf
并不期望 fprintf
。那么char**
期望什么?
嗯,这实际上是在以下消息中:fprintf
它告诉你“预期是‘const char * limit’,但参数的类型是‘char **’
” 就是这样:
In file included from stickynotes.c:1:
/usr/include/stdio.h:358:44: note: expected ‘const char * restrict’ but argument is of type ‘char **’
358 | const char *__restrict __format, ...) __nonnull ((1));
| ~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~
想要一个
fprintf
,但你给了它一个char*
,因为你这样做:char**
&messages_array[i]
的定义是:
messages_array
所以
char *messages_array[9] = ....
是一个包含 9 个元素的
messages_array
数组。因此,char*
将为您提供类型
messages_array[i]
,而 char*
将为您提供类型 &messages_array[i]
。换句话说 - char**
已经具有
messages_array[i]
所期望的类型,但您可以使用 fprintf
更改它。解决办法很简单,就是在调用 &
时去掉 &
。原则上,调用 fprintf
时也是如此。
但是事情远不止这些......
fgets
保存指向字符串文字(也称为文本字符串)的指针。在 C 中,字符串文字不能被修改。尝试修改 C 中的常量字符串会导致未定义的行为。
这正是messages_array
将会做的。所以你有问题。要解决这个问题,您需要将
fgets
转换为允许修改字符串的东西。有多种不同的方法可以做到这一点。这是一个:
messages_array
现在
#define MAX_SIZE 100
char messages_array[9][MAX_SIZE] = {"this mesage has not yet been set", .....};
不是指向字符串文字的指针。现在它实际上可以保存真实的字符串值。它被初始化为字符串文字的副本,但一旦初始化,
messages_array
就保存它自己的可修改字符串。免责声明您的代码中可能还有其他问题。我只是关注这个问题。
例如,我很确定
messages_array
是
没有做你所期望的。尝试:
sizeof(new_message)