使用 write() 将用户输入的 char* 写入文件
Use write() to write char* to file from user input
我正在尝试编写一个函数,该函数从标准输入获取路径并将该路径保存到文件中。
尽管尝试了很多次,但我对如何正确地做这件事已经失去了任何感觉。有人可以告诉我如何做对吗?
这是我的代码:
void char_to_file(const char *pathname, const char *dest)
{
int fd_1;
if (fd_1 = open(dest, O_WRONLY | O_CREAT | O_TRUNC, 0666) == -1)
custom_error_shout("OPEN FD_1");
while (*(pathname) != '[=10=]')
{
*(pathname++);
if (write(fd_1, &pathname, 1) == -1)
custom_error_shout("WRITE TO FILE");
}
if (close(fd_1) == -1)
custom_error_shout("CLOSE FD_1");
}
将创建文件,但不会写入任何内容。没有出现错误。
您确实选择了艰难的方式来做到这一点。就像@tadman 在评论中建议的那样,试试这个:
void char_to_file(const char *pathname, const char *dest)
{
FILE *fp;
fp = fopen(dest, "w");
if (fp == NULL)
{
custom_error_shout("Something went wrong opening the file");
return;
}
if (fputs(pathname, fp) == EOF)
custom_error_shout("Something went wrong writing to the file");
fclose(fp);
}
没有写入任何内容的原因是您将 fd_1
重置为条件 open(..) == -1
的结果,除非打开失败意味着结果将是 0
(STDIN_FILENO
).如果 open()
确实失败并且 returns -1
,那么 fd_1
将等于 1
(STDOUT_FILENO
)。所以你正在尝试 write
到 stdin
除非 open()
失败。
这是因为您未能将您的作业括在括号中,例如if (fd_1 = open() == -1)
-- 应该是 if ((fd_1 = open()) == -1)
。否则 ==
(关系运算符)的 operator precedence 高于 =
(简单赋值),open(..) == -1
的结果赋值给 fd_1
.
要更正此问题,您需要:
if ((fd_1 = open(dest, O_WRONLY | O_CREAT | O_TRUNC, 0666)) == -1)
(注意:您选择mode
或0666
将受制于系统umask
并且可能会产生实际权限的 0644
。参见 man 2 umask)
您的 write
命令应该传递第一个字符的地址,而不是指向该地址的指针,例如
if (write(fd_1, pathname, 1) == -1)
您应该启用编译器警告。例如。 -Wall -Wextra -pedantic
用于 gcc/clang 或 /W3
用于 VS(对于其他编译器,请检查选项)。启用警告后,您应该会收到有关 未使用计算值 的警告:
*(pathname++);
要使指针前进,只需使用pathname++;
。如果没有分配或以其他方式使用结果,则取消引用结果没有任何意义。
如果 pathname
或 dest
中的字符串没有其他问题,并且您的错误宏可以正常工作——那么这应该可以解决您的问题。 (注意,使用 fopen
和 fputs()
等文件流操作更有意义)。
如果您还有其他问题,请告诉我。
我正在尝试编写一个函数,该函数从标准输入获取路径并将该路径保存到文件中。 尽管尝试了很多次,但我对如何正确地做这件事已经失去了任何感觉。有人可以告诉我如何做对吗? 这是我的代码:
void char_to_file(const char *pathname, const char *dest)
{
int fd_1;
if (fd_1 = open(dest, O_WRONLY | O_CREAT | O_TRUNC, 0666) == -1)
custom_error_shout("OPEN FD_1");
while (*(pathname) != '[=10=]')
{
*(pathname++);
if (write(fd_1, &pathname, 1) == -1)
custom_error_shout("WRITE TO FILE");
}
if (close(fd_1) == -1)
custom_error_shout("CLOSE FD_1");
}
将创建文件,但不会写入任何内容。没有出现错误。
您确实选择了艰难的方式来做到这一点。就像@tadman 在评论中建议的那样,试试这个:
void char_to_file(const char *pathname, const char *dest)
{
FILE *fp;
fp = fopen(dest, "w");
if (fp == NULL)
{
custom_error_shout("Something went wrong opening the file");
return;
}
if (fputs(pathname, fp) == EOF)
custom_error_shout("Something went wrong writing to the file");
fclose(fp);
}
没有写入任何内容的原因是您将 fd_1
重置为条件 open(..) == -1
的结果,除非打开失败意味着结果将是 0
(STDIN_FILENO
).如果 open()
确实失败并且 returns -1
,那么 fd_1
将等于 1
(STDOUT_FILENO
)。所以你正在尝试 write
到 stdin
除非 open()
失败。
这是因为您未能将您的作业括在括号中,例如if (fd_1 = open() == -1)
-- 应该是 if ((fd_1 = open()) == -1)
。否则 ==
(关系运算符)的 operator precedence 高于 =
(简单赋值),open(..) == -1
的结果赋值给 fd_1
.
要更正此问题,您需要:
if ((fd_1 = open(dest, O_WRONLY | O_CREAT | O_TRUNC, 0666)) == -1)
(注意:您选择mode
或0666
将受制于系统umask
并且可能会产生实际权限的 0644
。参见 man 2 umask)
您的 write
命令应该传递第一个字符的地址,而不是指向该地址的指针,例如
if (write(fd_1, pathname, 1) == -1)
您应该启用编译器警告。例如。 -Wall -Wextra -pedantic
用于 gcc/clang 或 /W3
用于 VS(对于其他编译器,请检查选项)。启用警告后,您应该会收到有关 未使用计算值 的警告:
*(pathname++);
要使指针前进,只需使用pathname++;
。如果没有分配或以其他方式使用结果,则取消引用结果没有任何意义。
如果 pathname
或 dest
中的字符串没有其他问题,并且您的错误宏可以正常工作——那么这应该可以解决您的问题。 (注意,使用 fopen
和 fputs()
等文件流操作更有意义)。
如果您还有其他问题,请告诉我。