我正在尝试从文本文件(in.txt
)的第一行中读取三个3个值。我如何在C中实现呢?
文本文件的第一行包含3个数字(N, S, D
)。它们代表文件中输入单词的顺序。因此,例如,我的in.txt文件为:
8 3 5
mary
tom
jane
joe
dave
judy
fred
bill
jane
jones
judy
mary
judy
fred
joe
dave
因此,第一个8
对应于N
,随后是3
至S
,最后一个5
至D
。这样做的目的是让我将第一个8
添加到二进制搜索树中,然后跟随3
在BST中进行搜索,最后一个5
从BST中删除。
但是,为此,我想知道的是如何能够从文件中读取它们以启动BST。
距离我还很远,我只能打开文件,但是由于它根本无法工作而不得不删除其他代码。所以这就是我现在所拥有的。
int main()
{
FILE *inFile, *outFile;
int n, s, d;
inFile = fopen("in.txt", "r");
while(!feof (inFile))
{
fscanf(inFile, "%d %d %d", &n, &s, &d);
}
fclose(inFile);
}
这是我在Stackoverflow上的第一篇文章,非常感谢您的帮助!
答案 0 :(得分:1)
首先,您需要查看Why is while ( !feof (file) ) always wrong?
从文件读取数据行时,请使用面向{em> line 的输入函数,例如fgets()
或POSIX getline()
,将整行读取到缓冲区中-然后从缓冲区解析所需的值。这提供了两个主要好处:
您可以独立验证:
a。从文件中读取数据;和
b。解析行中的值。
输入缓冲区中保留的内容不取决于所使用的scanf
format-specifier 。 (一整行总是被占用,因此您随时可以从下一行的开头开始阅读以供下一次输入)
每次从文件读取时,只需使用fgets
时提供足够大小的缓冲区即可(不要忽略缓冲区大小!)。 POSIX getline
将自动分配所需的任何空间。然后使用sscanf
解析行中所需的任何信息(或strtok
或strsep
或您想要在缓冲区中定位特定点的任何其他函数)。
如果您不解析信息并且需要整行,只需用 nul-character 覆盖缓冲区的末端来修剪'\n'
。 strcspn
提供了一种简单的方法,或者使用strlen
获取长度,然后覆盖最后一个字符。
在您的情况下,您只需要以不同于其余行的方式处理第一行-因此,请保持行计数器在开始时初始化为零。如果您的行计数器为零,则从行中解析3整数值,否则对后续行进行任何所需的操作(下面的行仅与行号一起输出)
将其完全放在一起,您可以执行以下操作:
#include <stdio.h>
#include <string.h>
#define MAXC 1024 /* don't skimp on buffer size */
int main (int argc, char **argv) {
char buf[MAXC]; /* buffer to hold each line */
int n, s, d; /* your int variables */
size_t ndx = 0; /* line counter */
/* use filename provided as 1st argument (stdin by default) */
FILE *fp = argc > 1 ? fopen (argv[1], "r") : stdin;
if (!fp) { /* validate file open for reading */
perror ("file open failed");
return 1;
}
while (fgets (buf, MAXC, fp)) { /* read each line into buf */
if (!ndx) { /* if 1st line, parse into n, s, d */
if (sscanf (buf, "%d %d %d", &n, &s, &d) == 3)
printf ("line[%2zu] - n: %d s: %d d: %d\n",
ndx + 1, n, s, d);
else { /* if parse fails - handle error */
fputs ("error: invalid format - line 1.\n", stderr);
return 1;
}
}
else { /* for all subsequent lines */
buf[strcspn(buf, "\r\n")] = 0; /* trim '\n' from buf */
printf ("line[%2zu] : %s\n", ndx + 1, buf);
}
ndx++; /* increment line counter */
}
if (fp != stdin) fclose (fp); /* close file if not stdin */
return 0;
}
使用/输出示例
使用您的输入文件,您将获得以下内容:
$ ./bin/rdline1_3int dat/line1_3int.txt
line[ 1] - n: 8 s: 3 d: 5
line[ 2] : mary
line[ 3] : tom
line[ 4] : jane
line[ 5] : joe
line[ 6] : dave
line[ 7] : judy
line[ 8] : fred
line[ 9] : bill
line[10] : jane
line[11] : jones
line[12] : judy
line[13] : mary
line[14] : judy
line[15] : fred
line[16] : joe
line[17] : dave
答案 1 :(得分:0)
我会做这样的事情:
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
void main()
{
int fd, N, S, D;
char buff[1];
fd = open("in.txt", O_RDONLY);
//reading N
if(read(fd, buff, 1) == -1){
perror("Unable to read N");
exit(0);
}
//converting N to int value
//EDIT
N = atoi(buff);
//skipping the file descriptor to avoid reading the space
lseek(fd, 1, SEEK_CUR);
//reading S
if(read(fd, buff, 1) == -1){
perror("Unable to read S");
exit(0);
}
//converting S to int value
//EDIT
S = atoi(buff);
//skipping the file descriptor to avoid reading the space
lseek(fd, 1, SEEK_CUR);
//reading D
if(read(fd, buff, 1) == -1){
perror("Unable to read N");
exit(0);
}
//converting D to int value
//EDIT
D = atoi(buff);;
close(fd);
//here your values are initialized
}
我没有测试这段代码,所以它可能无法正常工作,请让我知道它是否有效:)