使用 read() 扫描字符数组



>我可以通过在函数中使用读取方法来设置 char 数组吗?我尝试了下面的方法,但没有产生任何效果。对我来说,我在method()参数中拿一个指针,我通过read()将数据保存到其中,然后我只是将参数的地址"给出"到文本。 不要怪我,我以前用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"

最简单的解决方案:使method要求(通过文档保证,因为 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"

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

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

或者继续使用当前分离的缓冲区,并在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"

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

最后,一个保持安全的解决方案,同时不需要您向method添加返回值:

/* ...
* 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] = '';
// Or the one-liner for people who don't believe in error handling: :-)
// text[read(STDIN_FILENO, text, 100)] = '';
}

然后调用方可以假定他们的缓冲区最多为 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"

最新更新