C 从 stdin 读取行
C reading lines from stdin
我的目标是使用 getline() 函数从管道 .txt 文件中读取每一行,但每次使用此函数时我都会以某种方式收到错误:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main() {
int Chars;
int size = 10;
char *string;
printf("Please enter a string: ");
string = (char*) malloc(size);
Chars = getline(&string, &size, stdin);
if (Chars == -1)
{
puts("ERROR!");
}
else
{
puts("You entered the following string: ");
puts(string);
printf("\nCurrent size for string block: %d", Chars);
}
return 0;
}
我总是收到错误代码:[错误] Id retruned 1 退出状态
我在 DevC++ 上重现了链接错误,其中 getline()
似乎丢失了,即使在使用 gcc[ 强制最近的 C 修订后也是如此=54=] 编译器选项,例如 -std=c11
.
所以我用 fgets()
:
重写了你的代码
char *fgets(char *s, int size, FILE *stream);
它肯定比 getline
更便携,但有一些区别:
- 如果在此限制之前没有遇到换行符,它最多读取
size-1
个字符(它会自动附加字符串终止符)。所以它不管理缓冲区重新分配
- 结果字符串包含
'\n'
个字符,如果找到
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define MAX_STR_SIZE 32
int main( void )
{
int len = 0;
char *str;
printf("Please enter a string: ");
str = malloc(MAX_STR_SIZE); /* (1) */
while( 1 )
{
size_t newline_pos;
fgets( str, MAX_STR_SIZE, stdin );
/* (2) */
if( len == 0) /* (3) */
{
puts("You entered the following string: ");
}
newline_pos = strcspn(str, "\n" );
str[newline_pos] = '[=11=]';
len += strlen(str); /* (4) */
fputs(str, stdout);
if(newline_pos < MAX_STR_SIZE-1) /* (5) */
break;
}
printf("\n\nCurrent size for string block: %d", len);
free( str ); /* (6) */
return 0;
}
所以,基本上,我只是使用 fgets
从 stdin
读取,迭代直到找到 '\n'
字符。为了了解是否满足此条件,我使用 strcspn() 函数,并使用相同的函数从结果字符串中删除换行符。
几个notes/assumptions(查看代码部分对应的数字):
- 只有在使用 C++ 编译器进行编译时才需要转换
malloc
的结果。 C 中可以省略
- 删除了
fgets
错误检查:它return在错误的情况下为NULL(在找到EOF之前没有读取任何字符。从标准输入读取它不会发生)
- 检查
len==0
我们确保 "You entered the following string: "
只打印一次
- 字符串的长度是对每次迭代读取的字符串长度求和得到的
- 当字符串包含
'\n'
时,满足break
条件。否则 strcspn
的 return 值将是 MAX_STR_SIZE
- 即使OS会释放程序使用的所有动态内存,在return上,总是
free
总是 是个好习惯
我的目标是使用 getline() 函数从管道 .txt 文件中读取每一行,但每次使用此函数时我都会以某种方式收到错误:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main() {
int Chars;
int size = 10;
char *string;
printf("Please enter a string: ");
string = (char*) malloc(size);
Chars = getline(&string, &size, stdin);
if (Chars == -1)
{
puts("ERROR!");
}
else
{
puts("You entered the following string: ");
puts(string);
printf("\nCurrent size for string block: %d", Chars);
}
return 0;
}
我总是收到错误代码:[错误] Id retruned 1 退出状态
我在 DevC++ 上重现了链接错误,其中 getline()
似乎丢失了,即使在使用 gcc[ 强制最近的 C 修订后也是如此=54=] 编译器选项,例如 -std=c11
.
所以我用 fgets()
:
char *fgets(char *s, int size, FILE *stream);
它肯定比 getline
更便携,但有一些区别:
- 如果在此限制之前没有遇到换行符,它最多读取
size-1
个字符(它会自动附加字符串终止符)。所以它不管理缓冲区重新分配 - 结果字符串包含
'\n'
个字符,如果找到
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define MAX_STR_SIZE 32
int main( void )
{
int len = 0;
char *str;
printf("Please enter a string: ");
str = malloc(MAX_STR_SIZE); /* (1) */
while( 1 )
{
size_t newline_pos;
fgets( str, MAX_STR_SIZE, stdin );
/* (2) */
if( len == 0) /* (3) */
{
puts("You entered the following string: ");
}
newline_pos = strcspn(str, "\n" );
str[newline_pos] = '[=11=]';
len += strlen(str); /* (4) */
fputs(str, stdout);
if(newline_pos < MAX_STR_SIZE-1) /* (5) */
break;
}
printf("\n\nCurrent size for string block: %d", len);
free( str ); /* (6) */
return 0;
}
所以,基本上,我只是使用 fgets
从 stdin
读取,迭代直到找到 '\n'
字符。为了了解是否满足此条件,我使用 strcspn() 函数,并使用相同的函数从结果字符串中删除换行符。
几个notes/assumptions(查看代码部分对应的数字):
- 只有在使用 C++ 编译器进行编译时才需要转换
malloc
的结果。 C 中可以省略
- 删除了
fgets
错误检查:它return在错误的情况下为NULL(在找到EOF之前没有读取任何字符。从标准输入读取它不会发生) - 检查
len==0
我们确保"You entered the following string: "
只打印一次 - 字符串的长度是对每次迭代读取的字符串长度求和得到的
- 当字符串包含
'\n'
时,满足break
条件。否则strcspn
的 return 值将是MAX_STR_SIZE
- 即使OS会释放程序使用的所有动态内存,在return上,总是
free
总是 是个好习惯