【问题标题】:Trying to take multiple string inputs尝试接受多个字符串输入
【发布时间】:2014-10-28 17:59:43
【问题描述】:

练习.c

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define ARR 32

int main(void){

  int MEM=64;
  char arr[ARR],*p=(char *)calloc(MEM,(sizeof(char))),*q=NULL;
  int i=0,j=1;

  printf("\nEnter String : ");

  while(j){

    scanf(" %[^\n]s " ,arr);

    if(j==1)
      strcpy(p,arr);
    else
      strcat(p,arr);


    if((j*ARR)==MEM){
      MEM=MEM+(j*ARR);
      q=realloc(p, MEM);
      if(!(q)){
        printf("\nNOT ENOUGH MEMORY\n");
        goto END;
      }
      p=q;
    }


    for(i=0;i<(strlen(arr));++i){
      if(arr[i]=='\n')
        break;
    }


    if(arr[i]=='\n')
      break;


    ++j;
  }

  printf("\n %s\n",p);


  END: free(p);p=NULL;q=NULL;

  return 0;
}

我正在尝试获取多个字符串输入。

我使用scanf(" %[^\n]s",arr); 而不是fgets(arr,ARR,stdin); 来获取输入,因为使用fgets,一旦我点击ENTER key,程序执行就会停止。但是使用scanf(" %[^\n]s",arr);,即使输入\n,程序也无法退出while() loop

我想知道我在编写代码时犯的一个或多个错误。

【问题讨论】:

  • @Ani 这个arr[strlen(arr)-1]='\0';可以和scanf(" %[^\n]s",arr);一起使用吗?
  • 您是否要读取多条输入?或者只是在一行中有多个空格分隔的“单词”?
  • @JoachimPileborg Read multiple lines of input.
  • @Ani 它不起作用,无论是 fgets 还是 scanf。之前fgets使用按ENTER key退出执行,现在进入死循环。

标签: c string dynamic-memory-allocation realloc


【解决方案1】:

在 C 中读取多行输入的规范方法是在循环中使用fgets,例如

while (fgets(arr, sizeof(arr), stdin) != NULL)
{
    if (arr_contains_special_input_to_exit_loop(arr))
        break;

    // Optionally check for and remove trailing newline from input

    // Append `arr` to your data
}

退出循环的条件可能是一些特殊的输入或空行或其他完全的东西。

【讨论】:

  • if() 中将使用什么确切条件?
【解决方案2】:

一个错误是:

for(i=0;i<(strlen(arr));++i){
  if(arr[i]=='\n')
    break;
}

查看之前的代码:

scanf(" %[^\n]s " ,arr);

[^\n] 防止任何换行符\n 包含在arr 中。因此,您查找 (arr[i]=='\n') 的循环将永远找不到。你的下一段代码继续寻找不存在的newlines

if(arr[i]=='\n')
  break;

最后一个break 也打破了你的外循环,阻止你在寻找换行符时要求进一步的输入(它不应该)。修复这些问题,它应该会进一步允许您输入多个项目。


编辑:

通过一些努力查看您在做什么,我现在让它接受多个输入并根据需要重新分配。字符串全部连接并在最后打印。它仍然可以做一些工作,但这应该会给你一些提示:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define ARR 32

int main (void) {

    int MEM = 64;
    char arr[ARR], *p = (char *) calloc (MEM, (sizeof (char))), *q = NULL;
    int i = 0, j = 1;


    while (j) {

        printf ("\nEnter String : ");
        scanf (" %[^\n]s ", arr);
        printf (" you entered (arr): %s\n", arr);
        if (strcmp (arr, "q") == 0) {
            printf ("\n  'q' entered, exiting.\n\n"); // provide for exit if `q` entered
            break;
        }

        if (j == 1)
            strcpy (p, arr);
        else
            strcat (p, arr);

        if ((j * ARR) == MEM) {
            MEM = MEM + (j * ARR);
            q = realloc (p, MEM);
            if (!q) {
                printf ("\nNOT ENOUGH MEMORY\n");
                goto END;
            }
            else
                printf ("\nMemory Reallocation - succeeded.\n");
            p = q;
        }
        ++j;
    }

    printf (" %s\n", p);

END:
    if (p) free (p);  /* always test pointer before calling free */
    p = NULL;
    q = NULL;

    return 0;
}

输出:

./bin/me

Enter String : fishinsea
  you entered (arr): fishinsea

Enter String : alligators
  you entered (arr): alligators

Memory Reallocation - succeeded.


Enter String : really_big_mosters
  you entered (arr): really_big_mosters

Enter String : SuperSnake_Prudhome
  you entered (arr): SuperSnake_Prudhome

Memory Reallocation - succeeded.

Enter String : 8_puppies
  you entered (arr): 8_puppies

Enter String : q
  you entered (arr): q

  'q' entered, exiting.

fishinseaalligatorsreally_big_mostersSuperSnake_Prudhome8_puppies

【讨论】:

  • 我将scanf(" %[^\n]s",arr); 替换为fgets(arr,ARR-1,stdin);,但程序仍然进入无限循环。您建议如何克服这个问题?
  • 您需要在点击返回后刷新仍包含“换行符”的输入缓冲区。声明一个假人int c;。在 fgets 之后,只需添加行 do { c=getchar(); } while ((c != '\n') || (c == EOF));
  • 在这段代码中:for (i = 0; i &lt; (strlen (arr)); ++i) { if (arr[i] == '\n') break; } if (arr[i] == '\n') break; 当我们不使用\n 作为转义字符时,为什么我们还在for loop 中使用它来检查条件?
  • 没必要——你可以扔,我只是不想扔掉,你想知道为什么。我会编辑并删除它。
  • 这是苏格拉底方法。你对每一个正确答案的奖励是——另一个问题。继续努力。
猜你喜欢
  • 2019-10-24
  • 1970-01-01
  • 2014-02-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-05-05
  • 2022-06-17
  • 1970-01-01
相关资源
最近更新 更多