【问题标题】:C++ Strings in Read Function from fcntl.h从 fcntl.h 读取函数中的 C++ 字符串
【发布时间】:2014-09-23 08:44:45
【问题描述】:

在我大学的基础 Linux 编程课程中,我们使用 fcntl.h 和 unistd.h 使用 C++ 字符串,我得到以下信息:

statusOfFunction = write(fileDescriptor, input.c_str(), input.length());

这条线有效。我创建了一个文件,其中包含输入字符串的内容。但是,为什么这些行都不起作用:

statusOfFunction = read(fileDescriptor, reading.c_str(), 10);
Error: No matching function call to "read"

statusOfFunction = read(fileDescriptor, reading, 10);
Error: No matching function call to "read"

statusOfFunction = read(fileDescriptor, &reading, 10);
No error throws up, but does not get executed

statusOfFunction = read(fileDescriptor, &reading.c_str(), 10);
Error: No matching function call to "read"

https://www.dropbox.com/s/lnw208uo3xurqxf/Basic%20Unix%20Operations%20on%20Text%20Files.cpp?dl=0

这是程序,供您参考。 谢谢! :)

【问题讨论】:

  • reading 是什么?您需要将原型与read 匹配,根据man 2 readssize_t read(int fd, void *buf, size_t count);,因此您需要读取一个指向缓冲区的空指针,该缓冲区足够大以容纳10 个字节(或您的count 是什么)。
  • 在您的基础 Linux 编程课程中,他们还没有了解 const 的含义吗?

标签: c++ unix fcntl unistd.h


【解决方案1】:

read 需要一个缓冲区来填充读取的数据。

你的行为很危险。

您应该分配一个字符缓冲区并确保在字符串长度后添加 NULL 字符,因为read 不会为您执行此操作。 c_str 函数公开了字符串类使用的内部缓冲区。它是只读的。

覆盖字符串对象本身在以后使用时肯定会导致崩溃。

char buff[11];
size_t bytes_read = read(fd, buff, 10);
buff[bytes_read] = 0; // terminate string
string myString(buff);

【讨论】:

  • 谢谢你的回答 :) 那么,在 Unix 库中使用 C++ 字符串是不是更可取?
  • 不推荐您使用它们的方式。有用于 I/O 的 C++ 类。将低级 C 函数与字符串类混合是危险的。在任何情况下 c_str() 返回一个 const 数组 - 所以你永远不应该修改它。
  • C++ I/O 也可以用于 Unix 吗?
  • C++ IO 类在 Linux 和 Unix 上运行良好。
  • 哇。在印度,就 Unix 编程而言,唯一的答案是 C。猜猜冒险有帮助 谢谢! ☺️
【解决方案2】:

第一个问题

statusOfFunction = read(fileDescriptor, reading.c_str(), 10);

c_str 被声明返回一个 const 指针。否则这是接近正确的方法。

首先你需要创建一个至少包含 10 个字符的字符串:

std::string temp_string(10, ' ');  // Creates a string contains 10 spaces

然后你需要传递一个非常量指针,你可以通过地址操作符&和字符串数组索引操作符[]得到:

statusOfFunction = read(fileDescriptor, &temp_string[0], temp_string.length());

最后你将它分配给实际的字符串:

reading = std::string(temp_string, 0, statusOfFunction);

当然,你应该检查statusOfFunction,所以它不是错误(当它-1)或文件结尾(当它0)。


您尝试阅读的所有其他方法都非常错误。

【讨论】:

  • 还是不行 :( dropbox.com/s/lnw208uo3xurqxf/… 请检查代码。我哪里错了吗?
  • @NadeemAhmedNajeeb 对于初学者,您错过了我告诉您创建字符串并为其分配内存的地方。您在链接代码中所做的操作会被读入一个空字符串,从而导致未定义的行为。
  • 我试过了,但我也得到了一个错误:std::string sample(10);没有匹配的初始化构造函数另外,我尝试使用 sample[10],认为 [] 可能被重载。原来我也错了
  • @NadeemAhmedNajeeb 对不起,我忘了构造函数需要额外的参数,更新的答案。这里的主要问题是您将std::string 用于并非真正设计的东西。而operator[] std::string类中重载,请阅读链接参考。
  • 约阿希姆,非常感谢! :) 我在代码中遗漏了两件事,您都已纠正: 1 遗漏:lseek(fileDescriptor, 0, SEEK_SET); 2 构造函数中缺少的参数
猜你喜欢
  • 2019-05-05
  • 1970-01-01
  • 1970-01-01
  • 2018-10-23
  • 1970-01-01
  • 1970-01-01
  • 2020-01-23
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多