c - 读取多行直到 EOF
问题描述
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
//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;
}
char** bigScan(char **string)
{
int c;
string=malloc(sizeof(char *));
string[0]='\0';
for(int i=0;(c=getchar()!=EOF);i++)
{
*string = realloc(string, (i+2)*sizeof(char *)); //reallocating memory
string[i] = scan(string[i]); //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
buf=bigScan(buf);
printf("%s\n",buf[0] );
}
所以基本上扫描函数读取每一行直到EOF或新行。bigScan的工作是通过调用扫描函数读取多行(指向字符串的指针),直到我们到达EOF。所以本质上,大扫描返回指向指针的指针,我们可以使用它读取整个文本。我的方法做错了什么?基本上在我的 bigScan 中调用扫描功能,直到我点击 EOF。
Ideal Input:
"Hi guys and girls
This is a message in multiple lines."
Ideal Output:
"Hi guys and girls
This is a message in multiple lines."
解决方案
- 内部无效
(c=getchar()!=EOF)
。bigScan
它将1
or的值分配0
给 c,因为该bool
值是!=
比较的结果。 - 内部将使您每行松散一个字符,因为该字符无处保存
getchar()
。bigScan
- 分配
bigScan
无效。您不应该为 string 分配内存*string = realloc(string
,但应该为指针本身分配内存,即。string = realloc(string, ... sizeof(char*))
. NULL
是用于指针的终止值。不要'\0'
用于指针。- 用于
size_t
存储尺寸。 - 如果要覆盖参数值,则传递参数值毫无意义。在此函数中,变量
a
未使用void f(int a) { a = 1; }
,因为两个函数中的变量string
在进入函数后立即分配。 - 该函数对字符
scan
有硬性限制。i<100
以下是您的功能的一些固定版本。还重命名了变量。并删除了参数。和不同的缩进。并用assert
来自标准的离子#include <assert.h>
作为原始错误检查。这样ungetc
读入的字符bigScan
就不会消失。而且我还没有运行这段代码,所以它有很多错误。
char* scan(void)
{
char *string = malloc(sizeof(*string));
assert(string != NULL);
string[0] = '\0';
size_t stringlen = 1;
for(int c; (c=getchar()) != '\n' && c != EOF;) {
void * const ptr = realloc(string, (stringlen + 1) * sizeof(*string));
assert(ptr != NULL);
stringlen++;
string[stringlen - 2] = c;
string[stringlen - 1] = '\0'; //inserting null character at the end
}
return string;
}
char** bigScan(void)
{
char **strings = malloc(sizeof(*strings));
assert(strings != NULL);
strings[0] = NULL;
size_t stringslen = 1;
for(int c; (c = getchar()) != EOF;) {
ungetc(c);
void * const ptr = realloc(strings, (stringslen + 1) * sizeof(*strings));
assert(ptr != NULL);
strings = ptr;
stringslen++;
strings[stringslen - 2] = scan();
strings[stringslen - 1] = NULL;
}
return strings;
}
推荐阅读
- r - 在 R 中,如何根据另一列添加具有 0/1 计数的多列?
- php - 第一次用户登录,上传图片 mkdir() 工作完美,但同一用户上传照片警告:mkdir():文件存在?
- javascript - Adyen 在 React 应用中的 Checkout SDK 集成
- scala - 如何从列表中获取对象
- mysql - 在事务中插入多行,如果其中一个失败,则插入其余行
- java - 我可以检测到用户何时打开其他应用程序吗?
- java - 如何关闭 GUI 窗口并使用 Java 中的内部类打印出一些文本?
- xamarin - 有没有办法可以在我的 Xamarin.Forms 应用程序中访问项目的构建版本?
- sql - T-SQL按时间间隔计数并找到最高频率
- c - 我的二进制搜索树的预遍历代码正在工作,但是每个元素都是指向结构的指针的堆栈是如何工作的?