【问题标题】:How can I read a paragraph in via the terminal as a single string in C?如何通过终端将段落读取为 C 中的单个字符串?
【发布时间】:2015-11-10 19:37:06
【问题描述】:

我正在编写一个 C 程序,它应该从用户的文章中读取。论文分为多个段落。 我不知道这篇文章有多少行或多少个字符,但我知道它以井号结尾(#)。我只想使用尽可能多的内存来保存这篇文章。

这是我迄今为止尝试过的:

#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 );

}

正如我之前所说,我事先不知道(也不想问)字符数。如何动态分配内存以节省空间? (什么是动态内存分配?)还有另一种不依赖动态分配的内存节省方式吗?

此外,我的代码现在一次只能读取一行。如何读取多行并将它们存储为单个字符串?

这是另一个代码

#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);
   }

它不工作

【问题讨论】:

  • "还有其他节省内存空间的方法吗?"压缩。在您完全熟悉动态分配之前,我真的不能推荐它作为一种技术。 “我如何读取多行并将其存储在单个字符串中?”如果您愿意用简单性换取长期的低性能:使用realloc
  • "我的代码只读了一行" __> 我不同意,它读的是一个单词,因为任何空格都会停止进一步阅读。
  • 使用getdelim
  • 注意:more_characters = (char*) realloc (characters, count * sizeof(char));可以简化为more_characters = realloc(characters, count);

标签: c string scanf


【解决方案1】:

您可以一次读取字符并将其复制到您的论文缓冲区中。当您的文章缓冲区空间不足时,您可以执行重新分配以获取另一块内存。当你读到的字符是“#”时,你就完成了。

【讨论】:

  • 什么是缓冲区。我只知道如何使用scanf从用户那里读取
  • 您可以使用 getc 一次读取一个字符。它仍在使用缓冲 IO。
【解决方案2】:

嗯,“不浪费内存空间”,

那么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;
}

更合理的方法是每次需要更多内存时将分配大小加倍,暂时浪费内存,然后进行最终的“正确大小”分配。

【讨论】:

  • 有很多函数我们没有研究它有没有其他方法可以使用 scanf 或 gets() 或任何基本函数?还有什么是数据类型 siz_t
  • @user5517410 如果答案需要限制,请在帖子中列出限制。
【解决方案3】:

如果这可以使用 C++,您可以使用字符串 (std::string),它会随着字符的添加而按需增长。如果你不能,那么你将不得不使用 malloc 创建一个数组来保存字符。当它已满时,您将不得不创建一个新的,并将当前数据从旧的复制到新的,然后添加新角色。您可以对读取的每个字符执行此操作以使用最少的内存,但这太低效了。更好的方法是在chucks 中分配字符数组,保持当前大小和当前在其中的字符数。当您想添加另一个字符并且数组已满时,您可以分配一个比当前字符大一些的新字符,将当前大小更新为新字符的大小,然后添加新字符。

【讨论】:

  • 或像@bruceg 所说,使用 realloc 创建新缓冲区,因为它会为您完成复制。
  • @user5517410 不确定你是否投反对票,但我确实在 C 中提供了解决方案
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-08-22
相关资源
最近更新 更多