逐行读取 C
Reading line by line C
我有一个包含一些文件名及其大小的 txt 文件。
我是这样写txt文件的:
banana //file name
3 //the size of file banana
programs
12
music
524
我必须找到一个键盘输入的文件名并显示它的大小。
这是我的代码:
FILE *text;
text=fopen("text.txt","r");
printf("Scan the number of letters of your file name");
int n;
scanf("%d",&n);
char s[++n];
printf("Scan the file name you are looking for: ");
int i;
for(i=0;i<=n;i++)
{
scanf("%c",&s[i]);
}
int l=0;
char c[n];
char g;
while(!feof(text))
{
if(l%2==1) {fgetc(text); fgetc(text); l++;}
if(l%2==0)
{
fgets(c,n,text);
fgetc(text);
for(i=0;i<n;i++)
{
printf("%c",c[i]);
}
l++;
}
}
显然,这是不正确的。你能帮助我吗?我有点困惑。
呃!请详细了解基本输入。您的程序存在各种缺陷:
fgetc
读取单个字符。这有时很有用,但显然您想阅读整行。 fgets
这样做。您只使用一次,但不建议将它们混合使用。预先确定要使用的输入范例:char-wise (fgetc
)、line-wise (fgets
) 或 token-wise (fscanf
)。
- 请不要让用户输入文件名中的字符数。快点,
MySpiffyDocument.txt
中有多少个字符?那是计算机应该做的工作。
- 不要使用
feof
来控制yopur输入。所有输入函数都有特殊的 return 值来指示读取文件末尾或发生错误。对于fgets
,此return 值为NULL
,对于fgetc
,此return 值为特殊常量EOF
。函数 feof
和 ferror
在遇到特殊的 return 值后对两端的 post mortem 分析很有用条件。
- 你负责核心程序逻辑的内部循环根本没有意义。例如,对于奇数
l
,递增 l
然后测试偶数 l
– 这将是正确的,因为您刚刚递增了奇数 l
。在这种情况下使用 else
。并且不要将无论如何发生的事情放在条件块中:在 if
/else
块之后递增 l
一次。
这是一个示例实现:
#include <stdlib.h>
#include <stdio.h>
int process(const char *filename)
{
char line[80];
char name[80];
int size;
int count = 0;
FILE *f = fopen(filename, "r");
if (f == NULL) return -1;
while (fgets(line, sizeof(line), f)) {
if (count % 2 == 0) {
if (sscanf(line, "%s", name) < 1) continue;
} else {
if (sscanf(line, "%d", &size) < 1) continue;
printf("%12d %s\n", size, name);
}
count++;
}
fclose(f);
return 0;
}
int main()
{
char line[80];
char name[80];
puts("Please enter filename:");
while (fgets(line, sizeof(line), stdin)) {
if (sscanf(line, "%s", name) == 1) {
process(name);
break;
}
}
return 0;
}
注意事项:
- 程序最多使用 80 个字符。缓冲区大小;这意味着您的行最多可以包含 78 个字符——行内容加上 new-line
'\n'
加上空终止符 '[=33=]'
。在很多情况下这应该没问题,但最终该行可能会溢出。 (所以你的 file-name 字母计数有一些优点,但这里真正的解决方案是动态分配内存。我现在不会打开那个蠕虫罐头。)
- 代码使用双重策略:先读取行,然后使用
sscanf
扫描这些行,这样只读取每行的第一个单词。
- 跳过空行。即使没有有效数字的行也会被跳过。这是草率的错误处理,可能会触发 odd/even 计数。
- 在 C 中从键盘交互读取内容不是很容易。
main
中笨拙的 fgets
/sscanf
构造试图处理用户输入空字符的情况线或通过 Ctrl-D/Z 唤起 end-of-file 信号。更好更简单的方法是通过 argc
和 argv
. 向命令行提供参数
- 我已经将文件读取移到了一个单独的函数中。
我有一个包含一些文件名及其大小的 txt 文件。 我是这样写txt文件的:
banana //file name
3 //the size of file banana
programs
12
music
524
我必须找到一个键盘输入的文件名并显示它的大小。
这是我的代码:
FILE *text;
text=fopen("text.txt","r");
printf("Scan the number of letters of your file name");
int n;
scanf("%d",&n);
char s[++n];
printf("Scan the file name you are looking for: ");
int i;
for(i=0;i<=n;i++)
{
scanf("%c",&s[i]);
}
int l=0;
char c[n];
char g;
while(!feof(text))
{
if(l%2==1) {fgetc(text); fgetc(text); l++;}
if(l%2==0)
{
fgets(c,n,text);
fgetc(text);
for(i=0;i<n;i++)
{
printf("%c",c[i]);
}
l++;
}
}
显然,这是不正确的。你能帮助我吗?我有点困惑。
呃!请详细了解基本输入。您的程序存在各种缺陷:
fgetc
读取单个字符。这有时很有用,但显然您想阅读整行。fgets
这样做。您只使用一次,但不建议将它们混合使用。预先确定要使用的输入范例:char-wise (fgetc
)、line-wise (fgets
) 或 token-wise (fscanf
)。- 请不要让用户输入文件名中的字符数。快点,
MySpiffyDocument.txt
中有多少个字符?那是计算机应该做的工作。 - 不要使用
feof
来控制yopur输入。所有输入函数都有特殊的 return 值来指示读取文件末尾或发生错误。对于fgets
,此return 值为NULL
,对于fgetc
,此return 值为特殊常量EOF
。函数feof
和ferror
在遇到特殊的 return 值后对两端的 post mortem 分析很有用条件。 - 你负责核心程序逻辑的内部循环根本没有意义。例如,对于奇数
l
,递增l
然后测试偶数l
– 这将是正确的,因为您刚刚递增了奇数l
。在这种情况下使用else
。并且不要将无论如何发生的事情放在条件块中:在if
/else
块之后递增l
一次。
这是一个示例实现:
#include <stdlib.h>
#include <stdio.h>
int process(const char *filename)
{
char line[80];
char name[80];
int size;
int count = 0;
FILE *f = fopen(filename, "r");
if (f == NULL) return -1;
while (fgets(line, sizeof(line), f)) {
if (count % 2 == 0) {
if (sscanf(line, "%s", name) < 1) continue;
} else {
if (sscanf(line, "%d", &size) < 1) continue;
printf("%12d %s\n", size, name);
}
count++;
}
fclose(f);
return 0;
}
int main()
{
char line[80];
char name[80];
puts("Please enter filename:");
while (fgets(line, sizeof(line), stdin)) {
if (sscanf(line, "%s", name) == 1) {
process(name);
break;
}
}
return 0;
}
注意事项:
- 程序最多使用 80 个字符。缓冲区大小;这意味着您的行最多可以包含 78 个字符——行内容加上 new-line
'\n'
加上空终止符'[=33=]'
。在很多情况下这应该没问题,但最终该行可能会溢出。 (所以你的 file-name 字母计数有一些优点,但这里真正的解决方案是动态分配内存。我现在不会打开那个蠕虫罐头。) - 代码使用双重策略:先读取行,然后使用
sscanf
扫描这些行,这样只读取每行的第一个单词。 - 跳过空行。即使没有有效数字的行也会被跳过。这是草率的错误处理,可能会触发 odd/even 计数。
- 在 C 中从键盘交互读取内容不是很容易。
main
中笨拙的fgets
/sscanf
构造试图处理用户输入空字符的情况线或通过 Ctrl-D/Z 唤起 end-of-file 信号。更好更简单的方法是通过argc
和argv
. 向命令行提供参数
- 我已经将文件读取移到了一个单独的函数中。