我可以在函数中使用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;
}
在main中:
char c[100];
method(c);
printf("%s",c); // should print "sth"
答案 0 :(得分:1)
最简单的解决方案:使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] = '\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"