简体   繁体   English

如何通过终端将段落作为 C 中的单个字符串读取?

[英]How can I read a paragraph in via the terminal as a single string in C?

I'm writing a C program that should read in an essay from a user.我正在编写一个 C 程序,该程序应该从用户的一篇文章中读取。 The essay is divided into multiple paragraphs.文章分为多个段落。 I don't know how many lines or characters the essay will be, but I do know that it ends with a hash symbol ( # ).我不知道这篇文章有多少行或字符,但我知道它以哈希符号 ( # ) 结尾。 I want to use only as much memory as is necessary to hold the essay.我只想使用保存文章所需的内存。

Here is what I have tried so far:这是我迄今为止尝试过的:

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


main(){

    int size;
    char *essay;

    printf("\n how many characters?\n");
    scanf("%d", &size);
    essay =(char *) malloc(size+1);
    printf("Type the string\n");
    scanf("%s",essay);

    printf("%s",essay );

}

As I said before, I don't know (and don't want to ask) about the number of characters beforehand.正如我之前所说,我事先不知道(也不想询问)字符数。 How do I dynamically allocate memory to save space?如何动态分配内存以节省空间? (What is dynamic memory allocation?) Is there another way to save memory that doesn't rely on dynamic allocation? (什么是动态内存分配?)有没有另一种不依赖动态分配的方式来节省内存?

Additionally, my code only reads one line at a time right now.此外,我的代码现在一次只读取一行。 How can I read multiple lines and store them as a single string?如何读取多行并将它们存储为单个字符串?

this is another code这是另一个代码

#include <stdio.h>    
#include <stdlib.h>    
int main ()
{
  char input;
  int count = 0;
int n;
  char* characters= NULL;
  char* more_characters = NULL;
  do {
     printf ("type the essay:\n");
     scanf ("%d", &input);
     count++;

       more_characters = (char*) realloc (characters, count * sizeof(char));
      if (more_characters!=NULL) {
       characters=more_characters;
       characters[count-1]=input;  }
     else {
       free (characters);
       printf ("Error (re)allocating memory");
       exit (1);
     }
  } while (input!='#');

printf ("the essay: ");
    for (n=0;n<count;n++) printf ("%c",characters[n]);
    free (characters);
   }

it is not working它不工作

You can read character at a time and copy it into your essay buffer.您可以一次读取字符并将其复制到您的论文缓冲区中。 When your essay buffer runs out of space, you can do a realloc to get another chunk of memory.当您的论文缓冲区空间不足时,您可以执行重新分配以获取另一块内存。 When your character that you read is a "#" you're done.当您读取的字符是“#”时,您就完成了。

Hmmm to "not waste space in memory",嗯,“不要浪费内存空间”,

then how about excessive calls of realloc() ?那么过度调用realloc()呢?

char *Read_Paragraph_i(void) {
  size_t size = 0;
  size_t i = 0;
  char *dest = NULL; 
  int ch;
  while ((ch = fgetc(stdin)) != EOF) {
    if (ch == '#') break;
    size++;
    char *new_ptr = realloc(dest, size);
    assert(new_ptr);
    dest = new_ptr;
    dest[i++] = ch;
  }
  size++;
  char *new_ptr = realloc(dest, size+);
  assert(new_ptr);
  dest = new_ptr;
  dest[i++] = '\0';
  return dest;
}

A more sane approach would double the allocation size every time more memory is need, temporally wasting memory and then a final "right-size" allocation.每次需要更多内存时,更明智的方法是将分配大小加倍,暂时浪费内存,然后是最终的“正确大小”分配。

If this can use C++, you can use string (std::string) which will grow as needed as characters are added.如果这可以使用 C++,您可以使用 string (std::string),它会随着添加字符的需要而增长。 If you can't then you will have to use malloc to create an array to hold characters.如果你不能,那么你将不得不使用 malloc 创建一个数组来保存字符。 When it is full, you will have to create a new one, and copy the current data from old to new one, then add the new character.当它已满时,您将不得不创建一个新的,并将当前数据从旧的数据复制到新的数据,然后添加新字符。 You can do that on each character read to use the minimal amount of memory, but that is WAY too inefficient.您可以对读取的每个字符执行此操作以使用最少的内存,但这效率太低了。 A better way is to allocate the character array in chucks, keeping the current size, and the number of characters currently in it.更好的方法是在chucks 中分配字符数组,保持当前大小,以及当前其中的字符数。 When you want to add another character and the array is full, then you allocate a new one that is some number of characters larger than current one, update current size to size of new one, then add new character.当您想添加另一个字符并且数组已满时,您分配一个比当前字符数大一些的新字符,将当前大小更新为新字符的大小,然后添加新字符。

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

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