C stdin 限制使我无法阅读超过 1200 个字符的行
C stdin limitation is blocking me from reading a line with over 1200 characters
我有这个简单的程序:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
size_t strlen(const char *str)
{
const char *s;
for (s = str; *s; ++s);
return(s - str);
}
/*
* Initial size of the read buffer
*/
#define DEFAULT_BUFFER 1024
/*
* Standard boolean type definition
*/
typedef enum { false = 0, true = 1 } bool;
/*
* Flags errors in pointer returning functions
*/
bool has_err = false;
/*
* Reads the next line of text from file and returns it.
* The line must be free()d afterwards.
*
* This function will segfault on binary data.
*/
char *readline(FILE *file){
char *buffer = NULL;
char *tmp_buf = NULL;
bool line_read = false;
int iteration = 0;
int offset = 0;
if(file == NULL){
fprintf(stderr, "readLine: NULL file pointer passed!\n");
has_err = true;
return NULL;
}
while(!line_read){
if((tmp_buf = malloc(DEFAULT_BUFFER)) == NULL){
fprintf(stderr, "readLine: Unable to allocate temporary buffer!\n");
if(buffer != NULL)
free(buffer);
has_err = true;
return NULL;
}
if(fgets(tmp_buf, DEFAULT_BUFFER, file) == NULL){
free(tmp_buf);
break;
}
if(tmp_buf[strlen(tmp_buf) - 1] == '\n') /* we have an end of line */
line_read = true;
offset = DEFAULT_BUFFER * (iteration + 1);
if((buffer = realloc(buffer, offset)) == NULL){
fprintf(stderr, "readLine: Unable to reallocate buffer!\n");
free(tmp_buf);
has_err = true;
return NULL;
}
offset = DEFAULT_BUFFER * iteration - iteration;
if(memcpy(buffer + offset, tmp_buf, DEFAULT_BUFFER) == NULL){
fprintf(stderr, "readLine: Cannot copy to buffer\n");
free(tmp_buf);
if(buffer != NULL)
free(buffer);
has_err = true;
return NULL;
}
free(tmp_buf);
iteration++;
}
return buffer;
}
int main (int argc, char *argv[])
{
int rows = 0, cols = 0;
char *line = readline(stdin);
printf("%s", line);
return 0;
}
然而,当我尝试在控制台中输入超过 1200 个字符时,程序在这行代码中停止工作:fgets(tmp_buf, DEFAULT_BUFFER, file)
问题:如何让 C 从 stdin
中读取而不施加任何内部限制?
P.S。如果我尝试使用控制台管道操作符(即 <
、./myprogram <input.txt
)
将我需要输入到程序中的内容传送到程序中,则该程序无法正常工作
提前致谢!
我不知道你在代码中做了什么,但这就是你的问题标题
#include <stdio.h>
#include <stdlib.h>
char *readline(FILE *file)
{
char *line;
size_t length;
size_t count;
int chr;
length = 100;
line = malloc(1 + length);
if (line == NULL)
{
fprintf(stderr, "memory exhausted!\n");
return NULL;
}
count = 0;
while (((chr = fgetc(file)) != EOF) && (chr != '\n'))
{
if (count >= length)
{
void *pointer;
length += length;
pointer = realloc(line, 1 + length);
if (pointer == NULL)
{
fprintf(stderr, "memory exhausted!\n");
free(line);
return NULL;
}
line = pointer;
}
line[count] = chr;
count += 1;
}
line[count] = '[=10=]';
return line;
}
int main(void)
{
char *line = readline(stdin);
if (line != NULL)
printf("%s\n", line);
free(line);
return 0;
}
这段代码的唯一限制是内存,即使没有足够的内存,代码也不会失败,因为如您所见,已经处理好了。
问题不是你的程序;它是终端驱动程序。终端驱动程序将保留的未读字符数有上限。它期望行短于某个限制,可能是 1024 或 1200 或其他一些值。如果您尝试键入更多字符,它们将不会被接受。
您可以尝试按 Control-D(在 Unix 上;Control-Z 在 Windows 上)发送待定来自终端驱动程序的行,然后继续使用更多字符。这应该可行,但必须一直数到 1199(或任何比限制小一的数字)然后按 Control-D 是一件很麻烦的事。如果数据是从某处复制'n'粘贴的,那将是双重麻烦,因此您无法选择以适当的时间间隔点击 Control-D。
您也可以尝试使用 non-canonical input mode。这需要小心——如果您在程序中设置非规范模式,则需要在程序退出前恢复规范模式。 (非规范模式是 vim
等程序使用的模式。)
我有这个简单的程序:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
size_t strlen(const char *str)
{
const char *s;
for (s = str; *s; ++s);
return(s - str);
}
/*
* Initial size of the read buffer
*/
#define DEFAULT_BUFFER 1024
/*
* Standard boolean type definition
*/
typedef enum { false = 0, true = 1 } bool;
/*
* Flags errors in pointer returning functions
*/
bool has_err = false;
/*
* Reads the next line of text from file and returns it.
* The line must be free()d afterwards.
*
* This function will segfault on binary data.
*/
char *readline(FILE *file){
char *buffer = NULL;
char *tmp_buf = NULL;
bool line_read = false;
int iteration = 0;
int offset = 0;
if(file == NULL){
fprintf(stderr, "readLine: NULL file pointer passed!\n");
has_err = true;
return NULL;
}
while(!line_read){
if((tmp_buf = malloc(DEFAULT_BUFFER)) == NULL){
fprintf(stderr, "readLine: Unable to allocate temporary buffer!\n");
if(buffer != NULL)
free(buffer);
has_err = true;
return NULL;
}
if(fgets(tmp_buf, DEFAULT_BUFFER, file) == NULL){
free(tmp_buf);
break;
}
if(tmp_buf[strlen(tmp_buf) - 1] == '\n') /* we have an end of line */
line_read = true;
offset = DEFAULT_BUFFER * (iteration + 1);
if((buffer = realloc(buffer, offset)) == NULL){
fprintf(stderr, "readLine: Unable to reallocate buffer!\n");
free(tmp_buf);
has_err = true;
return NULL;
}
offset = DEFAULT_BUFFER * iteration - iteration;
if(memcpy(buffer + offset, tmp_buf, DEFAULT_BUFFER) == NULL){
fprintf(stderr, "readLine: Cannot copy to buffer\n");
free(tmp_buf);
if(buffer != NULL)
free(buffer);
has_err = true;
return NULL;
}
free(tmp_buf);
iteration++;
}
return buffer;
}
int main (int argc, char *argv[])
{
int rows = 0, cols = 0;
char *line = readline(stdin);
printf("%s", line);
return 0;
}
然而,当我尝试在控制台中输入超过 1200 个字符时,程序在这行代码中停止工作:fgets(tmp_buf, DEFAULT_BUFFER, file)
问题:如何让 C 从 stdin
中读取而不施加任何内部限制?
P.S。如果我尝试使用控制台管道操作符(即 <
、./myprogram <input.txt
)
提前致谢!
我不知道你在代码中做了什么,但这就是你的问题标题
#include <stdio.h>
#include <stdlib.h>
char *readline(FILE *file)
{
char *line;
size_t length;
size_t count;
int chr;
length = 100;
line = malloc(1 + length);
if (line == NULL)
{
fprintf(stderr, "memory exhausted!\n");
return NULL;
}
count = 0;
while (((chr = fgetc(file)) != EOF) && (chr != '\n'))
{
if (count >= length)
{
void *pointer;
length += length;
pointer = realloc(line, 1 + length);
if (pointer == NULL)
{
fprintf(stderr, "memory exhausted!\n");
free(line);
return NULL;
}
line = pointer;
}
line[count] = chr;
count += 1;
}
line[count] = '[=10=]';
return line;
}
int main(void)
{
char *line = readline(stdin);
if (line != NULL)
printf("%s\n", line);
free(line);
return 0;
}
这段代码的唯一限制是内存,即使没有足够的内存,代码也不会失败,因为如您所见,已经处理好了。
问题不是你的程序;它是终端驱动程序。终端驱动程序将保留的未读字符数有上限。它期望行短于某个限制,可能是 1024 或 1200 或其他一些值。如果您尝试键入更多字符,它们将不会被接受。
您可以尝试按 Control-D(在 Unix 上;Control-Z 在 Windows 上)发送待定来自终端驱动程序的行,然后继续使用更多字符。这应该可行,但必须一直数到 1199(或任何比限制小一的数字)然后按 Control-D 是一件很麻烦的事。如果数据是从某处复制'n'粘贴的,那将是双重麻烦,因此您无法选择以适当的时间间隔点击 Control-D。
您也可以尝试使用 non-canonical input mode。这需要小心——如果您在程序中设置非规范模式,则需要在程序退出前恢复规范模式。 (非规范模式是 vim
等程序使用的模式。)