我知道如何使用内部,用户输入(当前正在使用scanf)进行int,double,float函数。
int getData(){
int a;
scanf("%i",&a);
return a;
}
但是如何在内部使用字符串类型和用户输入来创建函数,然后我们使用字符串类型返回该值?
答案 0 :(得分:3)
C字符串是由NUL(零)字节终止的char
数组。数组通常作为第一个元素的指针传递。从函数返回该值的问题在于,指向的地址必须在该函数的生存期内保持有效,这意味着它必须是static
缓冲区(然后,对该缓冲区的任何后续调用都将其覆盖)函数,打破先前返回的值)或由函数分配,在这种情况下,调用者负责释放它。
您提到的scanf
对于读取交互式用户输入也是有问题的,例如,它可能会使输入处于意外状态,例如当您在行末不使用换行符时, {1>}的下一个调用(可能是不相关的函数)在遇到换行符时可能无法给出预期的结果。
通常更容易地将输入逐行读取到缓冲区中,例如使用scanf
,然后从那里解析该行。 (某些输入您可能只需要逐个字符地读取就可以在没有缓冲区的情况下进行解析,但是这样的代码通常很长且很难快速理解。)
读取任何可能包含除换行符以外的空格的字符串的示例如下:
fgets
另一种选择是让调用者提供缓冲区及其大小,然后在成功时返回相同的缓冲区,而在失败时返回/// Read a line from stdin and return a `malloc`ed copy of it without
/// the trailing newline. The caller is responsible for `free`ing it.
char *readNewString(void) {
char buffer[1024];
if (!fgets(buffer, sizeof buffer, stdin)) {
return NULL; // read failed, e.g., EOF
}
int len = strlen(buffer);
if (len > 0 && buffer[len - 1] == '\n') {
buffer[--len] = '\0'; // remove the newline
// You may also wish to remove trailing and/or leading whitespace
} else {
// Invalid input
//
// Depending on the context you may wish to e.g.,
// consume input until newline/EOF or abort.
}
char *str = malloc(len + 1);
if (!str) {
return NULL; // out of memory (unlikely)
}
return strcpy(str, buffer); // or use `memcpy` but then be careful with length
}
。这种方法具有
这样做的好处是,调用方可以决定何时重新使用缓冲区以及是否需要复制字符串,还是只需读取一次并忘记该字符串。
答案 1 :(得分:0)
将Arkku的方法扩展为无限制大小(实际上,它限制为SIZE_MAX-1个字符)作为输入:
#include <stdlib.h>
#include <string.h>
#define BUFFER_MAX (256)
int read_string(FILE * pf, char ** ps)
{
int result = 0;
if (!ps)
{
result = -1;
errno = EINVAL;
}
else
{
char buffer[BUFFER_MAX];
size_t len = 0;
*ps = NULL;
while (NULL != fgets(buffer, sizeof buffer, pf))
{
len += strlen(buffer);
{
void * p = realloc(*ps, len + 1);
if (!p)
{
int es = errno;
result = -1;
free(*ps);
errno = es;
break;
}
*ps = p;
}
strcpy(&(*ps)[len], buffer);
}
if (ferror(pf))
{
result = -1;
}
}
return result;
}
这样称呼它:
#include <stdlib.h>
#include <stdlio.h>
int read_string(FILE * pf, char ** ps);
int main(void);
{
char * p;
if (-1 == read_string(stdin, &p)) /* This read from standard input,
still any FILE* would do here. */
{
perror("read_string() failed");
exit(EXIT_FAILURE);
}
printf("Read: '%s'\n", p);
free(p); /* Clean up. */
}