简体   繁体   English

如何在C中使用用户输入来使字符串函数?

[英]How to make string function with user input in C?

I know how to make function with int, double, float with user input inside(im currently using scanf). 我知道如何使用int,double,float和内部用户输入来实现函数(我目前正在使用scanf)。

int getData(){
    int a;
    scanf("%i",&a);
    return a;
}

but how to make function with string type and user input inside, then we return that value with type string? 但是如何使用字符串类型和内部用户输入来创建函数,然后我们使用字符串类型返回该值?

AC string is an array of char terminated by a NUL (zero) byte. AC字符串是由NUL(零)字节终止的char数组。 Arrays are normally passed around as pointers to the first element. 数组通常作为第一个元素的指针传递。 The problem with returning that from the function is that the address pointed to must remain valid beyond the lifetime of the function, which means it needs to be either a static buffer (which is then overwritten by any subsequent calls to the same function, breaking earlier returned values) or allocated by the function, in which case the caller is responsible for freeing it. 从函数返回该值的问题在于,指向的地址必须在该函数的生存期内保持有效,这意味着它必须是一个static缓冲区(然后被对该函数的任何后续调用所覆盖,这会更早中断)返回值)或由函数分配,在这种情况下,调用方负责释放它。

The scanf you mention is also problematic for reading interactive user input, eg, it may leave the input in an unexpected state such as when you don't consume the newline at the end of a line the next call to scanf (maybe in an unrelated function) may surprisingly fail to give the expected result when it encounters the newline. 您提到的scanf在读取交互式用户输入时也存在问题,例如,它可能会使输入处于意外状态,例如当您在一行的末尾不使用换行符时,对scanf下一次调用(可能是不相关的)函数)在遇到换行符时可能无法给出预期的结果。

It is often simpler to read input into a buffer line-by-line, eg, with fgets , and then parse the line from there. 将输入逐行读入缓冲区通常比较简单,例如使用fgets ,然后从那里解析该行。 (Some inputs you may be able to parse without a buffer simply by reading character by character, but such code often gets long and hard to follow quickly.) (某些输入您可能可以简单地通过逐个字符地读取而无需缓冲区来解析,但是这样的代码通常很长且很难快速地执行。)

An example of reading any string, which may contain whitespace other than the newline, would be something like: 读取任何可能包含除换行符以外的空格的字符串的示例如下:

/// 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
}

Another option is to have the caller supply the buffer and its size, then just return the same buffer on success and NULL on failure. 另一个选择是让调用方提供缓冲区及其大小,然后在成功时返回相同的缓冲区,而在失败时返回NULL This approach has the advantage that the caller may decide when a buffer is reused and whether the string needs to be copied or simply read once and forgotten. 这种方法的优势在于,调用方可以决定何时重用缓冲区以及是否需要复制字符串或仅读取一次并忘记该字符串。

Extending Arkku 's approach to an unlimited size (in fact it is limited to SIZE_MAX - 1 characters) as input: 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;
}

Call it like this: 这样称呼它:

#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. */
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM