【问题标题】:Dynamically read user input strings in C [duplicate]在C中动态读取用户输入字符串[重复]
【发布时间】:2016-11-07 18:55:14
【问题描述】:

给定一个未知长度的用户输入(由最大长度为 100 的单词组成)。有没有办法逐个字符串动态读取它?

我的理解是 scanf 读取一个字符串直到到达一个空格,所以我尝试使用 scanf 但它进入了一个无限循环。

char buf[101];
while (scanf("%s", buf))
{
    //something is done with the string
}

【问题讨论】:

  • while (scanf("%100[^\n]%*c", buf)) { ... } NO ';' 在结束后)
  • @David C. Rankin scanf("%100[^\n]%*c" 如果第一个字符是 '\n',则不会读取任何内容。
  • 您是否尝试过while (scanf("%100s", buf) == 1) 一次读取单词
  • 是的,如果您想以'\n' 开头,您可以在% 之前添加一个空格。 (哦,没关系,我以为他在阅读带空格的单词时遇到了问题,不想标记行......)

标签: c


【解决方案1】:

我认为你需要这样的东西。

while (scanf("%s", code) == 1)
{
    // no need for second scanf call
    // do whatever you like here
}  

编辑:试试这个。

freopen("input.txt","r",stdin);
//Above line makes program to take input from file.
//File should be present in same folder
char c[50];
while(scanf("%s",c)!=EOF)
{
    printf("%s\n",c);
}

【讨论】:

  • 我尝试了== 1和> 0,它仍然进入无限循环..
  • 那是因为你将'\n' 留在stdin 中,因为scanf%s 会读到下一个'\n'(好吧,你知道故事的其余部分——现在)
  • 检查我编辑的答案
  • 它到达输入的末尾,然后再次等待输入。我不知道用什么条件让它打破循环。
  • scanf("%s",c)gets(c) 一样安全。两者都不应使用。
【解决方案2】:

我找到了解决办法!

while (scanf("%s%c", buf, &c))
    {
        //do something with the string
        if (c == '\n') break;
    }

【讨论】:

  • scanf("%s%c", buf, &c) 返回 1 或 EOF 时会发生什么? if (c == '\n') 可以安全执行吗?
  • 不清楚为什么代码停在'\n',因为帖子说“给定长度未知的用户输入”,可能有很多行输入。
  • Is there a way to read it dynamically string by string? 但您对问题的解决方案不是动态的.. @lezlemon
  • @CherubimAnand 也许我没有说清楚,它会读取字符串,直到达到我想要的 '\n'。单个字符串的最大长度是已知的,但它们的数量是未知的。
  • @chux 我应该更清楚。输入将始终是由空格分隔的字符串(单词),直到它达到'\ n',因此 c 将等于' ',直到达到行尾,即输入的结尾,出于我的目的.
【解决方案3】:

给定一个未知长度的用户输入(由最大长度为 100 的单词组成),有没有办法逐个字符串地动态读取它?

构建自己的函数,而不是 scanf 将有助于实现这一目标

  • 在这里,我创建了一个函数scan,它会通过在每次迭代中增加字符串的大小来动态接收字符串

  • 我使用了额外的头文件string.hstdlib.h,原因如下:

    1. stdlib.h 中的函数(点击了解更多)库文件可用于动态分配内存。

    2. string.h 中的函数(点击了解更多)库文件可用于处理字符串

注意:用户输入字符串end时停止输入。

#include <stdio.h>  //the standard library file
#include <stdlib.h> //library file useful for dynamic allocation of memory
#include <string.h> //library file with functions useful to handle strings

//the function    
char* scan(char *string)
{
    int c; //as getchar() returns `int`
    string = malloc(sizeof(char)); //allocating memory

    string[0]='\0';

    for(int i=0; i<100 && (c=getchar())!='\n' && c != EOF ; i++)
    {
        string = realloc(string, (i+2)*sizeof(char)); //reallocating memory
        string[i] = (char) c; //type casting `int` to `char`
        string[i+1] = '\0'; //inserting null character at the end
    }

    return string;
}

int main(void)
{
    char *buf; //pointer to hold base address of string

    while( strcmp((buf=scan(buf)),"end") ) //this loop will continue till you enter `end`
    {
        //do something with the string

        free(buf); //don't forget to free the buf at the end of each iteration
    }

    free(buf); //freeing `buf` for last input i.e, `end` 

}

让我们//do something with the string 看看上面的代码是否有效:)

我在 main 函数中更改了以下 while 循环:

    while( strcmp((buf=scan(buf)),"end") )
    {
        //do something with the string
    }

while( strcmp((buf=scan(buf)),"end") )
{
    printf("you entered : %s\n",buf);
    printf("size        : %u\n",strlen(buf));
    printf("reversing   : %s\n",strrev(buf));

    printf("\n-------------------\n");

    free(buf);
}

现在,

输入:

hall
of
fame
stay in it
end

输出:

you entered : hall
size        : 4
reversing   : llah

-------------------
you entered : of
size        : 2
reversing   : fo

-------------------
you entered : fame
size        : 4
reversing   : emaf

-------------------
you entered : stay in it
size        : 10
reversing   : ti ni yats

-------------------

【讨论】:

  • 不是 OP 真正关心的问题,但请考虑 i&lt;100 &amp;&amp; (c=getchar())!='\n' 而不是 (c=getchar())!='\n' &amp;&amp; i&lt;100。如果没有空间,为什么要阅读并丢弃一个字符?最好下次再读。
  • EOF 表示输入错误或文件结束(不再输入)。读取循环应该有 3 个结束条件:i&lt;100 &amp;&amp; (c=getchar())!='\n' &amp;&amp; c != EOF。否则在文件末尾,代码将不断读取 100 EOF。这也意味着strcmp((buf=scan(buf)),"end") 是一个问题。如果"end" 不存在会怎样?调用代码如何区分只有"\n" 的行和文件结尾?祝你好运 +1。
  • 非常感谢您花时间解释@chux,您真的帮了我很多!你摇滚:)
猜你喜欢
  • 2019-02-01
  • 2011-04-30
  • 2011-12-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多