是否有任何函数可以从标准输入中获取无限的输入字符串

时间:2014-12-14 04:39:57

标签: c input char scanf gets

条件是:

我想从标准输入中输入一行,我不知道它的大小,也许很长。

像<{1}}这样的方法,scanf需要知道您输入的最大长度,以便您的输入大小小于缓冲区大小。

那么有什么好方法可以解决它吗?

答案必须只在C中,而不是C ++ ,所以c ++字符串不是我想要的。我想要的是C标准字符串,类似gets,以char*结尾。

5 个答案:

答案 0 :(得分:7)

C标准没有定义这样的功能,但是POSIX没有。

getline函数,documented here(或者如果您使用的是类UNIX系统,则键入man getline)可以满足您的要求。

可能无法在非POSIX系统(例如MS Windows)上使用。

一个演示其用法的小程序:

#include <stdio.h>
#include <stdlib.h>
int main(void) {
    char *line = NULL;
    size_t n = 0;
    ssize_t result = getline(&line, &n, stdin);
    printf("result = %zd, n = %zu, line = \"%s\"\n", result, n, line);
    free(line);
}

fgets一样,'\n'换行符留在数组中。

答案 1 :(得分:4)

一种方法是使用getchar运行循环并继续将字符放入数组中。数组填满后,realloc将其更大一些。

答案 2 :(得分:0)

conversion specification内经常会忽略scanf,它将分配足以保存字符串输入的内存,而不管长度如何。较新版本的scanf为此目的使用m旧版本使用了a。例如:

#include <stdio.h>
#include <stdlib.h>

int main (void) {
    char *str = NULL;
    printf (" enter a string of any length, whitespace is OK: ");
    scanf ("%m[^\n]%*c", &str);
    printf ("\n str: %s\n\n", str);
    if (str) free (str);
    return 0;
}

注意: scanf需要char **指针参数来接收分配的字符串。另外 note scanf不会在存储的字符串中包含'\n'。进一步注意%*c接收并丢弃'\n'字符以防止换行符保留在输入缓冲区中。您也可以在转换说明符前面加上空格,以跳过输入缓冲区中可能存在的任何/所有空格。

最后注意:有报告称并非scanf的所有实施都提供此功能。 (这也可能是m/a更改的混淆)检查您的实施。

答案 3 :(得分:0)

其中一个方法是使用getchar()函数,我们可以在字符中获取输入并将其传递给动态创建的数组。您可以看到,当它超过我们设置的默认长度时,我们重新分配了用于存储字符的空间

#include<stdio.h>
#include<stdlib.h>

void main(){
    int size = 10;
    char* str;
    str = (char*) calloc(size,sizeof(char));
    char c;
    c = getchar();
    int t = 0;
    int cnt = 0;
    int len;

    while(c!='\n') {
        if(cnt > size) {
            str = (char*) realloc(str,2*cnt);
        }

        str[t] = c;
        c = getchar();
        t++;
        cnt++;
    }
        str[t]='\0';
    printf("The string is %s\n",str);
    len = strlen(str);
    printf("The size is %d",len);
}

答案 4 :(得分:0)

使用getcharmallocrealloc来读取无限制的输入字符串

声明字符串类型,也可以使用char *

// String type
typedef char *String;

我编写了此函数,用于在字符串末尾加入char

/**
 * Join the Char into end of String
 *
 * @param string - String
 * @param c - joined char
 */
void String_joinChar(String *string, const char c)
{
  const size_t length = strlen(*string);
  (*string) = (String)realloc((*string), sizeof(char) * (length + 2));
  (*string)[length] = c;
  (*string)[length + 1] = '\0';
}

此函数用于输入字符串,该函数使用getchar从键盘读取字符,并将其连接到当前字符串的末尾。

/**
 * Input String
 *
 * @return Inputed String
 */
String String_input()
{
  String string = (String)malloc(sizeof(char));
  strcpy(string, "");

  char cursor;
  fflush(stdin);
  while ((cursor = getchar()) != '\n' && cursor != EOF)
  {
    String_joinChar(&string, cursor);
  }

  return string;
}

由于使用char *mallocrealloc,我们必须释放它

/**
 * Destroy String
 *
 * @param string - Destroyed String
 */
void String_destroy(String string)
{
  free(string);
}

现在我们只用它!

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main()
{
  String string = String_input();
  printf("\n%s\n", string);
  String_destroy(string);
  return 0;
}

希望对您有用!