【发布时间】:2019-09-08 10:55:26
【问题描述】:
我一直在努力完成剥削的艺术 作者 Jon Erickson,但我遇到了一个关于从文件和他的代码中读取数据的症结。
./notetaker 和 ./notesearch 有两个程序,前者用于创建带有用户 id 的便笺,后者用于检索当前用户的便笺。
但是,在做笔记并尝试通过 ./notesearch 访问它后,该笔记不会显示为书中建议的文本。
到目前为止,我推断出在 ./notetaker 中创建的文件是数据文件,而不是文本文件,因此打印出来时不可读。
那么为什么作者建议他的代码可以工作,而实际上却没有,最简单的解决方法是什么。
我已经开始将 fopen、fgets() 等作为解决方案,但它似乎与原始代码相去甚远。
如果我让 ./notesearch 查看随机文本文件,它将以人类可读的形式打印出来,所以我认为问题在于原始文件的创建及其类型。
但不幸的是,我不知道如何克服这个问题
来自 ./notetaker 的片段
int main(int argc, char *argv[]) {
int userid;
int file_descriptor;
char *buffer, *datafile;
buffer = (char *) ec_malloc(100);
datafile = (char *) ec_malloc(20);
strcpy(datafile, "notes");
if (argc < 2)
usage(argv[0], datafile);
strcpy(buffer, argv[1]);
printf("[DEBUG] buffer @ %p: '%s'\n", buffer, buffer);
printf("[DEBUG] datafile @ %p: '%s'\n", datafile, datafile);
strncat(buffer, "\n", 1); //adds a newline to end
// opening file
file_descriptor = open(datafile, O_WRONLY|O_CREAT|O_APPEND, S_IRUSR|S_IWUSR);
if (file_descriptor == -1)
fatal("in main() while opening file");
printf("[DEBUG] file descriptor is %d\n", file_descriptor);
userid = getuid();
// write data
if (write(file_descriptor, &userid, 4) == -1)
fatal("in main() while writing userid to file");
write(file_descriptor, "\n", 1);
if (write(file_descriptor, buffer, strlen(buffer)) == -1)
fatal("in main() while writing buffer to file");
write(file_descriptor, "\n", 1);
// closing file
if (close(file_descriptor) == -1)
fatal("in main() while closing file");
来自 ./notesearch 的片段
#define FILENAME "notes"
int print_notes(int, int, char *);
int find_user_note(int, int);
int search_note(char *, char *);
int main(int argc, char *argv[]) {
int userid, printing = 1, file_descriptor;
char search_string[100];
if (argc > 1)
strcpy(search_string, argv[1]);
else
search_string[0] = 0;
userid = getuid();
file_descriptor = open(FILENAME, O_RDONLY);
if (file_descriptor == -1)
fatal("in main() while opening file for reading");
while (printing)
printing = print_notes(file_descriptor, userid, search_string);
printf("------ [ end of note data ] ------\n");
close(file_descriptor);
}
// print notes for a given uid
// can match an optional search string
int print_notes(int file_descriptor, int uid, char *search_string) {
int note_length;
char byte = 0, note_buffer[100];
note_length = find_user_note(file_descriptor, uid);
// if EOF return 0
if (note_length == -1)
return 0;
read(file_descriptor, note_buffer, note_length); // read note data
note_buffer[note_length] = 0; // terminate string
// print note if search_string
if (search_note(note_buffer, search_string))
printf("------ [ note data ] ------\n");
printf(note_buffer);
printf("\n");
return 1;
}
// finds next note for given uid
int find_user_note(int file_descriptor, int user_uid) {
int note_uid = -1;
unsigned char byte;
int length;
while (note_uid != user_uid) {
if (read(file_descriptor, ¬e_uid, 4) != 4) // read uid data
return -1;
if (read(file_descriptor, &byte, 1) != 1) // read newline separator
return -1;
byte = length = 0;
while (byte != '\n') {
if (read(file_descriptor, &byte, 1) != 1) // read a single byte
return -1;
length++;
}
}
// rewind file by bytes length
lseek(file_descriptor, length * -1, SEEK_CUR);
printf("[DEBUG] found a %d byte note for user id %d\n", length, note_uid);
return length;
}
【问题讨论】:
-
你能告诉我们notetaker创建的数据文件包含什么吗?
-
是的,抱歉,省略了该信息,它仅包含在命令行中作为参数编写的文本,即 ./notetaker 'this is my note'
-
printf(note_buffer);这是一个非常不安全的操作,请执行printf("%s", note_buffer);so the problem I believe lies in the creation of the original file and its type- 所以用cat或任何文本编辑器检查文件也会发现问题? -
不,这就是我难以理解的,如果我
cat文件我可以看到纯文本,除了不可读的用户 ID,但如果我file文件它说'数据' -
数据文件应该由 { int, '\n' , string,\n'} 的块组成,混合文本和二进制,你可以在你创建的数据文件上运行
od在此处发布输出
标签: c