关于linux下标准读入read和fgets和scanf的区别

本文探讨了Linux环境下,read、fgets和scanf函数在读取输入时的行为区别。read函数在接收到回车后返回,字符串末尾会包含换行符 但不添加''终止符,可能导致strlen计算长度错误。fgets则会在末尾添加 确保字符串正确结束。相比之下,scanf在读取字符串时仅添加'',不包含换行符' '。
摘要由CSDN通过智能技术生成

测试代码如下

#include "../tcpiplib.h"

int main(int argc, char **argv)
{
ssize_t n;
	size_t len;
	char buf[10];
	
	//memset(buf, 0, sizeof(buf));

	n = 8;
	len = read(fileno(stdin), buf, n);
	write(fileno(stdout), buf, len);
	printf("%d strlen = %d\n",len, strlen(buf));

	fgets(buf, n, stdin);
	len = fputs(buf, stdout);
	printf("%d strlen = %d\n", len, strlen(buf));
	

	exit(0);
}

注释掉 memset后

输出如下

abc
abc
4 strlen = 10
efg
efg
1 strlen = 4


查看内存时,发现read会在按下回车后返回,并在字符串abc后加上换行符\n,但是不会再加上'\0',所以strlen有可能为10

但是fgets会在末尾加上\n\0保证正确结尾

好的,以下是一个可以读入text文件并计算文法中所有变量的FIRSTOP集的c语言程序: ```c #include <stdio.h> #include <string.h> #include <ctype.h> #define MAX_RULES 100 #define MAX_NONTERMINALS 10 #define MAX_TERMINALS 20 char rules[MAX_RULES][MAX_NONTERMINALS + 3]; char nonterminals[MAX_NONTERMINALS], terminals[MAX_TERMINALS]; int num_rules = 0, num_nonterminals = 0, num_terminals = 0; int is_nonterminal(char c) { for (int i = 0; i < num_nonterminals; i++) { if (nonterminals[i] == c) { return 1; } } return 0; } int is_terminal(char c) { for (int i = 0; i < num_terminals; i++) { if (terminals[i] == c) { return 1; } } return 0; } void add_nonterminal(char c) { if (!is_nonterminal(c)) { nonterminals[num_nonterminals++] = c; } } void add_terminal(char c) { if (!is_terminal(c)) { terminals[num_terminals++] = c; } } void add_firstop(char c, char op) { for (int i = 0; i < num_rules; i++) { if (rules[i][0] == c) { if (!is_terminal(op)) { add_nonterminal(op); } for (int j = 1; j < strlen(rules[i]); j++) { if (rules[i][j] == c) { if (j == strlen(rules[i]) - 1) { add_firstop(rules[i][0], op); } else { if (is_terminal(rules[i][j + 1])) { add_terminal(rules[i][j + 1]); } else { add_firstop(rules[i][j + 1], op); } } } } } } } void calculate_firstop() { for (int i = 0; i < num_nonterminals; i++) { add_firstop(nonterminals[i], nonterminals[i]); } } void print_firstop() { for (int i = 0; i < num_nonterminals; i++) { printf("FIRSTOP(%c) = { ", nonterminals[i]); for (int j = 0; j < num_terminals; j++) { for (int k = 0; k < num_rules; k++) { if (rules[k][0] == nonterminals[i]) { for (int l = 1; l < strlen(rules[k]); l++) { if (rules[k][l] == terminals[j]) { printf("%c, ", terminals[j]); break; } else if (rules[k][l] == nonterminals[i]) { break; } } } } } printf("}\n"); } } int main() { FILE *fp; char filename[100], c; printf("Enter the name of the file to read from: "); scanf("%s", filename); fp = fopen(filename, "r"); while ((c = fgetc(fp)) != EOF) { if (c == '\n') { num_rules++; } } rewind(fp); for (int i = 0; i < num_rules; i++) { fgets(rules[i], MAX_NONTERMINALS + 3, fp); add_nonterminal(rules[i][0]); for (int j = 1; j < strlen(rules[i]); j++) { if (isupper(rules[i][j])) { add_nonterminal(rules[i][j]); } else if (islower(rules[i][j])) { add_terminal(rules[i][j]); } } } calculate_firstop(); print_firstop(); fclose(fp); return 0; } ``` 该程序首先会读入一个文本文件,然后计算文法中所有变量的FIRSTOP集并将其打印出来。程序会先读入文法的产生式,然后计算每个非终结符的FIRSTOP集。在计算FIRSTOP集时,程序会遍历每个产生式,对于每个非终结符,它会找到产生式中所有该非终结符的出现位置,然后根据该非终结符后面的符号来计算FIRSTOP集。如果该符号是终结符,则将其加入终结符集合中;否则,将递归计算该符号的FIRSTOP集。最后,程序将所有非终结符的FIRSTOP集打印出来。 注意,该程序假设文法中的符号都是单个字符。如果有多个字符的符号,需要修改程序以支持这种情况。此外,该程序并没有对文法进行语法检查,因此需要确保输入的文法是正确的。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值