gpt4 book ai didi

c - 使用 read() 扫描字符数组

转载 作者:行者123 更新时间:2023-11-30 14:52:49 25 4
gpt4 key购买 nike

我可以在函数中使用 read 方法设置 char 数组吗?我尝试了下面的方法,但没有任何效果。对我来说,我在 method() 参数中获取一个指针,我通过 read() 将数据保存到它,然后我只是将 args 的地址“给出”到文本。不要怪我,我以前用java编写代码,所以指针可能会使用错误,请注意我犯的每一个错误(请通知我)。

void method(char* text) {
char args[100];
int read = read(STDIN_FILENO, args, 100); // i write "sth" on keyboard
text = args;
}

在主要部分:

char c[100];
method(c);
printf("%s",c); // should print "sth"

最佳答案

最简单的解决方案:使方法要求(通过文档保证,因为C不能强制传递特定的数组大小)调用者提供大小为100的缓冲区,而不是维护本地和非本地缓冲区。您还需要返回 read 的结果,以便调用者知道他们收到了多少有效字节:

/* ...
* text - must point to at least 100 bytes of valid memory
* Returns number of read bytes
*/
int method(char* text) {
return read(STDIN_FILENO, text, 100); // i write "sth" on keyboard
}

并在main中:

char c[100];
// Store number of valid bytes available
int numvalid = method(c);
// Use .* to specify a dynamic maximum field width, so you don't have a read overflow
printf("%.*s", numvalid, c); // should print "sth"

其他方法包括让函数为调用者执行分配(调用者传递双指针并自行释放缓冲区):

int method(char** text) { // Receives double-pointer so it can change caller's char*
*text = malloc(100); // Dynamic allocation (add error checking)
return read(STDIN_FILENO, *text, 100); // i write "sth" on keyboard
}

char *c = NULL; // Pointer to be filled, not array
int numvalid = method(&c); // Pass address of pointer so method can change c
// Use .* to specify a dynamic maximum field width, so you don't have a read overflow
printf("%.*s", numvalid, c); // should print "sth"
free(c); // Free memory allocated by method

或者继续使用当前的独立缓冲区,并在方法通过memcpy(复制数据)退出之前从一个缓冲区复制到另一个缓冲区,而不是通过指针赋值(这不会改变调用者可见的任何内容):

int method(char* text) {
char args[100];
int read = read(STDIN_FILENO, args, 100); // i write "sth" on keyboard
// Copy data from args to text buffer
// Note: Using memcpy, *not* strcpy, because read provides no guarantees
// that the buffer will be NUL-terminated
memcpy(text, args, read);
return read; // Still need to return number of valid bytes
}

char c[100];
int numvalid = method(c);
printf("%.*s", numvalid, c); // should print "sth"

但是这种方法有点毫无意义; 方法仍然需要传递100字节的缓冲区才能安全运行,它只是不必要地将数据放在临时空间中,然后将其复制到最终目的地以浪费周期。

最后,一个仍然安全的解决方案,同时要求您向方法添加返回值:

/* ...
* text - must point to at least 100 bytes of valid memory
* On return, data is NUL-terminated, *unless* 100 non-NUL bytes were read
*/
void method(char* text) {
int numread = read(STDIN_FILENO, text, 100);
if (0 <= numread && numread < 100) text[numread] = '\0';

// Or the one-liner for people who don't believe in error handling: :-)
// text[read(STDIN_FILENO, text, 100)] = '\0';
}

然后调用者可以假设他们的缓冲区最多为 100 个字节,因此他们可以在 %s 格式代码上使用限制器以在 NUL 或之后停止100 字节,以先到者为准:

char c[100];
method(c);
// Use .100 to prevent read overflow, knowing that method NUL terminated
// anything shorter than 100 bytes (preventing undefined behavior reading
// uninitialized bytes for smaller reads)
printf("%.100s", c); // should print "sth"

关于c - 使用 read() 扫描字符数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47560121/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com